@walkeros/server-destination-kafka 4.0.0 → 4.0.1-next-1778183328892
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 +94 -0
- package/dist/dev.d.mts +89 -1
- package/dist/dev.d.ts +89 -1
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.d.mts +52 -0
- package/dist/examples/index.d.ts +52 -0
- package/dist/examples/index.js +22 -0
- package/dist/examples/index.mjs +22 -0
- package/dist/index.d.mts +92 -3
- package/dist/index.d.ts +92 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +113 -8
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -55,6 +55,100 @@ npm install @walkeros/server-destination-kafka
|
|
|
55
55
|
| `key` | Override message key mapping path for this rule |
|
|
56
56
|
| `topic` | Route this rule to a different topic than the destination default |
|
|
57
57
|
|
|
58
|
+
## Setup
|
|
59
|
+
|
|
60
|
+
Provisioning a Kafka topic requires explicit decisions. There is no safe default
|
|
61
|
+
for `numPartitions` or `replicationFactor`. Both are cluster-specific
|
|
62
|
+
operational choices that depend on broker count, expected throughput, and
|
|
63
|
+
consumer parallelism. A `replicationFactor` of 3 fails on a one-broker cluster;
|
|
64
|
+
a `replicationFactor` of 1 silently degrades durability on every healthy
|
|
65
|
+
production cluster. A `numPartitions` of 1 caps consumer throughput at a single
|
|
66
|
+
thread.
|
|
67
|
+
|
|
68
|
+
### Object form is the only valid form
|
|
69
|
+
|
|
70
|
+
The boolean form `setup: true` is rejected at runtime:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
Error: kafka destination setup requires explicit options:
|
|
74
|
+
{ topic, numPartitions, replicationFactor }. There is no safe default for
|
|
75
|
+
partition count or replication factor, these depend on your cluster topology.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Required fields
|
|
79
|
+
|
|
80
|
+
- `numPartitions` (number)
|
|
81
|
+
- `replicationFactor` (number)
|
|
82
|
+
- `topic` (string), falls back to `settings.kafka.topic` when omitted
|
|
83
|
+
|
|
84
|
+
### Optional fields
|
|
85
|
+
|
|
86
|
+
- `configEntries`: topic-level config entries, e.g.
|
|
87
|
+
`{ "retention.ms": "604800000" }`
|
|
88
|
+
- `schemaRegistry`: Confluent Schema Registry binding (see below)
|
|
89
|
+
- `validateOnly`: kafkajs broker-side dry-run, no topic is created
|
|
90
|
+
|
|
91
|
+
### Example
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"destinations": {
|
|
96
|
+
"kafka": {
|
|
97
|
+
"package": "@walkeros/server-destination-kafka",
|
|
98
|
+
"config": {
|
|
99
|
+
"settings": {
|
|
100
|
+
"kafka": { "brokers": ["broker:9092"], "topic": "walkeros-events" }
|
|
101
|
+
},
|
|
102
|
+
"setup": {
|
|
103
|
+
"numPartitions": 6,
|
|
104
|
+
"replicationFactor": 3,
|
|
105
|
+
"configEntries": { "retention.ms": "604800000" }
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Run `walkeros setup destination.kafka` to provision the topic. The command is
|
|
114
|
+
idempotent: re-running it against an existing topic is a safe no-op. Drift on
|
|
115
|
+
`numPartitions`, `replicationFactor`, or `configEntries` is logged as a WARN
|
|
116
|
+
without auto-mutating the broker. Operators decide whether to recreate the topic
|
|
117
|
+
or accept the drift.
|
|
118
|
+
|
|
119
|
+
### Schema Registry (optional)
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"setup": {
|
|
124
|
+
"numPartitions": 6,
|
|
125
|
+
"replicationFactor": 3,
|
|
126
|
+
"schemaRegistry": {
|
|
127
|
+
"url": "https://schema-registry.example.com",
|
|
128
|
+
"subject": "walkeros-events-value",
|
|
129
|
+
"schemaType": "JSON",
|
|
130
|
+
"schema": "{ \"type\": \"object\", \"properties\": { \"event\": { \"type\": \"string\" } } }",
|
|
131
|
+
"compatibility": "BACKWARD"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The schema is registered via the Confluent Schema Registry REST API. The
|
|
138
|
+
optional `compatibility` level is set on the subject after registration.
|
|
139
|
+
|
|
140
|
+
### Runtime error when topic missing
|
|
141
|
+
|
|
142
|
+
When `setup` was not run and the topic does not exist on the cluster, `push()`
|
|
143
|
+
catches the kafkajs `UNKNOWN_TOPIC_OR_PARTITION` error and logs an actionable
|
|
144
|
+
message:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
Kafka topic "walkeros-events" not found on cluster broker:9092. Run
|
|
148
|
+
"walkeros setup destination.kafka" with explicit
|
|
149
|
+
{ numPartitions, replicationFactor } to create it.
|
|
150
|
+
```
|
|
151
|
+
|
|
58
152
|
## Authentication
|
|
59
153
|
|
|
60
154
|
### Confluent Cloud
|
package/dist/dev.d.mts
CHANGED
|
@@ -95,17 +95,53 @@ declare const MappingSchema: z.ZodObject<{
|
|
|
95
95
|
}, z.core.$strip>;
|
|
96
96
|
type Mapping = z.infer<typeof MappingSchema>;
|
|
97
97
|
|
|
98
|
+
declare const SetupSchema: z.ZodObject<{
|
|
99
|
+
topic: z.ZodOptional<z.ZodString>;
|
|
100
|
+
numPartitions: z.ZodOptional<z.ZodNumber>;
|
|
101
|
+
replicationFactor: z.ZodOptional<z.ZodNumber>;
|
|
102
|
+
configEntries: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
103
|
+
schemaRegistry: z.ZodOptional<z.ZodObject<{
|
|
104
|
+
url: z.ZodString;
|
|
105
|
+
subject: z.ZodString;
|
|
106
|
+
schemaType: z.ZodEnum<{
|
|
107
|
+
AVRO: "AVRO";
|
|
108
|
+
JSON: "JSON";
|
|
109
|
+
PROTOBUF: "PROTOBUF";
|
|
110
|
+
}>;
|
|
111
|
+
schema: z.ZodString;
|
|
112
|
+
compatibility: z.ZodOptional<z.ZodEnum<{
|
|
113
|
+
BACKWARD: "BACKWARD";
|
|
114
|
+
FORWARD: "FORWARD";
|
|
115
|
+
FULL: "FULL";
|
|
116
|
+
NONE: "NONE";
|
|
117
|
+
BACKWARD_TRANSITIVE: "BACKWARD_TRANSITIVE";
|
|
118
|
+
FORWARD_TRANSITIVE: "FORWARD_TRANSITIVE";
|
|
119
|
+
FULL_TRANSITIVE: "FULL_TRANSITIVE";
|
|
120
|
+
}>>;
|
|
121
|
+
auth: z.ZodOptional<z.ZodObject<{
|
|
122
|
+
username: z.ZodString;
|
|
123
|
+
password: z.ZodString;
|
|
124
|
+
}, z.core.$strip>>;
|
|
125
|
+
}, z.core.$strip>>;
|
|
126
|
+
validateOnly: z.ZodOptional<z.ZodBoolean>;
|
|
127
|
+
}, z.core.$strip>;
|
|
128
|
+
type Setup = z.infer<typeof SetupSchema>;
|
|
129
|
+
|
|
98
130
|
declare const settings: _walkeros_core_dev.JSONSchema;
|
|
99
131
|
declare const mapping: _walkeros_core_dev.JSONSchema;
|
|
132
|
+
declare const setup: _walkeros_core_dev.JSONSchema;
|
|
100
133
|
|
|
101
134
|
declare const index$1_KafkaSettingsSchema: typeof KafkaSettingsSchema;
|
|
102
135
|
type index$1_Mapping = Mapping;
|
|
103
136
|
declare const index$1_MappingSchema: typeof MappingSchema;
|
|
104
137
|
declare const index$1_SettingsSchema: typeof SettingsSchema;
|
|
138
|
+
type index$1_Setup = Setup;
|
|
139
|
+
declare const index$1_SetupSchema: typeof SetupSchema;
|
|
105
140
|
declare const index$1_mapping: typeof mapping;
|
|
106
141
|
declare const index$1_settings: typeof settings;
|
|
142
|
+
declare const index$1_setup: typeof setup;
|
|
107
143
|
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 };
|
|
144
|
+
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, type index$1_Setup as Setup, index$1_SetupSchema as SetupSchema, index$1_mapping as mapping, index$1_settings as settings, index$1_setup as setup };
|
|
109
145
|
}
|
|
110
146
|
|
|
111
147
|
/**
|
|
@@ -118,11 +154,63 @@ interface KafkaProducerMock {
|
|
|
118
154
|
disconnect: () => Promise<void>;
|
|
119
155
|
send: (record: ProducerRecord) => Promise<unknown>;
|
|
120
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Mock-friendly Admin interface used by setup (subset of kafkajs.Admin).
|
|
159
|
+
* Tests provide this via env.Kafka; production creates a real
|
|
160
|
+
* kafkajs Admin client.
|
|
161
|
+
*/
|
|
162
|
+
interface KafkaAdminMock {
|
|
163
|
+
connect: () => Promise<void>;
|
|
164
|
+
disconnect: () => Promise<void>;
|
|
165
|
+
createTopics: (args: {
|
|
166
|
+
topics: Array<{
|
|
167
|
+
topic: string;
|
|
168
|
+
numPartitions: number;
|
|
169
|
+
replicationFactor: number;
|
|
170
|
+
configEntries?: Array<{
|
|
171
|
+
name: string;
|
|
172
|
+
value: string;
|
|
173
|
+
}>;
|
|
174
|
+
}>;
|
|
175
|
+
validateOnly?: boolean;
|
|
176
|
+
waitForLeaders?: boolean;
|
|
177
|
+
timeout?: number;
|
|
178
|
+
}) => Promise<boolean>;
|
|
179
|
+
fetchTopicMetadata: (args: {
|
|
180
|
+
topics?: string[];
|
|
181
|
+
}) => Promise<{
|
|
182
|
+
topics: Array<{
|
|
183
|
+
name: string;
|
|
184
|
+
partitions: Array<{
|
|
185
|
+
partitionId: number;
|
|
186
|
+
leader: number;
|
|
187
|
+
replicas: number[];
|
|
188
|
+
isr: number[];
|
|
189
|
+
}>;
|
|
190
|
+
}>;
|
|
191
|
+
}>;
|
|
192
|
+
describeConfigs: (args: {
|
|
193
|
+
resources: Array<{
|
|
194
|
+
type: number;
|
|
195
|
+
name: string;
|
|
196
|
+
}>;
|
|
197
|
+
includeSynonyms?: boolean;
|
|
198
|
+
}) => Promise<{
|
|
199
|
+
resources: Array<{
|
|
200
|
+
resourceName: string;
|
|
201
|
+
configEntries: Array<{
|
|
202
|
+
configName: string;
|
|
203
|
+
configValue: string;
|
|
204
|
+
}>;
|
|
205
|
+
}>;
|
|
206
|
+
}>;
|
|
207
|
+
}
|
|
121
208
|
/**
|
|
122
209
|
* Mock-friendly Kafka client interface (subset of kafkajs.Kafka).
|
|
123
210
|
*/
|
|
124
211
|
interface KafkaClientMock {
|
|
125
212
|
producer: (config?: ProducerConfig) => KafkaProducerMock;
|
|
213
|
+
admin: () => KafkaAdminMock;
|
|
126
214
|
}
|
|
127
215
|
/**
|
|
128
216
|
* Constructor signature for the Kafka client. Accepts a config
|
package/dist/dev.d.ts
CHANGED
|
@@ -95,17 +95,53 @@ declare const MappingSchema: z.ZodObject<{
|
|
|
95
95
|
}, z.core.$strip>;
|
|
96
96
|
type Mapping = z.infer<typeof MappingSchema>;
|
|
97
97
|
|
|
98
|
+
declare const SetupSchema: z.ZodObject<{
|
|
99
|
+
topic: z.ZodOptional<z.ZodString>;
|
|
100
|
+
numPartitions: z.ZodOptional<z.ZodNumber>;
|
|
101
|
+
replicationFactor: z.ZodOptional<z.ZodNumber>;
|
|
102
|
+
configEntries: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
103
|
+
schemaRegistry: z.ZodOptional<z.ZodObject<{
|
|
104
|
+
url: z.ZodString;
|
|
105
|
+
subject: z.ZodString;
|
|
106
|
+
schemaType: z.ZodEnum<{
|
|
107
|
+
AVRO: "AVRO";
|
|
108
|
+
JSON: "JSON";
|
|
109
|
+
PROTOBUF: "PROTOBUF";
|
|
110
|
+
}>;
|
|
111
|
+
schema: z.ZodString;
|
|
112
|
+
compatibility: z.ZodOptional<z.ZodEnum<{
|
|
113
|
+
BACKWARD: "BACKWARD";
|
|
114
|
+
FORWARD: "FORWARD";
|
|
115
|
+
FULL: "FULL";
|
|
116
|
+
NONE: "NONE";
|
|
117
|
+
BACKWARD_TRANSITIVE: "BACKWARD_TRANSITIVE";
|
|
118
|
+
FORWARD_TRANSITIVE: "FORWARD_TRANSITIVE";
|
|
119
|
+
FULL_TRANSITIVE: "FULL_TRANSITIVE";
|
|
120
|
+
}>>;
|
|
121
|
+
auth: z.ZodOptional<z.ZodObject<{
|
|
122
|
+
username: z.ZodString;
|
|
123
|
+
password: z.ZodString;
|
|
124
|
+
}, z.core.$strip>>;
|
|
125
|
+
}, z.core.$strip>>;
|
|
126
|
+
validateOnly: z.ZodOptional<z.ZodBoolean>;
|
|
127
|
+
}, z.core.$strip>;
|
|
128
|
+
type Setup = z.infer<typeof SetupSchema>;
|
|
129
|
+
|
|
98
130
|
declare const settings: _walkeros_core_dev.JSONSchema;
|
|
99
131
|
declare const mapping: _walkeros_core_dev.JSONSchema;
|
|
132
|
+
declare const setup: _walkeros_core_dev.JSONSchema;
|
|
100
133
|
|
|
101
134
|
declare const index$1_KafkaSettingsSchema: typeof KafkaSettingsSchema;
|
|
102
135
|
type index$1_Mapping = Mapping;
|
|
103
136
|
declare const index$1_MappingSchema: typeof MappingSchema;
|
|
104
137
|
declare const index$1_SettingsSchema: typeof SettingsSchema;
|
|
138
|
+
type index$1_Setup = Setup;
|
|
139
|
+
declare const index$1_SetupSchema: typeof SetupSchema;
|
|
105
140
|
declare const index$1_mapping: typeof mapping;
|
|
106
141
|
declare const index$1_settings: typeof settings;
|
|
142
|
+
declare const index$1_setup: typeof setup;
|
|
107
143
|
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 };
|
|
144
|
+
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, type index$1_Setup as Setup, index$1_SetupSchema as SetupSchema, index$1_mapping as mapping, index$1_settings as settings, index$1_setup as setup };
|
|
109
145
|
}
|
|
110
146
|
|
|
111
147
|
/**
|
|
@@ -118,11 +154,63 @@ interface KafkaProducerMock {
|
|
|
118
154
|
disconnect: () => Promise<void>;
|
|
119
155
|
send: (record: ProducerRecord) => Promise<unknown>;
|
|
120
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Mock-friendly Admin interface used by setup (subset of kafkajs.Admin).
|
|
159
|
+
* Tests provide this via env.Kafka; production creates a real
|
|
160
|
+
* kafkajs Admin client.
|
|
161
|
+
*/
|
|
162
|
+
interface KafkaAdminMock {
|
|
163
|
+
connect: () => Promise<void>;
|
|
164
|
+
disconnect: () => Promise<void>;
|
|
165
|
+
createTopics: (args: {
|
|
166
|
+
topics: Array<{
|
|
167
|
+
topic: string;
|
|
168
|
+
numPartitions: number;
|
|
169
|
+
replicationFactor: number;
|
|
170
|
+
configEntries?: Array<{
|
|
171
|
+
name: string;
|
|
172
|
+
value: string;
|
|
173
|
+
}>;
|
|
174
|
+
}>;
|
|
175
|
+
validateOnly?: boolean;
|
|
176
|
+
waitForLeaders?: boolean;
|
|
177
|
+
timeout?: number;
|
|
178
|
+
}) => Promise<boolean>;
|
|
179
|
+
fetchTopicMetadata: (args: {
|
|
180
|
+
topics?: string[];
|
|
181
|
+
}) => Promise<{
|
|
182
|
+
topics: Array<{
|
|
183
|
+
name: string;
|
|
184
|
+
partitions: Array<{
|
|
185
|
+
partitionId: number;
|
|
186
|
+
leader: number;
|
|
187
|
+
replicas: number[];
|
|
188
|
+
isr: number[];
|
|
189
|
+
}>;
|
|
190
|
+
}>;
|
|
191
|
+
}>;
|
|
192
|
+
describeConfigs: (args: {
|
|
193
|
+
resources: Array<{
|
|
194
|
+
type: number;
|
|
195
|
+
name: string;
|
|
196
|
+
}>;
|
|
197
|
+
includeSynonyms?: boolean;
|
|
198
|
+
}) => Promise<{
|
|
199
|
+
resources: Array<{
|
|
200
|
+
resourceName: string;
|
|
201
|
+
configEntries: Array<{
|
|
202
|
+
configName: string;
|
|
203
|
+
configValue: string;
|
|
204
|
+
}>;
|
|
205
|
+
}>;
|
|
206
|
+
}>;
|
|
207
|
+
}
|
|
121
208
|
/**
|
|
122
209
|
* Mock-friendly Kafka client interface (subset of kafkajs.Kafka).
|
|
123
210
|
*/
|
|
124
211
|
interface KafkaClientMock {
|
|
125
212
|
producer: (config?: ProducerConfig) => KafkaProducerMock;
|
|
213
|
+
admin: () => KafkaAdminMock;
|
|
126
214
|
}
|
|
127
215
|
/**
|
|
128
216
|
* Constructor signature for the Kafka client. Accepts a config
|
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,r=(e,i)=>{for(var a in i)t(e,a,{get:i[a],enumerable:!0})},s={};r(s,{examples:()=>S,schemas:()=>n}),module.exports=(e=s,((e,r,s,n)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let c of a(r))o.call(e,c)||c===s||t(e,c,{get:()=>r[c],enumerable:!(n=i(r,c))||n.enumerable});return e})(t({},"__esModule",{value:!0}),e));var n={};r(n,{KafkaSettingsSchema:()=>m,MappingSchema:()=>b,SettingsSchema:()=>u,SetupSchema:()=>h,mapping:()=>y,settings:()=>k,setup:()=>z});var c=require("@walkeros/core/dev"),p=require("@walkeros/core/dev"),d=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).")}),l=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.")}),m=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:d.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:l.optional().describe("Retry configuration for transient failures.")}),u=p.z.object({kafka:m.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.")}),f=require("@walkeros/core/dev"),v=f.z.object({url:f.z.string().url().describe("Schema Registry URL."),subject:f.z.string().min(1).describe("Subject name, conventionally <topic>-value."),schemaType:f.z.enum(["AVRO","JSON","PROTOBUF"]).describe("Schema type."),schema:f.z.string().min(1).describe("The schema, stringified."),compatibility:f.z.enum(["BACKWARD","FORWARD","FULL","NONE","BACKWARD_TRANSITIVE","FORWARD_TRANSITIVE","FULL_TRANSITIVE"]).optional().describe("Subject compatibility level set after registration."),auth:f.z.object({username:f.z.string(),password:f.z.string()}).optional().describe("Optional Basic auth credentials.")}),h=f.z.object({topic:f.z.string().min(1).optional().describe("Topic name. Falls back to settings.kafka.topic if omitted."),numPartitions:f.z.number().int().positive().optional().describe("Number of partitions. Required at runtime. No safe default; choose based on expected throughput and consumer parallelism."),replicationFactor:f.z.number().int().positive().optional().describe("Replication factor. Required at runtime. Must be <= broker count. No safe default."),configEntries:f.z.record(f.z.string(),f.z.string()).optional().describe('Topic-level config entries, e.g. { "retention.ms": "604800000" }.'),schemaRegistry:v.optional().describe("Optional Confluent Schema Registry binding."),validateOnly:f.z.boolean().optional().describe("Use kafkajs validateOnly mode (broker-side dry-run). Default: false.")}),k=(0,c.zodToSchema)(u),y=(0,c.zodToSchema)(b),z=(0,c.zodToSchema)(h),S={};r(S,{env:()=>w,step:()=>E});var w={};r(w,{push:()=>D,simulation:()=>O});var T=()=>Promise.resolve(),A=()=>Promise.resolve(),j=()=>Promise.resolve([]);var R=()=>({connect:T,disconnect:A,send:j});var D={Kafka:{Kafka:class{constructor(e){}producer(e){return R()}admin(){return{connect:()=>Promise.resolve(),disconnect:()=>Promise.resolve(),createTopics:()=>Promise.resolve(!0),fetchTopicMetadata:({topics:e})=>Promise.resolve({topics:(e??[]).map(e=>({name:e,partitions:[{partitionId:0,leader:0,replicas:[0],isr:[0]}]}))}),describeConfigs:({resources:e})=>Promise.resolve({resources:e.map(e=>({resourceName:e.name,configEntries:[]}))})}}},CompressionTypes:{None:0,GZIP:1,Snappy:2,LZ4:3,ZSTD:4}}},O=["call:producer.send"],E={};r(E,{defaultEvent:()=>K,ignoredEvent:()=>L,keyFromUser:()=>M,mappedData:()=>N,mappedEventName:()=>P,topicOverride:()=>q});var I=require("@walkeros/core"),K={title:"Default event",description:"An event is produced to the configured Kafka topic with the full JSON body and entity_action as the message key.",in:(0,I.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}]]},P={title:"Renamed event",description:"A mapping renames the event which also changes the default Kafka message key used for partitioning.",in:(0,I.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}]]},N={title:"Mapped payload",description:"A data mapping transforms the event payload before producing it as the Kafka message value.",in:(0,I.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}]]},M={title:"Key from user id",description:"A settings.kafka.key path resolves the message key from the event, here using user.id for per-user partitioning.",in:(0,I.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}]]},q={title:"Topic override",description:"A mapping rule overrides the destination topic so specific events are routed to a dedicated stream.",in:(0,I.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}]]},L={public:!1,in:(0,I.getEvent)("debug noise",{timestamp:1700000105}),mapping:{ignore:!0},out:[]};//# sourceMappingURL=dev.js.map
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, KafkaSettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nconst SASLSchema = z.object({\n mechanism: z\n .enum(['plain', 'scram-sha-256', 'scram-sha-512', 'aws', 'oauthbearer'])\n .describe('SASL authentication mechanism.'),\n username: z\n .string()\n .optional()\n .describe('Username for plain/scram mechanisms.'),\n password: z\n .string()\n .optional()\n .describe('Password for plain/scram mechanisms.'),\n accessKeyId: z\n .string()\n .optional()\n .describe('AWS access key ID for IAM auth (mechanism: aws).'),\n secretAccessKey: z\n .string()\n .optional()\n .describe('AWS secret access key for IAM auth (mechanism: aws).'),\n sessionToken: z\n .string()\n .optional()\n .describe('AWS session token for temporary credentials (mechanism: aws).'),\n authorizationIdentity: z\n .string()\n .optional()\n .describe('AWS authorization identity (mechanism: aws).'),\n});\n\nconst RetrySchema = z.object({\n maxRetryTime: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Max total retry wait in ms. Default: 30000.'),\n initialRetryTime: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('First retry delay in ms. Default: 300.'),\n retries: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe('Max retry count. Default: 5.'),\n});\n\nexport const KafkaSettingsSchema = z.object({\n brokers: z\n .array(z.string().min(1))\n .min(1)\n .describe('Kafka broker addresses (host:port). At least one required.'),\n clientId: z\n .string()\n .optional()\n .describe('Kafka client ID. Default: walkeros.'),\n ssl: z\n .union([z.boolean(), z.record(z.string(), z.unknown())])\n .optional()\n .describe(\n 'TLS configuration. Set true for default TLS, or provide a tls.ConnectionOptions object for mTLS.',\n ),\n sasl: SASLSchema.optional().describe(\n 'SASL authentication config. Required for Confluent Cloud, AWS MSK with IAM, etc.',\n ),\n connectionTimeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Connection timeout in ms. Default: 1000.'),\n requestTimeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Request timeout in ms. Default: 30000.'),\n topic: z.string().min(1).describe('Target Kafka topic name.'),\n acks: z\n .number()\n .int()\n .min(-1)\n .max(1)\n .optional()\n .describe(\n 'Acknowledgement level. -1 = all replicas, 0 = fire-and-forget, 1 = leader only. Default: -1.',\n ),\n timeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Broker response timeout in ms. Default: 30000.'),\n compression: z\n .enum(['none', 'gzip', 'snappy', 'lz4', 'zstd'])\n .optional()\n .describe(\n 'Message compression codec. Default: gzip. Snappy/LZ4/ZSTD require additional npm packages.',\n ),\n idempotent: z\n .boolean()\n .optional()\n .describe(\n 'Enable idempotent producer for exactly-once delivery. Default: false.',\n ),\n allowAutoTopicCreation: z\n .boolean()\n .optional()\n .describe('Allow auto-creation of topics on the broker. Default: false.'),\n key: z\n .string()\n .optional()\n .describe(\n 'Mapping value path for message key derivation (e.g. user.id, data.userId). Default: entity_action.',\n ),\n headers: z\n .record(z.string(), z.string())\n .optional()\n .describe('Static headers added to every message.'),\n retry: RetrySchema.optional().describe(\n 'Retry configuration for transient failures.',\n ),\n});\n\nexport const SettingsSchema = z.object({\n kafka: KafkaSettingsSchema.describe(\n 'Kafka connection and producer settings.',\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n key: z\n .string()\n .optional()\n .describe(\n 'Override message key mapping path for this rule (e.g. data.id). Takes precedence over settings.kafka.key.',\n ),\n topic: z\n .string()\n .optional()\n .describe(\n 'Override Kafka topic for this rule. Takes precedence over settings.kafka.topic.',\n ),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type {\n Env,\n KafkaClientConstructor,\n KafkaClientMock,\n KafkaProducerMock,\n ProducerRecord,\n ProducerConfig,\n KafkaClientConfig,\n CompressionTypesMap,\n} from '../types';\n\n// Narrow helper type aliases so the mock SDK is typed explicitly without `any`.\ntype ProducerConnect = () => Promise<void>;\ntype ProducerDisconnect = () => Promise<void>;\ntype ProducerSend = (record: ProducerRecord) => Promise<unknown>;\ntype KafkaProducerFactory = (config?: ProducerConfig) => KafkaProducerMock;\n\nconst asyncConnect: ProducerConnect = () => Promise.resolve();\nconst asyncDisconnect: ProducerDisconnect = () => Promise.resolve();\nconst asyncSend: ProducerSend = () => Promise.resolve([]);\n\nfunction createMockProducer(): KafkaProducerMock {\n return {\n connect: asyncConnect,\n disconnect: asyncDisconnect,\n send: asyncSend,\n };\n}\n\nconst mockProducerFactory: KafkaProducerFactory = () => createMockProducer();\n\nclass MockKafkaClient implements KafkaClientMock {\n constructor(_config: KafkaClientConfig) {}\n producer(config?: ProducerConfig): KafkaProducerMock {\n return mockProducerFactory(config);\n }\n}\n\nconst MockKafkaConstructor: KafkaClientConstructor = MockKafkaClient;\n\nconst MockCompressionTypes: CompressionTypesMap = {\n None: 0,\n GZIP: 1,\n Snappy: 2,\n LZ4: 3,\n ZSTD: 4,\n};\n\nexport const push: Env = {\n Kafka: {\n Kafka: MockKafkaConstructor,\n CompressionTypes: MockCompressionTypes,\n },\n};\n\nexport const simulation = ['call:producer.send'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type KafkaStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Default event -- full WalkerOS.Event serialized as JSON to the configured\n * topic. Message key defaults to entity_action when no key path is set.\n */\nexport const defaultEvent: KafkaStepExample = {\n title: 'Default event',\n description:\n 'An event is produced to the configured Kafka topic with the full JSON body and entity_action as the message key.',\n in: getEvent('page view', {\n timestamp: 1700000100,\n }),\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'page_view',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000100',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Mapped event name -- rule.name renames the event, which also changes the\n * default message key when no key mapping is configured.\n */\nexport const mappedEventName: KafkaStepExample = {\n title: 'Renamed event',\n description:\n 'A mapping renames the event which also changes the default Kafka message key used for partitioning.',\n in: getEvent('order complete', {\n timestamp: 1700000101,\n }),\n mapping: {\n name: 'purchase',\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'purchase',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000101',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Mapped data -- data.map transforms the event payload. Value is the mapped\n * object serialized as JSON.\n */\nexport const mappedData: KafkaStepExample = {\n title: 'Mapped payload',\n description:\n 'A data mapping transforms the event payload before producing it as the Kafka message value.',\n in: getEvent('order complete', {\n timestamp: 1700000102,\n data: { id: 'ORD-400', total: 99.99, currency: 'EUR' },\n }),\n mapping: {\n name: 'purchase',\n data: {\n map: {\n order_id: 'data.id',\n revenue: 'data.total',\n currency: 'data.currency',\n },\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'purchase',\n value: 'json:data',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000102',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Key from user -- settings.kafka.key path resolves the message key from\n * the event (here user.id).\n */\nexport const keyFromUser: KafkaStepExample = {\n title: 'Key from user id',\n description:\n 'A settings.kafka.key path resolves the message key from the event, here using user.id for per-user partitioning.',\n in: getEvent('user signup', {\n timestamp: 1700000103,\n user: { id: 'usr-789' },\n data: { plan: 'pro' },\n }),\n settings: {\n kafka: {\n brokers: ['localhost:9092'],\n topic: 'walkeros-events',\n key: 'user.id',\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'usr-789',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000103',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Topic override -- rule.settings.topic routes this rule to a different\n * topic than the destination default.\n */\nexport const topicOverride: KafkaStepExample = {\n title: 'Topic override',\n description:\n 'A mapping rule overrides the destination topic so specific events are routed to a dedicated stream.',\n in: getEvent('order complete', {\n timestamp: 1700000104,\n data: { id: 'ORD-500', total: 42 },\n }),\n mapping: {\n settings: {\n topic: 'orders-stream',\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'orders-stream',\n messages: [\n {\n key: 'order_complete',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000104',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no producer.send call.\n */\nexport const ignoredEvent: KafkaStepExample = {\n public: false,\n in: getEvent('debug noise', {\n timestamp: 1700000105,\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
|
|
1
|
+
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/schemas/setup.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\nimport { SetupSchema } from './setup';\n\nexport { SettingsSchema, KafkaSettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\nexport { SetupSchema, type Setup } from './setup';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\nexport const setup = zodToSchema(SetupSchema);\n","import { z } from '@walkeros/core/dev';\n\nconst SASLSchema = z.object({\n mechanism: z\n .enum(['plain', 'scram-sha-256', 'scram-sha-512', 'aws', 'oauthbearer'])\n .describe('SASL authentication mechanism.'),\n username: z\n .string()\n .optional()\n .describe('Username for plain/scram mechanisms.'),\n password: z\n .string()\n .optional()\n .describe('Password for plain/scram mechanisms.'),\n accessKeyId: z\n .string()\n .optional()\n .describe('AWS access key ID for IAM auth (mechanism: aws).'),\n secretAccessKey: z\n .string()\n .optional()\n .describe('AWS secret access key for IAM auth (mechanism: aws).'),\n sessionToken: z\n .string()\n .optional()\n .describe('AWS session token for temporary credentials (mechanism: aws).'),\n authorizationIdentity: z\n .string()\n .optional()\n .describe('AWS authorization identity (mechanism: aws).'),\n});\n\nconst RetrySchema = z.object({\n maxRetryTime: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Max total retry wait in ms. Default: 30000.'),\n initialRetryTime: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('First retry delay in ms. Default: 300.'),\n retries: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe('Max retry count. Default: 5.'),\n});\n\nexport const KafkaSettingsSchema = z.object({\n brokers: z\n .array(z.string().min(1))\n .min(1)\n .describe('Kafka broker addresses (host:port). At least one required.'),\n clientId: z\n .string()\n .optional()\n .describe('Kafka client ID. Default: walkeros.'),\n ssl: z\n .union([z.boolean(), z.record(z.string(), z.unknown())])\n .optional()\n .describe(\n 'TLS configuration. Set true for default TLS, or provide a tls.ConnectionOptions object for mTLS.',\n ),\n sasl: SASLSchema.optional().describe(\n 'SASL authentication config. Required for Confluent Cloud, AWS MSK with IAM, etc.',\n ),\n connectionTimeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Connection timeout in ms. Default: 1000.'),\n requestTimeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Request timeout in ms. Default: 30000.'),\n topic: z.string().min(1).describe('Target Kafka topic name.'),\n acks: z\n .number()\n .int()\n .min(-1)\n .max(1)\n .optional()\n .describe(\n 'Acknowledgement level. -1 = all replicas, 0 = fire-and-forget, 1 = leader only. Default: -1.',\n ),\n timeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Broker response timeout in ms. Default: 30000.'),\n compression: z\n .enum(['none', 'gzip', 'snappy', 'lz4', 'zstd'])\n .optional()\n .describe(\n 'Message compression codec. Default: gzip. Snappy/LZ4/ZSTD require additional npm packages.',\n ),\n idempotent: z\n .boolean()\n .optional()\n .describe(\n 'Enable idempotent producer for exactly-once delivery. Default: false.',\n ),\n allowAutoTopicCreation: z\n .boolean()\n .optional()\n .describe('Allow auto-creation of topics on the broker. Default: false.'),\n key: z\n .string()\n .optional()\n .describe(\n 'Mapping value path for message key derivation (e.g. user.id, data.userId). Default: entity_action.',\n ),\n headers: z\n .record(z.string(), z.string())\n .optional()\n .describe('Static headers added to every message.'),\n retry: RetrySchema.optional().describe(\n 'Retry configuration for transient failures.',\n ),\n});\n\nexport const SettingsSchema = z.object({\n kafka: KafkaSettingsSchema.describe(\n 'Kafka connection and producer settings.',\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n key: z\n .string()\n .optional()\n .describe(\n 'Override message key mapping path for this rule (e.g. data.id). Takes precedence over settings.kafka.key.',\n ),\n topic: z\n .string()\n .optional()\n .describe(\n 'Override Kafka topic for this rule. Takes precedence over settings.kafka.topic.',\n ),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","// Zod schema for the Kafka destination's setup options.\n//\n// The runtime contract (in `setup.ts`) requires `numPartitions` and\n// `replicationFactor` and rejects the boolean form `setup: true` with an\n// actionable error. The \"no safe defaults\" rule is enforced at runtime, not\n// in this schema: configs frequently arrive from JSON where TS cannot enforce\n// required fields, and the runtime check is the single source of truth. This\n// schema therefore keeps both fields optional in shape, with the descriptions\n// noting the runtime requirement so MCP / IntelliSense surfaces the constraint\n// to authors.\nimport { z } from '@walkeros/core/dev';\n\nconst SchemaRegistrySchema = z.object({\n url: z.string().url().describe('Schema Registry URL.'),\n subject: z\n .string()\n .min(1)\n .describe('Subject name, conventionally <topic>-value.'),\n schemaType: z.enum(['AVRO', 'JSON', 'PROTOBUF']).describe('Schema type.'),\n schema: z.string().min(1).describe('The schema, stringified.'),\n compatibility: z\n .enum([\n 'BACKWARD',\n 'FORWARD',\n 'FULL',\n 'NONE',\n 'BACKWARD_TRANSITIVE',\n 'FORWARD_TRANSITIVE',\n 'FULL_TRANSITIVE',\n ])\n .optional()\n .describe('Subject compatibility level set after registration.'),\n auth: z\n .object({ username: z.string(), password: z.string() })\n .optional()\n .describe('Optional Basic auth credentials.'),\n});\n\nexport const SetupSchema = z.object({\n topic: z\n .string()\n .min(1)\n .optional()\n .describe('Topic name. Falls back to settings.kafka.topic if omitted.'),\n numPartitions: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Number of partitions. Required at runtime. No safe default; choose based on expected throughput and consumer parallelism.',\n ),\n replicationFactor: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Replication factor. Required at runtime. Must be <= broker count. No safe default.',\n ),\n configEntries: z\n .record(z.string(), z.string())\n .optional()\n .describe(\n 'Topic-level config entries, e.g. { \"retention.ms\": \"604800000\" }.',\n ),\n schemaRegistry: SchemaRegistrySchema.optional().describe(\n 'Optional Confluent Schema Registry binding.',\n ),\n validateOnly: z\n .boolean()\n .optional()\n .describe(\n 'Use kafkajs validateOnly mode (broker-side dry-run). Default: false.',\n ),\n});\n\nexport type Setup = z.infer<typeof SetupSchema>;\n\nexport { SchemaRegistrySchema };\n","export * as env from './env';\nexport * as step from './step';\n","import type {\n Env,\n KafkaAdminMock,\n KafkaClientConstructor,\n KafkaClientMock,\n KafkaProducerMock,\n ProducerRecord,\n ProducerConfig,\n KafkaClientConfig,\n CompressionTypesMap,\n} from '../types';\n\n// Narrow helper type aliases so the mock SDK is typed explicitly without `any`.\ntype ProducerConnect = () => Promise<void>;\ntype ProducerDisconnect = () => Promise<void>;\ntype ProducerSend = (record: ProducerRecord) => Promise<unknown>;\ntype KafkaProducerFactory = (config?: ProducerConfig) => KafkaProducerMock;\n\nconst asyncConnect: ProducerConnect = () => Promise.resolve();\nconst asyncDisconnect: ProducerDisconnect = () => Promise.resolve();\nconst asyncSend: ProducerSend = () => Promise.resolve([]);\n\nfunction createMockProducer(): KafkaProducerMock {\n return {\n connect: asyncConnect,\n disconnect: asyncDisconnect,\n send: asyncSend,\n };\n}\n\nconst mockProducerFactory: KafkaProducerFactory = () => createMockProducer();\n\nfunction createMockAdmin(): KafkaAdminMock {\n return {\n connect: () => Promise.resolve(),\n disconnect: () => Promise.resolve(),\n createTopics: () => Promise.resolve(true),\n fetchTopicMetadata: ({ topics }) =>\n Promise.resolve({\n topics: (topics ?? []).map((name) => ({\n name,\n partitions: [{ partitionId: 0, leader: 0, replicas: [0], isr: [0] }],\n })),\n }),\n describeConfigs: ({ resources }) =>\n Promise.resolve({\n resources: resources.map((r) => ({\n resourceName: r.name,\n configEntries: [],\n })),\n }),\n };\n}\n\nclass MockKafkaClient implements KafkaClientMock {\n constructor(_config: KafkaClientConfig) {}\n producer(config?: ProducerConfig): KafkaProducerMock {\n return mockProducerFactory(config);\n }\n admin(): KafkaAdminMock {\n return createMockAdmin();\n }\n}\n\nconst MockKafkaConstructor: KafkaClientConstructor = MockKafkaClient;\n\nconst MockCompressionTypes: CompressionTypesMap = {\n None: 0,\n GZIP: 1,\n Snappy: 2,\n LZ4: 3,\n ZSTD: 4,\n};\n\nexport const push: Env = {\n Kafka: {\n Kafka: MockKafkaConstructor,\n CompressionTypes: MockCompressionTypes,\n },\n};\n\nexport const simulation = ['call:producer.send'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type KafkaStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Default event -- full WalkerOS.Event serialized as JSON to the configured\n * topic. Message key defaults to entity_action when no key path is set.\n */\nexport const defaultEvent: KafkaStepExample = {\n title: 'Default event',\n description:\n 'An event is produced to the configured Kafka topic with the full JSON body and entity_action as the message key.',\n in: getEvent('page view', {\n timestamp: 1700000100,\n }),\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'page_view',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000100',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Mapped event name -- rule.name renames the event, which also changes the\n * default message key when no key mapping is configured.\n */\nexport const mappedEventName: KafkaStepExample = {\n title: 'Renamed event',\n description:\n 'A mapping renames the event which also changes the default Kafka message key used for partitioning.',\n in: getEvent('order complete', {\n timestamp: 1700000101,\n }),\n mapping: {\n name: 'purchase',\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'purchase',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000101',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Mapped data -- data.map transforms the event payload. Value is the mapped\n * object serialized as JSON.\n */\nexport const mappedData: KafkaStepExample = {\n title: 'Mapped payload',\n description:\n 'A data mapping transforms the event payload before producing it as the Kafka message value.',\n in: getEvent('order complete', {\n timestamp: 1700000102,\n data: { id: 'ORD-400', total: 99.99, currency: 'EUR' },\n }),\n mapping: {\n name: 'purchase',\n data: {\n map: {\n order_id: 'data.id',\n revenue: 'data.total',\n currency: 'data.currency',\n },\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'purchase',\n value: 'json:data',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000102',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Key from user -- settings.kafka.key path resolves the message key from\n * the event (here user.id).\n */\nexport const keyFromUser: KafkaStepExample = {\n title: 'Key from user id',\n description:\n 'A settings.kafka.key path resolves the message key from the event, here using user.id for per-user partitioning.',\n in: getEvent('user signup', {\n timestamp: 1700000103,\n user: { id: 'usr-789' },\n data: { plan: 'pro' },\n }),\n settings: {\n kafka: {\n brokers: ['localhost:9092'],\n topic: 'walkeros-events',\n key: 'user.id',\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'usr-789',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000103',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Topic override -- rule.settings.topic routes this rule to a different\n * topic than the destination default.\n */\nexport const topicOverride: KafkaStepExample = {\n title: 'Topic override',\n description:\n 'A mapping rule overrides the destination topic so specific events are routed to a dedicated stream.',\n in: getEvent('order complete', {\n timestamp: 1700000104,\n data: { id: 'ORD-500', total: 42 },\n }),\n mapping: {\n settings: {\n topic: 'orders-stream',\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'orders-stream',\n messages: [\n {\n key: 'order_complete',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000104',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no producer.send call.\n */\nexport const ignoredEvent: KafkaStepExample = {\n public: false,\n in: getEvent('debug noise', {\n timestamp: 1700000105,\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":"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","names":["import_dev","import_dev","import_dev"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=(t,
|
|
1
|
+
var e=Object.defineProperty,t=(t,i)=>{for(var a in i)e(t,a,{get:i[a],enumerable:!0})},i={};t(i,{KafkaSettingsSchema:()=>n,MappingSchema:()=>d,SettingsSchema:()=>c,SetupSchema:()=>u,mapping:()=>f,settings:()=>g,setup:()=>b});import{zodToSchema as a}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";var o=s.object({mechanism:s.enum(["plain","scram-sha-256","scram-sha-512","aws","oauthbearer"]).describe("SASL authentication mechanism."),username:s.string().optional().describe("Username for plain/scram mechanisms."),password:s.string().optional().describe("Password for plain/scram mechanisms."),accessKeyId:s.string().optional().describe("AWS access key ID for IAM auth (mechanism: aws)."),secretAccessKey:s.string().optional().describe("AWS secret access key for IAM auth (mechanism: aws)."),sessionToken:s.string().optional().describe("AWS session token for temporary credentials (mechanism: aws)."),authorizationIdentity:s.string().optional().describe("AWS authorization identity (mechanism: aws).")}),r=s.object({maxRetryTime:s.number().int().positive().optional().describe("Max total retry wait in ms. Default: 30000."),initialRetryTime:s.number().int().positive().optional().describe("First retry delay in ms. Default: 300."),retries:s.number().int().min(0).optional().describe("Max retry count. Default: 5.")}),n=s.object({brokers:s.array(s.string().min(1)).min(1).describe("Kafka broker addresses (host:port). At least one required."),clientId:s.string().optional().describe("Kafka client ID. Default: walkeros."),ssl:s.union([s.boolean(),s.record(s.string(),s.unknown())]).optional().describe("TLS configuration. Set true for default TLS, or provide a tls.ConnectionOptions object for mTLS."),sasl:o.optional().describe("SASL authentication config. Required for Confluent Cloud, AWS MSK with IAM, etc."),connectionTimeout:s.number().int().positive().optional().describe("Connection timeout in ms. Default: 1000."),requestTimeout:s.number().int().positive().optional().describe("Request timeout in ms. Default: 30000."),topic:s.string().min(1).describe("Target Kafka topic name."),acks:s.number().int().min(-1).max(1).optional().describe("Acknowledgement level. -1 = all replicas, 0 = fire-and-forget, 1 = leader only. Default: -1."),timeout:s.number().int().positive().optional().describe("Broker response timeout in ms. Default: 30000."),compression:s.enum(["none","gzip","snappy","lz4","zstd"]).optional().describe("Message compression codec. Default: gzip. Snappy/LZ4/ZSTD require additional npm packages."),idempotent:s.boolean().optional().describe("Enable idempotent producer for exactly-once delivery. Default: false."),allowAutoTopicCreation:s.boolean().optional().describe("Allow auto-creation of topics on the broker. Default: false."),key:s.string().optional().describe("Mapping value path for message key derivation (e.g. user.id, data.userId). Default: entity_action."),headers:s.record(s.string(),s.string()).optional().describe("Static headers added to every message."),retry:r.optional().describe("Retry configuration for transient failures.")}),c=s.object({kafka:n.describe("Kafka connection and producer settings.")});import{z as p}from"@walkeros/core/dev";var d=p.object({key:p.string().optional().describe("Override message key mapping path for this rule (e.g. data.id). Takes precedence over settings.kafka.key."),topic:p.string().optional().describe("Override Kafka topic for this rule. Takes precedence over settings.kafka.topic.")});import{z as m}from"@walkeros/core/dev";var l=m.object({url:m.string().url().describe("Schema Registry URL."),subject:m.string().min(1).describe("Subject name, conventionally <topic>-value."),schemaType:m.enum(["AVRO","JSON","PROTOBUF"]).describe("Schema type."),schema:m.string().min(1).describe("The schema, stringified."),compatibility:m.enum(["BACKWARD","FORWARD","FULL","NONE","BACKWARD_TRANSITIVE","FORWARD_TRANSITIVE","FULL_TRANSITIVE"]).optional().describe("Subject compatibility level set after registration."),auth:m.object({username:m.string(),password:m.string()}).optional().describe("Optional Basic auth credentials.")}),u=m.object({topic:m.string().min(1).optional().describe("Topic name. Falls back to settings.kafka.topic if omitted."),numPartitions:m.number().int().positive().optional().describe("Number of partitions. Required at runtime. No safe default; choose based on expected throughput and consumer parallelism."),replicationFactor:m.number().int().positive().optional().describe("Replication factor. Required at runtime. Must be <= broker count. No safe default."),configEntries:m.record(m.string(),m.string()).optional().describe('Topic-level config entries, e.g. { "retention.ms": "604800000" }.'),schemaRegistry:l.optional().describe("Optional Confluent Schema Registry binding."),validateOnly:m.boolean().optional().describe("Use kafkajs validateOnly mode (broker-side dry-run). Default: false.")}),g=a(c),f=a(d),b=a(u),v={};t(v,{env:()=>k,step:()=>R});var k={};t(k,{push:()=>w,simulation:()=>T});var h=()=>Promise.resolve(),y=()=>Promise.resolve(),S=()=>Promise.resolve([]);var A=()=>({connect:h,disconnect:y,send:S});var w={Kafka:{Kafka:class{constructor(e){}producer(e){return A()}admin(){return{connect:()=>Promise.resolve(),disconnect:()=>Promise.resolve(),createTopics:()=>Promise.resolve(!0),fetchTopicMetadata:({topics:e})=>Promise.resolve({topics:(e??[]).map(e=>({name:e,partitions:[{partitionId:0,leader:0,replicas:[0],isr:[0]}]}))}),describeConfigs:({resources:e})=>Promise.resolve({resources:e.map(e=>({resourceName:e.name,configEntries:[]}))})}}},CompressionTypes:{None:0,GZIP:1,Snappy:2,LZ4:3,ZSTD:4}}},T=["call:producer.send"],R={};t(R,{defaultEvent:()=>j,ignoredEvent:()=>P,keyFromUser:()=>K,mappedData:()=>I,mappedEventName:()=>O,topicOverride:()=>N});import{getEvent as D}from"@walkeros/core";var j={title:"Default event",description:"An event is produced to the configured Kafka topic with the full JSON body and entity_action as the message key.",in:D("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}]]},O={title:"Renamed event",description:"A mapping renames the event which also changes the default Kafka message key used for partitioning.",in:D("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}]]},I={title:"Mapped payload",description:"A data mapping transforms the event payload before producing it as the Kafka message value.",in:D("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}]]},K={title:"Key from user id",description:"A settings.kafka.key path resolves the message key from the event, here using user.id for per-user partitioning.",in:D("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}]]},N={title:"Topic override",description:"A mapping rule overrides the destination topic so specific events are routed to a dedicated stream.",in:D("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}]]},P={public:!1,in:D("debug noise",{timestamp:1700000105}),mapping:{ignore:!0},out:[]};export{v as examples,i as schemas};//# sourceMappingURL=dev.mjs.map
|
package/dist/dev.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, KafkaSettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nconst SASLSchema = z.object({\n mechanism: z\n .enum(['plain', 'scram-sha-256', 'scram-sha-512', 'aws', 'oauthbearer'])\n .describe('SASL authentication mechanism.'),\n username: z\n .string()\n .optional()\n .describe('Username for plain/scram mechanisms.'),\n password: z\n .string()\n .optional()\n .describe('Password for plain/scram mechanisms.'),\n accessKeyId: z\n .string()\n .optional()\n .describe('AWS access key ID for IAM auth (mechanism: aws).'),\n secretAccessKey: z\n .string()\n .optional()\n .describe('AWS secret access key for IAM auth (mechanism: aws).'),\n sessionToken: z\n .string()\n .optional()\n .describe('AWS session token for temporary credentials (mechanism: aws).'),\n authorizationIdentity: z\n .string()\n .optional()\n .describe('AWS authorization identity (mechanism: aws).'),\n});\n\nconst RetrySchema = z.object({\n maxRetryTime: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Max total retry wait in ms. Default: 30000.'),\n initialRetryTime: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('First retry delay in ms. Default: 300.'),\n retries: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe('Max retry count. Default: 5.'),\n});\n\nexport const KafkaSettingsSchema = z.object({\n brokers: z\n .array(z.string().min(1))\n .min(1)\n .describe('Kafka broker addresses (host:port). At least one required.'),\n clientId: z\n .string()\n .optional()\n .describe('Kafka client ID. Default: walkeros.'),\n ssl: z\n .union([z.boolean(), z.record(z.string(), z.unknown())])\n .optional()\n .describe(\n 'TLS configuration. Set true for default TLS, or provide a tls.ConnectionOptions object for mTLS.',\n ),\n sasl: SASLSchema.optional().describe(\n 'SASL authentication config. Required for Confluent Cloud, AWS MSK with IAM, etc.',\n ),\n connectionTimeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Connection timeout in ms. Default: 1000.'),\n requestTimeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Request timeout in ms. Default: 30000.'),\n topic: z.string().min(1).describe('Target Kafka topic name.'),\n acks: z\n .number()\n .int()\n .min(-1)\n .max(1)\n .optional()\n .describe(\n 'Acknowledgement level. -1 = all replicas, 0 = fire-and-forget, 1 = leader only. Default: -1.',\n ),\n timeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Broker response timeout in ms. Default: 30000.'),\n compression: z\n .enum(['none', 'gzip', 'snappy', 'lz4', 'zstd'])\n .optional()\n .describe(\n 'Message compression codec. Default: gzip. Snappy/LZ4/ZSTD require additional npm packages.',\n ),\n idempotent: z\n .boolean()\n .optional()\n .describe(\n 'Enable idempotent producer for exactly-once delivery. Default: false.',\n ),\n allowAutoTopicCreation: z\n .boolean()\n .optional()\n .describe('Allow auto-creation of topics on the broker. Default: false.'),\n key: z\n .string()\n .optional()\n .describe(\n 'Mapping value path for message key derivation (e.g. user.id, data.userId). Default: entity_action.',\n ),\n headers: z\n .record(z.string(), z.string())\n .optional()\n .describe('Static headers added to every message.'),\n retry: RetrySchema.optional().describe(\n 'Retry configuration for transient failures.',\n ),\n});\n\nexport const SettingsSchema = z.object({\n kafka: KafkaSettingsSchema.describe(\n 'Kafka connection and producer settings.',\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n key: z\n .string()\n .optional()\n .describe(\n 'Override message key mapping path for this rule (e.g. data.id). Takes precedence over settings.kafka.key.',\n ),\n topic: z\n .string()\n .optional()\n .describe(\n 'Override Kafka topic for this rule. Takes precedence over settings.kafka.topic.',\n ),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type {\n Env,\n KafkaClientConstructor,\n KafkaClientMock,\n KafkaProducerMock,\n ProducerRecord,\n ProducerConfig,\n KafkaClientConfig,\n CompressionTypesMap,\n} from '../types';\n\n// Narrow helper type aliases so the mock SDK is typed explicitly without `any`.\ntype ProducerConnect = () => Promise<void>;\ntype ProducerDisconnect = () => Promise<void>;\ntype ProducerSend = (record: ProducerRecord) => Promise<unknown>;\ntype KafkaProducerFactory = (config?: ProducerConfig) => KafkaProducerMock;\n\nconst asyncConnect: ProducerConnect = () => Promise.resolve();\nconst asyncDisconnect: ProducerDisconnect = () => Promise.resolve();\nconst asyncSend: ProducerSend = () => Promise.resolve([]);\n\nfunction createMockProducer(): KafkaProducerMock {\n return {\n connect: asyncConnect,\n disconnect: asyncDisconnect,\n send: asyncSend,\n };\n}\n\nconst mockProducerFactory: KafkaProducerFactory = () => createMockProducer();\n\nclass MockKafkaClient implements KafkaClientMock {\n constructor(_config: KafkaClientConfig) {}\n producer(config?: ProducerConfig): KafkaProducerMock {\n return mockProducerFactory(config);\n }\n}\n\nconst MockKafkaConstructor: KafkaClientConstructor = MockKafkaClient;\n\nconst MockCompressionTypes: CompressionTypesMap = {\n None: 0,\n GZIP: 1,\n Snappy: 2,\n LZ4: 3,\n ZSTD: 4,\n};\n\nexport const push: Env = {\n Kafka: {\n Kafka: MockKafkaConstructor,\n CompressionTypes: MockCompressionTypes,\n },\n};\n\nexport const simulation = ['call:producer.send'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type KafkaStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Default event -- full WalkerOS.Event serialized as JSON to the configured\n * topic. Message key defaults to entity_action when no key path is set.\n */\nexport const defaultEvent: KafkaStepExample = {\n title: 'Default event',\n description:\n 'An event is produced to the configured Kafka topic with the full JSON body and entity_action as the message key.',\n in: getEvent('page view', {\n timestamp: 1700000100,\n }),\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'page_view',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000100',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Mapped event name -- rule.name renames the event, which also changes the\n * default message key when no key mapping is configured.\n */\nexport const mappedEventName: KafkaStepExample = {\n title: 'Renamed event',\n description:\n 'A mapping renames the event which also changes the default Kafka message key used for partitioning.',\n in: getEvent('order complete', {\n timestamp: 1700000101,\n }),\n mapping: {\n name: 'purchase',\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'purchase',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000101',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Mapped data -- data.map transforms the event payload. Value is the mapped\n * object serialized as JSON.\n */\nexport const mappedData: KafkaStepExample = {\n title: 'Mapped payload',\n description:\n 'A data mapping transforms the event payload before producing it as the Kafka message value.',\n in: getEvent('order complete', {\n timestamp: 1700000102,\n data: { id: 'ORD-400', total: 99.99, currency: 'EUR' },\n }),\n mapping: {\n name: 'purchase',\n data: {\n map: {\n order_id: 'data.id',\n revenue: 'data.total',\n currency: 'data.currency',\n },\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'purchase',\n value: 'json:data',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000102',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Key from user -- settings.kafka.key path resolves the message key from\n * the event (here user.id).\n */\nexport const keyFromUser: KafkaStepExample = {\n title: 'Key from user id',\n description:\n 'A settings.kafka.key path resolves the message key from the event, here using user.id for per-user partitioning.',\n in: getEvent('user signup', {\n timestamp: 1700000103,\n user: { id: 'usr-789' },\n data: { plan: 'pro' },\n }),\n settings: {\n kafka: {\n brokers: ['localhost:9092'],\n topic: 'walkeros-events',\n key: 'user.id',\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'usr-789',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000103',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Topic override -- rule.settings.topic routes this rule to a different\n * topic than the destination default.\n */\nexport const topicOverride: KafkaStepExample = {\n title: 'Topic override',\n description:\n 'A mapping rule overrides the destination topic so specific events are routed to a dedicated stream.',\n in: getEvent('order complete', {\n timestamp: 1700000104,\n data: { id: 'ORD-500', total: 42 },\n }),\n mapping: {\n settings: {\n topic: 'orders-stream',\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'orders-stream',\n messages: [\n {\n key: 'order_complete',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000104',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no producer.send call.\n */\nexport const ignoredEvent: KafkaStepExample = {\n public: false,\n in: getEvent('debug noise', {\n timestamp: 1700000105,\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":"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","names":["z"]}
|
|
1
|
+
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/schemas/setup.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\nimport { SetupSchema } from './setup';\n\nexport { SettingsSchema, KafkaSettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\nexport { SetupSchema, type Setup } from './setup';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\nexport const setup = zodToSchema(SetupSchema);\n","import { z } from '@walkeros/core/dev';\n\nconst SASLSchema = z.object({\n mechanism: z\n .enum(['plain', 'scram-sha-256', 'scram-sha-512', 'aws', 'oauthbearer'])\n .describe('SASL authentication mechanism.'),\n username: z\n .string()\n .optional()\n .describe('Username for plain/scram mechanisms.'),\n password: z\n .string()\n .optional()\n .describe('Password for plain/scram mechanisms.'),\n accessKeyId: z\n .string()\n .optional()\n .describe('AWS access key ID for IAM auth (mechanism: aws).'),\n secretAccessKey: z\n .string()\n .optional()\n .describe('AWS secret access key for IAM auth (mechanism: aws).'),\n sessionToken: z\n .string()\n .optional()\n .describe('AWS session token for temporary credentials (mechanism: aws).'),\n authorizationIdentity: z\n .string()\n .optional()\n .describe('AWS authorization identity (mechanism: aws).'),\n});\n\nconst RetrySchema = z.object({\n maxRetryTime: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Max total retry wait in ms. Default: 30000.'),\n initialRetryTime: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('First retry delay in ms. Default: 300.'),\n retries: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe('Max retry count. Default: 5.'),\n});\n\nexport const KafkaSettingsSchema = z.object({\n brokers: z\n .array(z.string().min(1))\n .min(1)\n .describe('Kafka broker addresses (host:port). At least one required.'),\n clientId: z\n .string()\n .optional()\n .describe('Kafka client ID. Default: walkeros.'),\n ssl: z\n .union([z.boolean(), z.record(z.string(), z.unknown())])\n .optional()\n .describe(\n 'TLS configuration. Set true for default TLS, or provide a tls.ConnectionOptions object for mTLS.',\n ),\n sasl: SASLSchema.optional().describe(\n 'SASL authentication config. Required for Confluent Cloud, AWS MSK with IAM, etc.',\n ),\n connectionTimeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Connection timeout in ms. Default: 1000.'),\n requestTimeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Request timeout in ms. Default: 30000.'),\n topic: z.string().min(1).describe('Target Kafka topic name.'),\n acks: z\n .number()\n .int()\n .min(-1)\n .max(1)\n .optional()\n .describe(\n 'Acknowledgement level. -1 = all replicas, 0 = fire-and-forget, 1 = leader only. Default: -1.',\n ),\n timeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Broker response timeout in ms. Default: 30000.'),\n compression: z\n .enum(['none', 'gzip', 'snappy', 'lz4', 'zstd'])\n .optional()\n .describe(\n 'Message compression codec. Default: gzip. Snappy/LZ4/ZSTD require additional npm packages.',\n ),\n idempotent: z\n .boolean()\n .optional()\n .describe(\n 'Enable idempotent producer for exactly-once delivery. Default: false.',\n ),\n allowAutoTopicCreation: z\n .boolean()\n .optional()\n .describe('Allow auto-creation of topics on the broker. Default: false.'),\n key: z\n .string()\n .optional()\n .describe(\n 'Mapping value path for message key derivation (e.g. user.id, data.userId). Default: entity_action.',\n ),\n headers: z\n .record(z.string(), z.string())\n .optional()\n .describe('Static headers added to every message.'),\n retry: RetrySchema.optional().describe(\n 'Retry configuration for transient failures.',\n ),\n});\n\nexport const SettingsSchema = z.object({\n kafka: KafkaSettingsSchema.describe(\n 'Kafka connection and producer settings.',\n ),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n key: z\n .string()\n .optional()\n .describe(\n 'Override message key mapping path for this rule (e.g. data.id). Takes precedence over settings.kafka.key.',\n ),\n topic: z\n .string()\n .optional()\n .describe(\n 'Override Kafka topic for this rule. Takes precedence over settings.kafka.topic.',\n ),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","// Zod schema for the Kafka destination's setup options.\n//\n// The runtime contract (in `setup.ts`) requires `numPartitions` and\n// `replicationFactor` and rejects the boolean form `setup: true` with an\n// actionable error. The \"no safe defaults\" rule is enforced at runtime, not\n// in this schema: configs frequently arrive from JSON where TS cannot enforce\n// required fields, and the runtime check is the single source of truth. This\n// schema therefore keeps both fields optional in shape, with the descriptions\n// noting the runtime requirement so MCP / IntelliSense surfaces the constraint\n// to authors.\nimport { z } from '@walkeros/core/dev';\n\nconst SchemaRegistrySchema = z.object({\n url: z.string().url().describe('Schema Registry URL.'),\n subject: z\n .string()\n .min(1)\n .describe('Subject name, conventionally <topic>-value.'),\n schemaType: z.enum(['AVRO', 'JSON', 'PROTOBUF']).describe('Schema type.'),\n schema: z.string().min(1).describe('The schema, stringified.'),\n compatibility: z\n .enum([\n 'BACKWARD',\n 'FORWARD',\n 'FULL',\n 'NONE',\n 'BACKWARD_TRANSITIVE',\n 'FORWARD_TRANSITIVE',\n 'FULL_TRANSITIVE',\n ])\n .optional()\n .describe('Subject compatibility level set after registration.'),\n auth: z\n .object({ username: z.string(), password: z.string() })\n .optional()\n .describe('Optional Basic auth credentials.'),\n});\n\nexport const SetupSchema = z.object({\n topic: z\n .string()\n .min(1)\n .optional()\n .describe('Topic name. Falls back to settings.kafka.topic if omitted.'),\n numPartitions: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Number of partitions. Required at runtime. No safe default; choose based on expected throughput and consumer parallelism.',\n ),\n replicationFactor: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Replication factor. Required at runtime. Must be <= broker count. No safe default.',\n ),\n configEntries: z\n .record(z.string(), z.string())\n .optional()\n .describe(\n 'Topic-level config entries, e.g. { \"retention.ms\": \"604800000\" }.',\n ),\n schemaRegistry: SchemaRegistrySchema.optional().describe(\n 'Optional Confluent Schema Registry binding.',\n ),\n validateOnly: z\n .boolean()\n .optional()\n .describe(\n 'Use kafkajs validateOnly mode (broker-side dry-run). Default: false.',\n ),\n});\n\nexport type Setup = z.infer<typeof SetupSchema>;\n\nexport { SchemaRegistrySchema };\n","export * as env from './env';\nexport * as step from './step';\n","import type {\n Env,\n KafkaAdminMock,\n KafkaClientConstructor,\n KafkaClientMock,\n KafkaProducerMock,\n ProducerRecord,\n ProducerConfig,\n KafkaClientConfig,\n CompressionTypesMap,\n} from '../types';\n\n// Narrow helper type aliases so the mock SDK is typed explicitly without `any`.\ntype ProducerConnect = () => Promise<void>;\ntype ProducerDisconnect = () => Promise<void>;\ntype ProducerSend = (record: ProducerRecord) => Promise<unknown>;\ntype KafkaProducerFactory = (config?: ProducerConfig) => KafkaProducerMock;\n\nconst asyncConnect: ProducerConnect = () => Promise.resolve();\nconst asyncDisconnect: ProducerDisconnect = () => Promise.resolve();\nconst asyncSend: ProducerSend = () => Promise.resolve([]);\n\nfunction createMockProducer(): KafkaProducerMock {\n return {\n connect: asyncConnect,\n disconnect: asyncDisconnect,\n send: asyncSend,\n };\n}\n\nconst mockProducerFactory: KafkaProducerFactory = () => createMockProducer();\n\nfunction createMockAdmin(): KafkaAdminMock {\n return {\n connect: () => Promise.resolve(),\n disconnect: () => Promise.resolve(),\n createTopics: () => Promise.resolve(true),\n fetchTopicMetadata: ({ topics }) =>\n Promise.resolve({\n topics: (topics ?? []).map((name) => ({\n name,\n partitions: [{ partitionId: 0, leader: 0, replicas: [0], isr: [0] }],\n })),\n }),\n describeConfigs: ({ resources }) =>\n Promise.resolve({\n resources: resources.map((r) => ({\n resourceName: r.name,\n configEntries: [],\n })),\n }),\n };\n}\n\nclass MockKafkaClient implements KafkaClientMock {\n constructor(_config: KafkaClientConfig) {}\n producer(config?: ProducerConfig): KafkaProducerMock {\n return mockProducerFactory(config);\n }\n admin(): KafkaAdminMock {\n return createMockAdmin();\n }\n}\n\nconst MockKafkaConstructor: KafkaClientConstructor = MockKafkaClient;\n\nconst MockCompressionTypes: CompressionTypesMap = {\n None: 0,\n GZIP: 1,\n Snappy: 2,\n LZ4: 3,\n ZSTD: 4,\n};\n\nexport const push: Env = {\n Kafka: {\n Kafka: MockKafkaConstructor,\n CompressionTypes: MockCompressionTypes,\n },\n};\n\nexport const simulation = ['call:producer.send'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Extended step example that may carry destination-level settings overrides.\n */\nexport type KafkaStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n};\n\n/**\n * Default event -- full WalkerOS.Event serialized as JSON to the configured\n * topic. Message key defaults to entity_action when no key path is set.\n */\nexport const defaultEvent: KafkaStepExample = {\n title: 'Default event',\n description:\n 'An event is produced to the configured Kafka topic with the full JSON body and entity_action as the message key.',\n in: getEvent('page view', {\n timestamp: 1700000100,\n }),\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'page_view',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000100',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Mapped event name -- rule.name renames the event, which also changes the\n * default message key when no key mapping is configured.\n */\nexport const mappedEventName: KafkaStepExample = {\n title: 'Renamed event',\n description:\n 'A mapping renames the event which also changes the default Kafka message key used for partitioning.',\n in: getEvent('order complete', {\n timestamp: 1700000101,\n }),\n mapping: {\n name: 'purchase',\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'purchase',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000101',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Mapped data -- data.map transforms the event payload. Value is the mapped\n * object serialized as JSON.\n */\nexport const mappedData: KafkaStepExample = {\n title: 'Mapped payload',\n description:\n 'A data mapping transforms the event payload before producing it as the Kafka message value.',\n in: getEvent('order complete', {\n timestamp: 1700000102,\n data: { id: 'ORD-400', total: 99.99, currency: 'EUR' },\n }),\n mapping: {\n name: 'purchase',\n data: {\n map: {\n order_id: 'data.id',\n revenue: 'data.total',\n currency: 'data.currency',\n },\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'purchase',\n value: 'json:data',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000102',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Key from user -- settings.kafka.key path resolves the message key from\n * the event (here user.id).\n */\nexport const keyFromUser: KafkaStepExample = {\n title: 'Key from user id',\n description:\n 'A settings.kafka.key path resolves the message key from the event, here using user.id for per-user partitioning.',\n in: getEvent('user signup', {\n timestamp: 1700000103,\n user: { id: 'usr-789' },\n data: { plan: 'pro' },\n }),\n settings: {\n kafka: {\n brokers: ['localhost:9092'],\n topic: 'walkeros-events',\n key: 'user.id',\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'walkeros-events',\n messages: [\n {\n key: 'usr-789',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000103',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Topic override -- rule.settings.topic routes this rule to a different\n * topic than the destination default.\n */\nexport const topicOverride: KafkaStepExample = {\n title: 'Topic override',\n description:\n 'A mapping rule overrides the destination topic so specific events are routed to a dedicated stream.',\n in: getEvent('order complete', {\n timestamp: 1700000104,\n data: { id: 'ORD-500', total: 42 },\n }),\n mapping: {\n settings: {\n topic: 'orders-stream',\n },\n },\n out: [\n [\n 'producer.send',\n {\n topic: 'orders-stream',\n messages: [\n {\n key: 'order_complete',\n value: 'json:event',\n headers: { 'content-type': 'application/json' },\n timestamp: '1700000104',\n },\n ],\n acks: -1,\n compression: 1,\n },\n ],\n ],\n};\n\n/**\n * Ignored event -- mapping.ignore: true produces no producer.send call.\n */\nexport const ignoredEvent: KafkaStepExample = {\n public: false,\n in: getEvent('debug noise', {\n timestamp: 1700000105,\n }),\n mapping: { ignore: true },\n out: [],\n};\n"],"mappings":"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","names":["z","z"]}
|