@platformatic/kafka 1.12.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apis/enumerations.d.ts +11 -2
- package/dist/apis/enumerations.js +9 -1
- package/dist/clients/base/options.d.ts +4 -1
- package/dist/clients/base/options.js +4 -3
- package/dist/clients/consumer/messages-stream.js +3 -1
- package/dist/clients/consumer/options.d.ts +7 -7
- package/dist/clients/consumer/options.js +6 -6
- package/dist/clients/consumer/types.d.ts +2 -0
- package/dist/clients/consumer/types.js +2 -0
- package/dist/clients/producer/options.d.ts +6 -6
- package/dist/clients/producer/options.js +5 -5
- package/dist/clients/producer/types.d.ts +2 -2
- package/dist/network/connection.d.ts +3 -2
- package/dist/network/connection.js +20 -8
- package/dist/protocol/compression.d.ts +11 -2
- package/dist/protocol/compression.js +8 -0
- package/dist/protocol/records.d.ts +2 -2
- package/dist/protocol/records.js +3 -0
- package/dist/protocol/sasl/oauth-bearer.d.ts +1 -0
- package/dist/protocol/sasl/oauth-bearer.js +18 -0
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
export declare const SASLMechanisms:
|
|
2
|
-
|
|
1
|
+
export declare const SASLMechanisms: {
|
|
2
|
+
readonly PLAIN: "PLAIN";
|
|
3
|
+
readonly SCRAM_SHA_256: "SCRAM-SHA-256";
|
|
4
|
+
readonly SCRAM_SHA_512: "SCRAM-SHA-512";
|
|
5
|
+
readonly OAUTHBEARER: "OAUTHBEARER";
|
|
6
|
+
};
|
|
7
|
+
export declare const allowedSASLMechanisms: SASLMechanismValue[];
|
|
8
|
+
export type SASLMechanism = keyof typeof SASLMechanisms;
|
|
9
|
+
export type SASLMechanismValue = (typeof SASLMechanisms)[keyof typeof SASLMechanisms];
|
|
3
10
|
export declare const FindCoordinatorKeyTypes: {
|
|
4
11
|
readonly GROUP: 0;
|
|
5
12
|
readonly TRANSACTION: 1;
|
|
@@ -11,11 +18,13 @@ export declare const ProduceAcks: {
|
|
|
11
18
|
readonly NO_RESPONSE: 0;
|
|
12
19
|
readonly LEADER: 1;
|
|
13
20
|
};
|
|
21
|
+
export declare const allowedProduceAcks: number[];
|
|
14
22
|
export type ProduceAck = keyof typeof ProduceAcks;
|
|
15
23
|
export declare const FetchIsolationLevels: {
|
|
16
24
|
READ_UNCOMMITTED: number;
|
|
17
25
|
READ_COMMITTED: number;
|
|
18
26
|
};
|
|
27
|
+
export declare const allowedFetchIsolationLevels: number[];
|
|
19
28
|
export type FetchIsolationLevel = keyof typeof FetchIsolationLevels;
|
|
20
29
|
export declare const ListOffsetTimestamps: {
|
|
21
30
|
LATEST: bigint;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
// SASL Authentication
|
|
2
|
-
export const SASLMechanisms =
|
|
2
|
+
export const SASLMechanisms = {
|
|
3
|
+
PLAIN: 'PLAIN',
|
|
4
|
+
SCRAM_SHA_256: 'SCRAM-SHA-256',
|
|
5
|
+
SCRAM_SHA_512: 'SCRAM-SHA-512',
|
|
6
|
+
OAUTHBEARER: 'OAUTHBEARER'
|
|
7
|
+
};
|
|
8
|
+
export const allowedSASLMechanisms = Object.values(SASLMechanisms);
|
|
3
9
|
// Metadata API
|
|
4
10
|
// ./metadata/find-coordinator.ts
|
|
5
11
|
export const FindCoordinatorKeyTypes = { GROUP: 0, TRANSACTION: 1, SHARE: 2 };
|
|
@@ -9,9 +15,11 @@ export const ProduceAcks = {
|
|
|
9
15
|
NO_RESPONSE: 0,
|
|
10
16
|
LEADER: 1
|
|
11
17
|
};
|
|
18
|
+
export const allowedProduceAcks = Object.values(ProduceAcks);
|
|
12
19
|
// Consumer API
|
|
13
20
|
// ./consumer/fetch.ts
|
|
14
21
|
export const FetchIsolationLevels = { READ_UNCOMMITTED: 0, READ_COMMITTED: 1 };
|
|
22
|
+
export const allowedFetchIsolationLevels = Object.values(FetchIsolationLevels);
|
|
15
23
|
export const ListOffsetTimestamps = { LATEST: -1n, EARLIEST: -2n };
|
|
16
24
|
// Admin API
|
|
17
25
|
// ./admin/*-acls.ts - See: https://cwiki.apache.org/confluence/display/KAFKA/KIP-140%3A+Add+administrative+RPCs+for+adding%2C+deleting%2C+and+listing+ACLs
|
|
@@ -88,7 +88,7 @@ export declare const baseOptionsSchema: {
|
|
|
88
88
|
properties: {
|
|
89
89
|
mechanism: {
|
|
90
90
|
type: string;
|
|
91
|
-
enum:
|
|
91
|
+
enum: import("../../apis/enumerations.ts").SASLMechanismValue[];
|
|
92
92
|
};
|
|
93
93
|
username: {
|
|
94
94
|
oneOf: ({
|
|
@@ -117,6 +117,9 @@ export declare const baseOptionsSchema: {
|
|
|
117
117
|
type?: undefined;
|
|
118
118
|
})[];
|
|
119
119
|
};
|
|
120
|
+
authBytesValidator: {
|
|
121
|
+
function: boolean;
|
|
122
|
+
};
|
|
120
123
|
};
|
|
121
124
|
required: string[];
|
|
122
125
|
additionalProperties: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { allowedSASLMechanisms } from "../../apis/enumerations.js";
|
|
2
2
|
import { ajv } from "../../utils.js";
|
|
3
3
|
import { version } from "../../version.js";
|
|
4
4
|
// Note: clientSoftwareName can only contain alphanumeric characters, hyphens and dots
|
|
@@ -36,10 +36,11 @@ export const baseOptionsSchema = {
|
|
|
36
36
|
sasl: {
|
|
37
37
|
type: 'object',
|
|
38
38
|
properties: {
|
|
39
|
-
mechanism: { type: 'string', enum:
|
|
39
|
+
mechanism: { type: 'string', enum: allowedSASLMechanisms },
|
|
40
40
|
username: { oneOf: [{ type: 'string' }, { function: true }] },
|
|
41
41
|
password: { oneOf: [{ type: 'string' }, { function: true }] },
|
|
42
|
-
token: { oneOf: [{ type: 'string' }, { function: true }] }
|
|
42
|
+
token: { oneOf: [{ type: 'string' }, { function: true }] },
|
|
43
|
+
authBytesValidator: { function: true }
|
|
43
44
|
},
|
|
44
45
|
required: ['mechanism'],
|
|
45
46
|
additionalProperties: false
|
|
@@ -39,7 +39,9 @@ export class MessagesStream extends Readable {
|
|
|
39
39
|
#metricsConsumedMessages;
|
|
40
40
|
#corruptedMessageHandler;
|
|
41
41
|
constructor(consumer, options) {
|
|
42
|
-
const { autocommit, mode, fallbackMode, maxFetches, offsets, deserializers, onCorruptedMessage,
|
|
42
|
+
const { autocommit, mode, fallbackMode, maxFetches, offsets, deserializers, onCorruptedMessage,
|
|
43
|
+
// The options below are only destructured to avoid being part of structuredClone below
|
|
44
|
+
partitionAssigner: _partitionAssigner, ...otherOptions } = options;
|
|
43
45
|
if (offsets && mode !== MessagesStreamModes.MANUAL) {
|
|
44
46
|
throw new UserError('Cannot specify offsets when the stream mode is not MANUAL.');
|
|
45
47
|
}
|
|
@@ -93,7 +93,7 @@ export declare const consumeOptionsProperties: {
|
|
|
93
93
|
};
|
|
94
94
|
isolationLevel: {
|
|
95
95
|
type: string;
|
|
96
|
-
enum:
|
|
96
|
+
enum: number[];
|
|
97
97
|
};
|
|
98
98
|
deserializers: {
|
|
99
99
|
type: string;
|
|
@@ -196,7 +196,7 @@ export declare const consumeOptionsSchema: {
|
|
|
196
196
|
};
|
|
197
197
|
isolationLevel: {
|
|
198
198
|
type: string;
|
|
199
|
-
enum:
|
|
199
|
+
enum: number[];
|
|
200
200
|
};
|
|
201
201
|
deserializers: {
|
|
202
202
|
type: string;
|
|
@@ -275,11 +275,11 @@ export declare const consumeOptionsSchema: {
|
|
|
275
275
|
};
|
|
276
276
|
mode: {
|
|
277
277
|
type: string;
|
|
278
|
-
enum: ("
|
|
278
|
+
enum: import("./types.ts").MessagesStreamModeValue[];
|
|
279
279
|
};
|
|
280
280
|
fallbackMode: {
|
|
281
281
|
type: string;
|
|
282
|
-
enum: ("
|
|
282
|
+
enum: import("./types.ts").MessagesStreamFallbackModeValue[];
|
|
283
283
|
};
|
|
284
284
|
maxFetches: {
|
|
285
285
|
type: string;
|
|
@@ -340,7 +340,7 @@ export declare const consumerOptionsSchema: {
|
|
|
340
340
|
};
|
|
341
341
|
isolationLevel: {
|
|
342
342
|
type: string;
|
|
343
|
-
enum:
|
|
343
|
+
enum: number[];
|
|
344
344
|
};
|
|
345
345
|
deserializers: {
|
|
346
346
|
type: string;
|
|
@@ -444,7 +444,7 @@ export declare const fetchOptionsSchema: {
|
|
|
444
444
|
};
|
|
445
445
|
isolationLevel: {
|
|
446
446
|
type: string;
|
|
447
|
-
enum:
|
|
447
|
+
enum: number[];
|
|
448
448
|
};
|
|
449
449
|
deserializers: {
|
|
450
450
|
type: string;
|
|
@@ -639,7 +639,7 @@ export declare const listOffsetsOptionsSchema: {
|
|
|
639
639
|
};
|
|
640
640
|
isolationLevel: {
|
|
641
641
|
type: string;
|
|
642
|
-
enum:
|
|
642
|
+
enum: number[];
|
|
643
643
|
};
|
|
644
644
|
timestamp: {
|
|
645
645
|
bigint: boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { allowedFetchIsolationLevels } from "../../apis/enumerations.js";
|
|
2
2
|
import { ajv } from "../../utils.js";
|
|
3
3
|
import { idProperty, topicWithPartitionAndOffsetProperties } from "../base/options.js";
|
|
4
4
|
import { serdeProperties } from "../serde.js";
|
|
5
|
-
import {
|
|
5
|
+
import { allowedMessagesStreamFallbackModes, allowedMessagesStreamModes } from "./types.js";
|
|
6
6
|
export const groupOptionsProperties = {
|
|
7
7
|
sessionTimeout: { type: 'number', minimum: 0 },
|
|
8
8
|
rebalanceTimeout: { type: 'number', minimum: 0 },
|
|
@@ -56,7 +56,7 @@ export const consumeOptionsProperties = {
|
|
|
56
56
|
minBytes: { type: 'number', minimum: 0 },
|
|
57
57
|
maxBytes: { type: 'number', minimum: 0 },
|
|
58
58
|
maxWaitTime: { type: 'number', minimum: 0 },
|
|
59
|
-
isolationLevel: { type: 'string', enum:
|
|
59
|
+
isolationLevel: { type: 'string', enum: allowedFetchIsolationLevels },
|
|
60
60
|
deserializers: serdeProperties,
|
|
61
61
|
highWaterMark: { type: 'number', minimum: 1 }
|
|
62
62
|
};
|
|
@@ -69,8 +69,8 @@ export const consumeOptionsSchema = {
|
|
|
69
69
|
type: 'object',
|
|
70
70
|
properties: {
|
|
71
71
|
topics: { type: 'array', items: idProperty },
|
|
72
|
-
mode: { type: 'string', enum:
|
|
73
|
-
fallbackMode: { type: 'string', enum:
|
|
72
|
+
mode: { type: 'string', enum: allowedMessagesStreamModes },
|
|
73
|
+
fallbackMode: { type: 'string', enum: allowedMessagesStreamFallbackModes },
|
|
74
74
|
maxFetches: { type: 'number', minimum: 0, default: 0 },
|
|
75
75
|
offsets: {
|
|
76
76
|
type: 'array',
|
|
@@ -187,7 +187,7 @@ export const listOffsetsOptionsSchema = {
|
|
|
187
187
|
items: { type: 'number', minimum: 0 }
|
|
188
188
|
}
|
|
189
189
|
},
|
|
190
|
-
isolationLevel: { type: 'string', enum:
|
|
190
|
+
isolationLevel: { type: 'string', enum: allowedFetchIsolationLevels },
|
|
191
191
|
timestamp: { bigint: true }
|
|
192
192
|
},
|
|
193
193
|
required: ['topics'],
|
|
@@ -33,6 +33,7 @@ export declare const MessagesStreamModes: {
|
|
|
33
33
|
readonly COMMITTED: "committed";
|
|
34
34
|
readonly MANUAL: "manual";
|
|
35
35
|
};
|
|
36
|
+
export declare const allowedMessagesStreamModes: MessagesStreamModeValue[];
|
|
36
37
|
export type MessagesStreamMode = keyof typeof MessagesStreamModes;
|
|
37
38
|
export type MessagesStreamModeValue = (typeof MessagesStreamModes)[keyof typeof MessagesStreamModes];
|
|
38
39
|
export declare const MessagesStreamFallbackModes: {
|
|
@@ -40,6 +41,7 @@ export declare const MessagesStreamFallbackModes: {
|
|
|
40
41
|
readonly EARLIEST: "earliest";
|
|
41
42
|
readonly FAIL: "fail";
|
|
42
43
|
};
|
|
44
|
+
export declare const allowedMessagesStreamFallbackModes: MessagesStreamFallbackModeValue[];
|
|
43
45
|
export type MessagesStreamFallbackMode = keyof typeof MessagesStreamFallbackModes;
|
|
44
46
|
export type MessagesStreamFallbackModeValue = (typeof MessagesStreamFallbackModes)[keyof typeof MessagesStreamFallbackModes];
|
|
45
47
|
export interface GroupOptions {
|
|
@@ -4,8 +4,10 @@ export const MessagesStreamModes = {
|
|
|
4
4
|
COMMITTED: 'committed',
|
|
5
5
|
MANUAL: 'manual'
|
|
6
6
|
};
|
|
7
|
+
export const allowedMessagesStreamModes = Object.values(MessagesStreamModes);
|
|
7
8
|
export const MessagesStreamFallbackModes = {
|
|
8
9
|
LATEST: 'latest',
|
|
9
10
|
EARLIEST: 'earliest',
|
|
10
11
|
FAIL: 'fail'
|
|
11
12
|
};
|
|
13
|
+
export const allowedMessagesStreamFallbackModes = Object.values(MessagesStreamFallbackModes);
|
|
@@ -11,14 +11,14 @@ export declare const produceOptionsProperties: {
|
|
|
11
11
|
acks: {
|
|
12
12
|
type: string;
|
|
13
13
|
enumeration: {
|
|
14
|
-
allowed:
|
|
14
|
+
allowed: number[];
|
|
15
15
|
errorMessage: string;
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
compression: {
|
|
19
19
|
type: string;
|
|
20
20
|
enumeration: {
|
|
21
|
-
allowed:
|
|
21
|
+
allowed: import("../../protocol/compression.ts").CompressionAlgorithmValue[];
|
|
22
22
|
errorMessage: string;
|
|
23
23
|
};
|
|
24
24
|
};
|
|
@@ -47,14 +47,14 @@ export declare const produceOptionsSchema: {
|
|
|
47
47
|
acks: {
|
|
48
48
|
type: string;
|
|
49
49
|
enumeration: {
|
|
50
|
-
allowed:
|
|
50
|
+
allowed: number[];
|
|
51
51
|
errorMessage: string;
|
|
52
52
|
};
|
|
53
53
|
};
|
|
54
54
|
compression: {
|
|
55
55
|
type: string;
|
|
56
56
|
enumeration: {
|
|
57
|
-
allowed:
|
|
57
|
+
allowed: import("../../protocol/compression.ts").CompressionAlgorithmValue[];
|
|
58
58
|
errorMessage: string;
|
|
59
59
|
};
|
|
60
60
|
};
|
|
@@ -87,14 +87,14 @@ export declare const sendOptionsSchema: {
|
|
|
87
87
|
acks: {
|
|
88
88
|
type: string;
|
|
89
89
|
enumeration: {
|
|
90
|
-
allowed:
|
|
90
|
+
allowed: number[];
|
|
91
91
|
errorMessage: string;
|
|
92
92
|
};
|
|
93
93
|
};
|
|
94
94
|
compression: {
|
|
95
95
|
type: string;
|
|
96
96
|
enumeration: {
|
|
97
|
-
allowed:
|
|
97
|
+
allowed: import("../../protocol/compression.ts").CompressionAlgorithmValue[];
|
|
98
98
|
errorMessage: string;
|
|
99
99
|
};
|
|
100
100
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ProduceAcks } from "../../apis/enumerations.js";
|
|
2
|
-
import { compressionsAlgorithms } from "../../protocol/compression.js";
|
|
1
|
+
import { allowedProduceAcks, ProduceAcks } from "../../apis/enumerations.js";
|
|
2
|
+
import { allowedCompressionsAlgorithms, compressionsAlgorithms } from "../../protocol/compression.js";
|
|
3
3
|
import { messageSchema } from "../../protocol/records.js";
|
|
4
4
|
import { ajv, enumErrorMessage } from "../../utils.js";
|
|
5
5
|
import { serdeProperties } from "../serde.js";
|
|
@@ -10,15 +10,15 @@ export const produceOptionsProperties = {
|
|
|
10
10
|
acks: {
|
|
11
11
|
type: 'number',
|
|
12
12
|
enumeration: {
|
|
13
|
-
allowed:
|
|
13
|
+
allowed: allowedProduceAcks,
|
|
14
14
|
errorMessage: enumErrorMessage(ProduceAcks)
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
compression: {
|
|
18
18
|
type: 'string',
|
|
19
19
|
enumeration: {
|
|
20
|
-
allowed:
|
|
21
|
-
errorMessage: enumErrorMessage(compressionsAlgorithms
|
|
20
|
+
allowed: allowedCompressionsAlgorithms,
|
|
21
|
+
errorMessage: enumErrorMessage(compressionsAlgorithms)
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
partitioner: { function: true },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type CompressionAlgorithmValue } from '../../protocol/compression.ts';
|
|
2
2
|
import { type MessageToProduce } from '../../protocol/records.ts';
|
|
3
3
|
import { type BaseOptions, type TopicWithPartitionAndOffset } from '../base/types.ts';
|
|
4
4
|
import { type Serializers } from '../serde.ts';
|
|
@@ -16,7 +16,7 @@ export interface ProduceOptions<Key, Value, HeaderKey, HeaderValue> {
|
|
|
16
16
|
producerEpoch?: number;
|
|
17
17
|
idempotent?: boolean;
|
|
18
18
|
acks?: number;
|
|
19
|
-
compression?:
|
|
19
|
+
compression?: CompressionAlgorithmValue;
|
|
20
20
|
partitioner?: Partitioner<Key, Value, HeaderKey, HeaderValue>;
|
|
21
21
|
autocreateTopics?: boolean;
|
|
22
22
|
repeatOnStaleMetadata?: boolean;
|
|
@@ -3,7 +3,7 @@ import { type Socket } from 'node:net';
|
|
|
3
3
|
import { type ConnectionOptions as TLSConnectionOptions } from 'node:tls';
|
|
4
4
|
import { type CallbackWithPromise } from '../apis/callbacks.ts';
|
|
5
5
|
import { type Callback, type ResponseParser } from '../apis/definitions.ts';
|
|
6
|
-
import { type
|
|
6
|
+
import { type SASLMechanismValue } from '../apis/enumerations.ts';
|
|
7
7
|
import { Writer } from '../protocol/writer.ts';
|
|
8
8
|
export type SASLCredentialProvider = () => string | Promise<string>;
|
|
9
9
|
export interface Broker {
|
|
@@ -11,10 +11,11 @@ export interface Broker {
|
|
|
11
11
|
port: number;
|
|
12
12
|
}
|
|
13
13
|
export interface SASLOptions {
|
|
14
|
-
mechanism:
|
|
14
|
+
mechanism: SASLMechanismValue;
|
|
15
15
|
username?: string | SASLCredentialProvider;
|
|
16
16
|
password?: string | SASLCredentialProvider;
|
|
17
17
|
token?: string | SASLCredentialProvider;
|
|
18
|
+
authBytesValidator?: (authBytes: Buffer, callback: CallbackWithPromise<Buffer>) => void;
|
|
18
19
|
}
|
|
19
20
|
export interface ConnectionOptions {
|
|
20
21
|
connectTimeout?: number;
|
|
@@ -3,7 +3,7 @@ import EventEmitter from 'node:events';
|
|
|
3
3
|
import { createConnection } from 'node:net';
|
|
4
4
|
import { connect as createTLSConnection } from 'node:tls';
|
|
5
5
|
import { createPromisifiedCallback, kCallbackPromise } from "../apis/callbacks.js";
|
|
6
|
-
import { SASLMechanisms } from "../apis/enumerations.js";
|
|
6
|
+
import { allowedSASLMechanisms, SASLMechanisms } from "../apis/enumerations.js";
|
|
7
7
|
import { saslAuthenticateV2, saslHandshakeV1 } from "../apis/index.js";
|
|
8
8
|
import { connectionsApiChannel, connectionsConnectsChannel, createDiagnosticContext, notifyCreation } from "../diagnostic.js";
|
|
9
9
|
import { AuthenticationError, NetworkError, TimeoutError, UnexpectedCorrelationIdError, UserError } from "../errors.js";
|
|
@@ -237,7 +237,7 @@ export class Connection extends EventEmitter {
|
|
|
237
237
|
this.#status = ConnectionStatuses.AUTHENTICATING;
|
|
238
238
|
}
|
|
239
239
|
const { mechanism, username, password, token } = this.#options.sasl;
|
|
240
|
-
if (!
|
|
240
|
+
if (!allowedSASLMechanisms.includes(mechanism)) {
|
|
241
241
|
this.#onConnectionError(host, port, diagnosticContext, new UserError(`SASL mechanism ${mechanism} not supported.`));
|
|
242
242
|
return;
|
|
243
243
|
}
|
|
@@ -248,10 +248,10 @@ export class Connection extends EventEmitter {
|
|
|
248
248
|
}
|
|
249
249
|
this.emit('sasl:handshake', response.mechanisms);
|
|
250
250
|
const callback = this.#onSaslAuthenticate.bind(this, host, port, diagnosticContext);
|
|
251
|
-
if (mechanism ===
|
|
251
|
+
if (mechanism === SASLMechanisms.PLAIN) {
|
|
252
252
|
saslPlain.authenticate(saslAuthenticateV2.api, this, username, password, callback);
|
|
253
253
|
}
|
|
254
|
-
else if (mechanism ===
|
|
254
|
+
else if (mechanism === SASLMechanisms.OAUTHBEARER) {
|
|
255
255
|
saslOAuthBearer.authenticate(saslAuthenticateV2.api, this, token, callback);
|
|
256
256
|
}
|
|
257
257
|
else {
|
|
@@ -336,7 +336,19 @@ export class Connection extends EventEmitter {
|
|
|
336
336
|
this.#onConnectionError(host, port, diagnosticContext, error);
|
|
337
337
|
return;
|
|
338
338
|
}
|
|
339
|
-
if (
|
|
339
|
+
if (this.#options.sasl.authBytesValidator) {
|
|
340
|
+
this.#options.sasl.authBytesValidator(response.authBytes, this.#onSaslAuthenticationValidation.bind(this, host, port, diagnosticContext, response.sessionLifetimeMs));
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
this.#onSaslAuthenticationValidation(host, port, diagnosticContext, response.sessionLifetimeMs, null, response.authBytes);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
#onSaslAuthenticationValidation(host, port, diagnosticContext, sessionLifetimeMs, error, authBytes) {
|
|
347
|
+
if (error) {
|
|
348
|
+
this.#onConnectionError(host, port, diagnosticContext, new AuthenticationError('SASL authentication failed.', { cause: error }));
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (sessionLifetimeMs > 0) {
|
|
340
352
|
this.#reauthenticationTimeout = setTimeout(() => {
|
|
341
353
|
const diagnosticContext = createDiagnosticContext({
|
|
342
354
|
connection: this,
|
|
@@ -345,13 +357,13 @@ export class Connection extends EventEmitter {
|
|
|
345
357
|
port
|
|
346
358
|
});
|
|
347
359
|
this.#authenticate(host, port, diagnosticContext);
|
|
348
|
-
}, Number(
|
|
360
|
+
}, Number(sessionLifetimeMs) * 0.8);
|
|
349
361
|
}
|
|
350
362
|
if (this.#status === ConnectionStatuses.CONNECTED) {
|
|
351
|
-
this.emit('sasl:authentication:extended',
|
|
363
|
+
this.emit('sasl:authentication:extended', authBytes);
|
|
352
364
|
}
|
|
353
365
|
else {
|
|
354
|
-
this.emit('sasl:authentication',
|
|
366
|
+
this.emit('sasl:authentication', authBytes);
|
|
355
367
|
this.#onConnectionSucceed(diagnosticContext);
|
|
356
368
|
}
|
|
357
369
|
}
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { DynamicBuffer } from './dynamic-buffer.ts';
|
|
2
2
|
export type SyncCompressionPhase = (data: Buffer | DynamicBuffer) => Buffer;
|
|
3
3
|
export type CompressionOperation = (data: Buffer) => Buffer;
|
|
4
|
-
export interface
|
|
4
|
+
export interface CompressionAlgorithmSpecification {
|
|
5
5
|
compressSync: SyncCompressionPhase;
|
|
6
6
|
decompressSync: SyncCompressionPhase;
|
|
7
7
|
bitmask: number;
|
|
8
8
|
available?: boolean;
|
|
9
9
|
}
|
|
10
|
+
export declare const CompressionAlgorithms: {
|
|
11
|
+
readonly NONE: "none";
|
|
12
|
+
readonly GZIP: "gzip";
|
|
13
|
+
readonly SNAPPY: "snappy";
|
|
14
|
+
readonly LZ4: "lz4";
|
|
15
|
+
readonly ZSTD: "zstd";
|
|
16
|
+
};
|
|
17
|
+
export declare const allowedCompressionsAlgorithms: CompressionAlgorithmValue[];
|
|
18
|
+
export type CompressionAlgorithm = keyof typeof CompressionAlgorithms;
|
|
19
|
+
export type CompressionAlgorithmValue = (typeof CompressionAlgorithms)[keyof typeof CompressionAlgorithms];
|
|
10
20
|
export declare const compressionsAlgorithms: {
|
|
11
21
|
readonly none: {
|
|
12
22
|
readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
|
|
@@ -67,4 +77,3 @@ export declare const compressionsAlgorithmsByBitmask: {
|
|
|
67
77
|
readonly available: boolean;
|
|
68
78
|
};
|
|
69
79
|
};
|
|
70
|
-
export type CompressionAlgorithms = keyof typeof compressionsAlgorithms;
|
|
@@ -4,6 +4,14 @@ import { UnsupportedCompressionError } from "../errors.js";
|
|
|
4
4
|
import { DynamicBuffer } from "./dynamic-buffer.js";
|
|
5
5
|
const require = createRequire(import.meta.url);
|
|
6
6
|
const { zstdCompressSync, zstdDecompressSync, gzipSync, gunzipSync } = zlib;
|
|
7
|
+
export const CompressionAlgorithms = {
|
|
8
|
+
NONE: 'none',
|
|
9
|
+
GZIP: 'gzip',
|
|
10
|
+
SNAPPY: 'snappy',
|
|
11
|
+
LZ4: 'lz4',
|
|
12
|
+
ZSTD: 'zstd'
|
|
13
|
+
};
|
|
14
|
+
export const allowedCompressionsAlgorithms = Object.values(CompressionAlgorithms);
|
|
7
15
|
function ensureBuffer(data) {
|
|
8
16
|
return DynamicBuffer.isDynamicBuffer(data) ? data.slice() : data;
|
|
9
17
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type NumericMap } from '../utils.ts';
|
|
2
|
-
import { type
|
|
2
|
+
import { type CompressionAlgorithmValue } from './compression.ts';
|
|
3
3
|
import { type NullableString } from './definitions.ts';
|
|
4
4
|
import { Reader } from './reader.ts';
|
|
5
5
|
import { Writer } from './writer.ts';
|
|
@@ -28,7 +28,7 @@ export interface MessageRecord {
|
|
|
28
28
|
}
|
|
29
29
|
export interface CreateRecordsBatchOptions {
|
|
30
30
|
transactionalId?: NullableString;
|
|
31
|
-
compression:
|
|
31
|
+
compression: CompressionAlgorithmValue;
|
|
32
32
|
firstSequence?: number;
|
|
33
33
|
producerId: bigint;
|
|
34
34
|
producerEpoch: number;
|
package/dist/protocol/records.js
CHANGED
|
@@ -140,6 +140,9 @@ export function readRecordsBatch(reader) {
|
|
|
140
140
|
throw new UnsupportedCompressionError(`Unsupported compression algorithm with bitmask ${compression}`);
|
|
141
141
|
}
|
|
142
142
|
const buffer = algorithm.decompressSync(reader.buffer.slice(reader.position, reader.buffer.length));
|
|
143
|
+
// Move the original reader to the end
|
|
144
|
+
reader.skip(reader.buffer.length - reader.position);
|
|
145
|
+
// Replace the reader with the decompressed buffer
|
|
143
146
|
reader = Reader.from(buffer);
|
|
144
147
|
}
|
|
145
148
|
for (let i = 0; i < recordsLength; i++) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CallbackWithPromise } from '../../apis/callbacks.ts';
|
|
2
2
|
import { type SASLAuthenticationAPI, type SaslAuthenticateResponse } from '../../apis/security/sasl-authenticate-v2.ts';
|
|
3
3
|
import { type Connection, type SASLCredentialProvider } from '../../network/connection.ts';
|
|
4
|
+
export declare function jwtValidateAuthenticationBytes(authBytes: Buffer, callback: CallbackWithPromise<Buffer>): void;
|
|
4
5
|
export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | SASLCredentialProvider, callback: CallbackWithPromise<SaslAuthenticateResponse>): void;
|
|
5
6
|
export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | SASLCredentialProvider): Promise<SaslAuthenticateResponse>;
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { createPromisifiedCallback, kCallbackPromise } from "../../apis/callbacks.js";
|
|
2
|
+
import { AuthenticationError } from "../../errors.js";
|
|
2
3
|
import { getCredential } from "./credential-provider.js";
|
|
4
|
+
export function jwtValidateAuthenticationBytes(authBytes, callback) {
|
|
5
|
+
let authData = {};
|
|
6
|
+
try {
|
|
7
|
+
if (authBytes.length > 0) {
|
|
8
|
+
authData = JSON.parse(authBytes.toString('utf-8'));
|
|
9
|
+
}
|
|
10
|
+
/* c8 ignore next 8 - Hard to test */
|
|
11
|
+
}
|
|
12
|
+
catch (e) {
|
|
13
|
+
callback(new AuthenticationError('Invalid authBytes in SASL/OAUTHBEARER response', { authBytes }), undefined);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (authData.status === 'invalid_token') {
|
|
17
|
+
callback(new AuthenticationError('Invalid SASL/OAUTHBEARER token.', { authData }), undefined);
|
|
18
|
+
}
|
|
19
|
+
callback(null, authBytes);
|
|
20
|
+
}
|
|
3
21
|
export function authenticate(authenticateAPI, connection, tokenOrProvider, callback) {
|
|
4
22
|
if (!callback) {
|
|
5
23
|
callback = createPromisifiedCallback();
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = "@platformatic/kafka";
|
|
2
|
-
export const version = "1.
|
|
2
|
+
export const version = "1.14.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/kafka",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Modern and performant client for Apache Kafka",
|
|
5
5
|
"homepage": "https://github.com/platformatic/kafka",
|
|
6
6
|
"author": "Platformatic Inc. <oss@platformatic.dev> (https://platformatic.dev)",
|
|
@@ -69,12 +69,12 @@
|
|
|
69
69
|
"lint": "eslint --cache",
|
|
70
70
|
"typecheck": "tsc -p . --noEmit",
|
|
71
71
|
"format": "prettier -w benchmarks playground src test",
|
|
72
|
-
"test": "c8 -c test/config/c8-local.json node --env-file=test/config/env --no-warnings --test --test-timeout=
|
|
73
|
-
"test:ci": "c8 -c test/config/c8-ci.json node --env-file=test/config/env --no-warnings --test --test-timeout=
|
|
72
|
+
"test": "c8 -c test/config/c8-local.json node --env-file=test/config/env --no-warnings --test --test-timeout=600000 'test/**/*.test.ts'",
|
|
73
|
+
"test:ci": "c8 -c test/config/c8-ci.json node --env-file=test/config/env --no-warnings --test --test-timeout=600000 'test/**/*.test.ts'",
|
|
74
74
|
"test:docker:up": "node scripts/docker.ts up -d --wait",
|
|
75
75
|
"test:docker:down": "node scripts/docker.ts down",
|
|
76
76
|
"ci": "npm run build && npm run lint && npm run test:ci",
|
|
77
|
-
"ci:v20": "npm run lint && rm -rf dist && tsc -p tsconfig.json && node dist/scripts/postbuild.js && cd dist && c8 -c ../test/config/c8-ci.json node --env-file=../test/config/env --no-warnings --test --test-timeout=
|
|
77
|
+
"ci:v20": "npm run lint && rm -rf dist && tsc -p tsconfig.json && node dist/scripts/postbuild.js && cd dist && c8 -c ../test/config/c8-ci.json node --env-file=../test/config/env --no-warnings --test --test-timeout=600000",
|
|
78
78
|
"generate:apis": "node scripts/generate-apis.ts",
|
|
79
79
|
"generate:errors": "node scripts/generate-errors.ts",
|
|
80
80
|
"create:api": "node scripts/create-api.ts"
|