@woovi/kafka 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +15 -3
- package/dist/index.d.ts +197 -0
- package/dist/index.js +15 -3
- package/dist/test-utils.cjs +18 -7
- package/dist/test-utils.d.ts +110 -0
- package/dist/test-utils.js +15 -7
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -109,13 +109,25 @@ function registerGracefulShutdown() {
|
|
|
109
109
|
function onShutdown(callback) {
|
|
110
110
|
shutdownCallbacks.push(callback);
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
const WOOVI_KAFKA_MOCK_KEY = '__woovi_kafka_mock__';
|
|
113
|
+
function getGlobalState() {
|
|
114
|
+
const g = globalThis;
|
|
115
|
+
if (!g[WOOVI_KAFKA_MOCK_KEY]) g[WOOVI_KAFKA_MOCK_KEY] = {
|
|
116
|
+
mock: null,
|
|
117
|
+
testMode: false
|
|
118
|
+
};
|
|
119
|
+
return g[WOOVI_KAFKA_MOCK_KEY];
|
|
120
|
+
}
|
|
113
121
|
function setMockKafkaForTestMode(mock) {
|
|
114
|
-
|
|
122
|
+
const state = getGlobalState();
|
|
123
|
+
state.mock = mock;
|
|
124
|
+
state.testMode = true;
|
|
115
125
|
testMode = true;
|
|
116
126
|
}
|
|
117
127
|
function getKafka() {
|
|
118
|
-
|
|
128
|
+
const state = getGlobalState();
|
|
129
|
+
if (state.testMode && state.mock) return state.mock;
|
|
130
|
+
if (testMode && kafkaInstance) return kafkaInstance;
|
|
119
131
|
if (!kafkaInstance) throw new Error('Kafka not initialized. Call createKafka() first.');
|
|
120
132
|
return kafkaInstance;
|
|
121
133
|
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import type { CompressionTypes } from 'kafkajs';
|
|
2
|
+
import type { Consumer } from 'kafkajs';
|
|
3
|
+
import type { ConsumerConfig } from 'kafkajs';
|
|
4
|
+
import type { ConsumerSubscribeTopics } from 'kafkajs';
|
|
5
|
+
import { Counter } from 'prom-client';
|
|
6
|
+
import type { EachBatchPayload } from 'kafkajs';
|
|
7
|
+
import type { EachMessagePayload } from 'kafkajs';
|
|
8
|
+
import { Gauge } from 'prom-client';
|
|
9
|
+
import { Histogram } from 'prom-client';
|
|
10
|
+
import { Kafka } from 'kafkajs';
|
|
11
|
+
import type { KafkaConfig as KafkaConfig_2 } from 'kafkajs';
|
|
12
|
+
import { logLevel } from 'kafkajs';
|
|
13
|
+
import type { Message } from 'kafkajs';
|
|
14
|
+
import type { Producer } from 'kafkajs';
|
|
15
|
+
import type { ProducerConfig } from 'kafkajs';
|
|
16
|
+
import type { RecordMetadata } from 'kafkajs';
|
|
17
|
+
import { Registry } from 'prom-client';
|
|
18
|
+
|
|
19
|
+
export declare interface BatchHandler {
|
|
20
|
+
(payload: EachBatchPayload): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export declare const batchProcessingDuration: Histogram<"topic" | "group_id" | "partition">;
|
|
24
|
+
|
|
25
|
+
export declare const batchSize: Histogram<"topic" | "group_id" | "partition">;
|
|
26
|
+
|
|
27
|
+
export declare const consumerLag: Gauge<"topic" | "group_id" | "partition">;
|
|
28
|
+
|
|
29
|
+
export declare function createConsumer(config: WooviConsumerConfig): WooviConsumer;
|
|
30
|
+
|
|
31
|
+
export declare function createKafka(config: KafkaConfig): Kafka;
|
|
32
|
+
|
|
33
|
+
export declare function createKafkaFromEnv(clientId: string): Kafka;
|
|
34
|
+
|
|
35
|
+
export declare function createProducer(config?: WooviProducerConfig): WooviProducer;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Disable test mode and reset the Kafka instance.
|
|
39
|
+
*/
|
|
40
|
+
export declare function disableTestMode(): void;
|
|
41
|
+
|
|
42
|
+
export { EachBatchPayload }
|
|
43
|
+
|
|
44
|
+
export { EachMessagePayload }
|
|
45
|
+
|
|
46
|
+
export declare function enableDefaultMetrics(): void;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Enable test mode with a mock Kafka instance.
|
|
50
|
+
* This allows tests to bypass the real Kafka connection.
|
|
51
|
+
*/
|
|
52
|
+
export declare function enableTestMode(mockKafka?: Kafka): void;
|
|
53
|
+
|
|
54
|
+
export declare interface ErrorHandler {
|
|
55
|
+
(error: Error, payload: EachMessagePayload): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export declare function getKafka(): Kafka;
|
|
59
|
+
|
|
60
|
+
export declare function getMessageHeaders(payload: EachMessagePayload): Record<string, string>;
|
|
61
|
+
|
|
62
|
+
export declare function getMetrics(): Promise<string>;
|
|
63
|
+
|
|
64
|
+
export declare function getMetricsContentType(): string;
|
|
65
|
+
|
|
66
|
+
export declare function healthCheck(): Promise<{
|
|
67
|
+
healthy: boolean;
|
|
68
|
+
error?: string;
|
|
69
|
+
}>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Check if test mode is enabled.
|
|
73
|
+
*/
|
|
74
|
+
export declare function isTestMode(): boolean;
|
|
75
|
+
|
|
76
|
+
export { Kafka }
|
|
77
|
+
|
|
78
|
+
export declare interface KafkaConfig {
|
|
79
|
+
brokers: string[];
|
|
80
|
+
clientId: string;
|
|
81
|
+
ssl?: KafkaConfig_2['ssl'];
|
|
82
|
+
sasl?: KafkaConfig_2['sasl'];
|
|
83
|
+
connectionTimeout?: number;
|
|
84
|
+
requestTimeout?: number;
|
|
85
|
+
retry?: KafkaConfig_2['retry'];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export declare const kafkaRegistry: Registry<"text/plain; version=0.0.4; charset=utf-8">;
|
|
89
|
+
|
|
90
|
+
export declare const lastMessageTimestamp: Gauge<"topic" | "group_id" | "partition">;
|
|
91
|
+
|
|
92
|
+
export { logLevel }
|
|
93
|
+
|
|
94
|
+
export { Message }
|
|
95
|
+
|
|
96
|
+
export declare interface MessageHandler {
|
|
97
|
+
(payload: EachMessagePayload): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export declare const messageProcessingDuration: Histogram<"topic" | "group_id" | "partition">;
|
|
101
|
+
|
|
102
|
+
export declare const messagesFailedTotal: Counter<"topic" | "group_id" | "partition" | "error_type">;
|
|
103
|
+
|
|
104
|
+
export declare const messagesProcessedTotal: Counter<"topic" | "group_id" | "partition" | "status">;
|
|
105
|
+
|
|
106
|
+
export declare const messagesProducedTotal: Counter<"topic" | "status">;
|
|
107
|
+
|
|
108
|
+
export declare function onShutdown(callback: () => Promise<void>): void;
|
|
109
|
+
|
|
110
|
+
export declare function parseMessage<T>(payload: EachMessagePayload): T | null;
|
|
111
|
+
|
|
112
|
+
export declare const produceLatency: Histogram<"topic">;
|
|
113
|
+
|
|
114
|
+
export declare interface PublishArgs<T = unknown> {
|
|
115
|
+
data: T;
|
|
116
|
+
topic?: string;
|
|
117
|
+
key?: string;
|
|
118
|
+
partition?: number;
|
|
119
|
+
headers?: Record<string, string>;
|
|
120
|
+
timestamp?: string;
|
|
121
|
+
compression?: CompressionTypes;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export declare interface PublishBatchArgs<T = unknown> {
|
|
125
|
+
messages: Array<{
|
|
126
|
+
data: T;
|
|
127
|
+
key?: string;
|
|
128
|
+
partition?: number;
|
|
129
|
+
headers?: Record<string, string>;
|
|
130
|
+
timestamp?: string;
|
|
131
|
+
}>;
|
|
132
|
+
topic?: string;
|
|
133
|
+
compression?: CompressionTypes;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export declare interface PublishMultiTopicArgs<T = unknown> {
|
|
137
|
+
messages: Array<{
|
|
138
|
+
topic: string;
|
|
139
|
+
data: T;
|
|
140
|
+
key?: string;
|
|
141
|
+
partition?: number;
|
|
142
|
+
headers?: Record<string, string>;
|
|
143
|
+
timestamp?: string;
|
|
144
|
+
}>;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export { RecordMetadata }
|
|
148
|
+
|
|
149
|
+
export declare function resetMetrics(): void;
|
|
150
|
+
|
|
151
|
+
export declare function setMockKafkaForTestMode(mock: Kafka): void;
|
|
152
|
+
|
|
153
|
+
export declare class WooviConsumer {
|
|
154
|
+
private consumer;
|
|
155
|
+
private topics;
|
|
156
|
+
private fromBeginning;
|
|
157
|
+
private connected;
|
|
158
|
+
private subscribed;
|
|
159
|
+
private groupId;
|
|
160
|
+
private onError?;
|
|
161
|
+
constructor(config: WooviConsumerConfig);
|
|
162
|
+
connect(): Promise<void>;
|
|
163
|
+
subscribe(): Promise<void>;
|
|
164
|
+
disconnect(): Promise<void>;
|
|
165
|
+
isConnected(): boolean;
|
|
166
|
+
run(handler: MessageHandler): Promise<void>;
|
|
167
|
+
runBatch(handler: BatchHandler): Promise<void>;
|
|
168
|
+
pause(topics?: string[]): Promise<void>;
|
|
169
|
+
resume(topics?: string[]): Promise<void>;
|
|
170
|
+
getConsumer(): Consumer;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export declare interface WooviConsumerConfig extends ConsumerConfig {
|
|
174
|
+
topics: ConsumerSubscribeTopics['topics'];
|
|
175
|
+
fromBeginning?: boolean;
|
|
176
|
+
onError?: ErrorHandler;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export declare class WooviProducer {
|
|
180
|
+
private producer;
|
|
181
|
+
private defaultTopic?;
|
|
182
|
+
private connected;
|
|
183
|
+
constructor(config?: WooviProducerConfig);
|
|
184
|
+
connect(): Promise<void>;
|
|
185
|
+
disconnect(): Promise<void>;
|
|
186
|
+
isConnected(): boolean;
|
|
187
|
+
publish<T>(args: PublishArgs<T>): Promise<RecordMetadata[]>;
|
|
188
|
+
publishBatch<T>(args: PublishBatchArgs<T>): Promise<RecordMetadata[]>;
|
|
189
|
+
publishToMultipleTopics<T>(args: PublishMultiTopicArgs<T>): Promise<RecordMetadata[]>;
|
|
190
|
+
getProducer(): Producer;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export declare interface WooviProducerConfig extends ProducerConfig {
|
|
194
|
+
defaultTopic?: string;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export { }
|
package/dist/index.js
CHANGED
|
@@ -52,13 +52,25 @@ function registerGracefulShutdown() {
|
|
|
52
52
|
function onShutdown(callback) {
|
|
53
53
|
shutdownCallbacks.push(callback);
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
const WOOVI_KAFKA_MOCK_KEY = '__woovi_kafka_mock__';
|
|
56
|
+
function getGlobalState() {
|
|
57
|
+
const g = globalThis;
|
|
58
|
+
if (!g[WOOVI_KAFKA_MOCK_KEY]) g[WOOVI_KAFKA_MOCK_KEY] = {
|
|
59
|
+
mock: null,
|
|
60
|
+
testMode: false
|
|
61
|
+
};
|
|
62
|
+
return g[WOOVI_KAFKA_MOCK_KEY];
|
|
63
|
+
}
|
|
56
64
|
function setMockKafkaForTestMode(mock) {
|
|
57
|
-
|
|
65
|
+
const state = getGlobalState();
|
|
66
|
+
state.mock = mock;
|
|
67
|
+
state.testMode = true;
|
|
58
68
|
testMode = true;
|
|
59
69
|
}
|
|
60
70
|
function getKafka() {
|
|
61
|
-
|
|
71
|
+
const state = getGlobalState();
|
|
72
|
+
if (state.testMode && state.mock) return state.mock;
|
|
73
|
+
if (testMode && kafkaInstance) return kafkaInstance;
|
|
62
74
|
if (!kafkaInstance) throw new Error('Kafka not initialized. Call createKafka() first.');
|
|
63
75
|
return kafkaInstance;
|
|
64
76
|
}
|
package/dist/test-utils.cjs
CHANGED
|
@@ -37,6 +37,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
37
37
|
mockProducerSend: ()=>mockProducerSend,
|
|
38
38
|
mockTransaction: ()=>mockTransaction,
|
|
39
39
|
mockTransactionSend: ()=>mockTransactionSend,
|
|
40
|
+
setupKafkaTest: ()=>setupKafkaTest,
|
|
40
41
|
KafkaJSNonRetriableError: ()=>KafkaJSNonRetriableError,
|
|
41
42
|
CompressionTypes: ()=>CompressionTypes,
|
|
42
43
|
mockProducer: ()=>mockProducer
|
|
@@ -204,12 +205,20 @@ const kafkaAssertLength = (args)=>{
|
|
|
204
205
|
}
|
|
205
206
|
};
|
|
206
207
|
function createMockKafka() {
|
|
207
|
-
return Kafka(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
208
|
+
return Kafka();
|
|
209
|
+
}
|
|
210
|
+
const WOOVI_KAFKA_MOCK_KEY = '__woovi_kafka_mock__';
|
|
211
|
+
function setupKafkaTest() {
|
|
212
|
+
const mockKafkaInstance = {
|
|
213
|
+
producer: mockProducer,
|
|
214
|
+
consumer: mockConsumer,
|
|
215
|
+
admin: mockAdmin
|
|
216
|
+
};
|
|
217
|
+
const g = globalThis;
|
|
218
|
+
g[WOOVI_KAFKA_MOCK_KEY] = {
|
|
219
|
+
mock: mockKafkaInstance,
|
|
220
|
+
testMode: true
|
|
221
|
+
};
|
|
213
222
|
}
|
|
214
223
|
exports.CompressionTypes = __webpack_exports__.CompressionTypes;
|
|
215
224
|
exports.Kafka = __webpack_exports__.Kafka;
|
|
@@ -227,6 +236,7 @@ exports.mockProducer = __webpack_exports__.mockProducer;
|
|
|
227
236
|
exports.mockProducerSend = __webpack_exports__.mockProducerSend;
|
|
228
237
|
exports.mockTransaction = __webpack_exports__.mockTransaction;
|
|
229
238
|
exports.mockTransactionSend = __webpack_exports__.mockTransactionSend;
|
|
239
|
+
exports.setupKafkaTest = __webpack_exports__.setupKafkaTest;
|
|
230
240
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
231
241
|
"CompressionTypes",
|
|
232
242
|
"Kafka",
|
|
@@ -243,7 +253,8 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
|
243
253
|
"mockProducer",
|
|
244
254
|
"mockProducerSend",
|
|
245
255
|
"mockTransaction",
|
|
246
|
-
"mockTransactionSend"
|
|
256
|
+
"mockTransactionSend",
|
|
257
|
+
"setupKafkaTest"
|
|
247
258
|
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
248
259
|
Object.defineProperty(exports, '__esModule', {
|
|
249
260
|
value: true
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export declare const clearAllMocks: () => void;
|
|
2
|
+
|
|
3
|
+
export declare const CompressionTypes: {
|
|
4
|
+
None: number;
|
|
5
|
+
GZIP: number;
|
|
6
|
+
Snappy: number;
|
|
7
|
+
LZ4: number;
|
|
8
|
+
ZSTD: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create a mock Kafka instance for testing.
|
|
13
|
+
* Use this with setMockKafkaForTestMode from @woovi/kafka.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* import { setMockKafkaForTestMode } from '@woovi/kafka';
|
|
17
|
+
* import { createMockKafka } from '@woovi/kafka/test-utils';
|
|
18
|
+
*
|
|
19
|
+
* beforeAll(() => {
|
|
20
|
+
* setMockKafkaForTestMode(createMockKafka());
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
export declare function createMockKafka(): any;
|
|
24
|
+
|
|
25
|
+
export declare const getKafkaMessages: () => KafkaMessage[];
|
|
26
|
+
|
|
27
|
+
export declare const Kafka: MockFn;
|
|
28
|
+
|
|
29
|
+
export declare const kafkaAssert: (args: KafkaAssertArgs) => void;
|
|
30
|
+
|
|
31
|
+
declare type KafkaAssertArgs = {
|
|
32
|
+
topic: string;
|
|
33
|
+
message: Record<string, unknown>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export declare const kafkaAssertLength: (args: KafkaAssertLengthArgs) => void;
|
|
37
|
+
|
|
38
|
+
declare type KafkaAssertLengthArgs = {
|
|
39
|
+
topic: string;
|
|
40
|
+
length: number;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export declare class KafkaJSNonRetriableError extends Error {
|
|
44
|
+
constructor(message: string);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export declare class KafkaJSProtocolError extends Error {
|
|
48
|
+
type: string;
|
|
49
|
+
constructor(message: string, type: string);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export declare type KafkaMessage = {
|
|
53
|
+
topic: string;
|
|
54
|
+
messages: Array<{
|
|
55
|
+
key?: string;
|
|
56
|
+
value: string;
|
|
57
|
+
headers?: Record<string, string>;
|
|
58
|
+
}>;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export declare const logLevel: {
|
|
62
|
+
NOTHING: number;
|
|
63
|
+
ERROR: number;
|
|
64
|
+
WARN: number;
|
|
65
|
+
INFO: number;
|
|
66
|
+
DEBUG: number;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export declare const mockAdmin: MockFn;
|
|
70
|
+
|
|
71
|
+
export declare const mockConsumer: MockFn;
|
|
72
|
+
|
|
73
|
+
declare type MockFn = {
|
|
74
|
+
(): any;
|
|
75
|
+
mock: {
|
|
76
|
+
calls: any[][];
|
|
77
|
+
};
|
|
78
|
+
mockClear: () => void;
|
|
79
|
+
mockReset: () => void;
|
|
80
|
+
mockImplementation: (fn: (...args: any[]) => any) => MockFn;
|
|
81
|
+
mockReturnValue: (value: any) => MockFn;
|
|
82
|
+
mockResolvedValue: (value: any) => MockFn;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export declare const mockProducer: MockFn;
|
|
86
|
+
|
|
87
|
+
export declare const mockProducerSend: MockFn;
|
|
88
|
+
|
|
89
|
+
export declare const mockTransaction: MockFn;
|
|
90
|
+
|
|
91
|
+
export declare const mockTransactionSend: MockFn;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Set up Kafka for testing with a mock instance.
|
|
95
|
+
* This creates a mock Kafka that records messages for kafkaAssert.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* import { setupKafkaTest, clearAllMocks } from '@woovi/kafka/test-utils';
|
|
99
|
+
*
|
|
100
|
+
* beforeAll(() => {
|
|
101
|
+
* setupKafkaTest();
|
|
102
|
+
* });
|
|
103
|
+
*
|
|
104
|
+
* beforeEach(() => {
|
|
105
|
+
* clearAllMocks();
|
|
106
|
+
* });
|
|
107
|
+
*/
|
|
108
|
+
export declare function setupKafkaTest(): void;
|
|
109
|
+
|
|
110
|
+
export { }
|
package/dist/test-utils.js
CHANGED
|
@@ -161,11 +161,19 @@ const kafkaAssertLength = (args)=>{
|
|
|
161
161
|
}
|
|
162
162
|
};
|
|
163
163
|
function createMockKafka() {
|
|
164
|
-
return Kafka(
|
|
165
|
-
clientId: 'test',
|
|
166
|
-
brokers: [
|
|
167
|
-
'localhost:9092'
|
|
168
|
-
]
|
|
169
|
-
});
|
|
164
|
+
return Kafka();
|
|
170
165
|
}
|
|
171
|
-
|
|
166
|
+
const WOOVI_KAFKA_MOCK_KEY = '__woovi_kafka_mock__';
|
|
167
|
+
function setupKafkaTest() {
|
|
168
|
+
const mockKafkaInstance = {
|
|
169
|
+
producer: mockProducer,
|
|
170
|
+
consumer: mockConsumer,
|
|
171
|
+
admin: mockAdmin
|
|
172
|
+
};
|
|
173
|
+
const g = globalThis;
|
|
174
|
+
g[WOOVI_KAFKA_MOCK_KEY] = {
|
|
175
|
+
mock: mockKafkaInstance,
|
|
176
|
+
testMode: true
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
export { CompressionTypes, Kafka, KafkaJSNonRetriableError, KafkaJSProtocolError, clearAllMocks, createMockKafka, getKafkaMessages, kafkaAssert, kafkaAssertLength, logLevel, mockAdmin, mockConsumer, mockProducer, mockProducerSend, mockTransaction, mockTransactionSend, setupKafkaTest };
|