@platformatic/kafka 1.27.0-alpha.3 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +64 -0
  2. package/dist/apis/admin/create-acls-v2.d.ts +16 -0
  3. package/dist/apis/admin/create-acls-v2.js +55 -0
  4. package/dist/apis/admin/delete-acls-v2.d.ts +21 -0
  5. package/dist/apis/admin/delete-acls-v2.js +84 -0
  6. package/dist/apis/admin/describe-acls-v2.d.ts +17 -0
  7. package/dist/apis/admin/describe-acls-v2.js +66 -0
  8. package/dist/apis/admin/describe-cluster-v0.d.ts +23 -0
  9. package/dist/apis/admin/describe-cluster-v0.js +48 -0
  10. package/dist/apis/admin/describe-log-dirs-v2.d.ts +32 -0
  11. package/dist/apis/admin/describe-log-dirs-v2.js +67 -0
  12. package/dist/apis/admin/describe-log-dirs-v3.d.ts +32 -0
  13. package/dist/apis/admin/describe-log-dirs-v3.js +73 -0
  14. package/dist/apis/admin/index.d.ts +7 -0
  15. package/dist/apis/admin/index.js +7 -0
  16. package/dist/apis/admin/list-transactions-v0.d.ts +18 -0
  17. package/dist/apis/admin/list-transactions-v0.js +43 -0
  18. package/dist/apis/consumer/index.d.ts +8 -0
  19. package/dist/apis/consumer/index.js +8 -0
  20. package/dist/apis/consumer/join-group-v6.d.ts +27 -0
  21. package/dist/apis/consumer/join-group-v6.js +67 -0
  22. package/dist/apis/consumer/join-group-v7.d.ts +27 -0
  23. package/dist/apis/consumer/join-group-v7.js +68 -0
  24. package/dist/apis/consumer/join-group-v8.d.ts +27 -0
  25. package/dist/apis/consumer/join-group-v8.js +70 -0
  26. package/dist/apis/consumer/leave-group-v4.d.ts +22 -0
  27. package/dist/apis/consumer/leave-group-v4.js +56 -0
  28. package/dist/apis/consumer/list-offsets-v5.d.ts +30 -0
  29. package/dist/apis/consumer/list-offsets-v5.js +67 -0
  30. package/dist/apis/consumer/list-offsets-v6.d.ts +30 -0
  31. package/dist/apis/consumer/list-offsets-v6.js +68 -0
  32. package/dist/apis/consumer/list-offsets-v7.d.ts +30 -0
  33. package/dist/apis/consumer/list-offsets-v7.js +68 -0
  34. package/dist/apis/consumer/sync-group-v4.d.ts +18 -0
  35. package/dist/apis/consumer/sync-group-v4.js +43 -0
  36. package/dist/apis/enumerations.d.ts +5 -5
  37. package/dist/apis/producer/add-offsets-to-txn-v1.d.ts +10 -0
  38. package/dist/apis/producer/add-offsets-to-txn-v1.js +33 -0
  39. package/dist/apis/producer/add-offsets-to-txn-v2.d.ts +10 -0
  40. package/dist/apis/producer/add-offsets-to-txn-v2.js +33 -0
  41. package/dist/apis/producer/index.d.ts +3 -0
  42. package/dist/apis/producer/index.js +3 -0
  43. package/dist/apis/producer/init-producer-id-v3.d.ts +21 -0
  44. package/dist/apis/producer/init-producer-id-v3.js +38 -0
  45. package/dist/clients/admin/options.d.ts +9 -9
  46. package/dist/clients/consumer/consumer.js +38 -2
  47. package/dist/clients/consumer/messages-stream.d.ts +2 -2
  48. package/dist/clients/consumer/messages-stream.js +105 -21
  49. package/dist/clients/consumer/options.d.ts +24 -0
  50. package/dist/clients/consumer/options.js +3 -1
  51. package/dist/clients/consumer/types.d.ts +4 -1
  52. package/dist/clients/producer/index.d.ts +1 -0
  53. package/dist/clients/producer/index.js +1 -0
  54. package/dist/clients/producer/options.d.ts +65 -18
  55. package/dist/clients/producer/options.js +21 -1
  56. package/dist/clients/producer/producer-stream.d.ts +19 -0
  57. package/dist/clients/producer/producer-stream.js +187 -0
  58. package/dist/clients/producer/producer.d.ts +6 -3
  59. package/dist/clients/producer/producer.js +137 -19
  60. package/dist/clients/producer/types.d.ts +28 -1
  61. package/dist/clients/producer/types.js +6 -1
  62. package/dist/clients/serde.d.ts +11 -6
  63. package/dist/diagnostic.d.ts +2 -2
  64. package/dist/errors.d.ts +5 -5
  65. package/dist/errors.js +8 -6
  66. package/dist/index.d.ts +1 -0
  67. package/dist/index.js +2 -0
  68. package/dist/network/connection.d.ts +7 -6
  69. package/dist/network/connection.js +1 -1
  70. package/dist/protocol/compression.d.ts +1 -1
  71. package/dist/protocol/compression.js +7 -46
  72. package/dist/protocol/crc32c.d.ts +1 -1
  73. package/dist/protocol/crc32c.js +5 -6
  74. package/dist/protocol/definitions.d.ts +1 -1
  75. package/dist/protocol/definitions.js +1 -1
  76. package/dist/protocol/index.d.ts +0 -2
  77. package/dist/protocol/index.js +0 -2
  78. package/dist/protocol/reader.d.ts +2 -2
  79. package/dist/protocol/reader.js +4 -4
  80. package/dist/protocol/records.d.ts +11 -22
  81. package/dist/protocol/records.js +3 -7
  82. package/dist/protocol/sasl/oauth-bearer.d.ts +3 -3
  83. package/dist/protocol/sasl/plain.d.ts +3 -3
  84. package/dist/protocol/sasl/scram-sha.d.ts +3 -3
  85. package/dist/protocol/sasl/utils.d.ts +3 -3
  86. package/dist/protocol/writer.d.ts +1 -1
  87. package/dist/protocol/writer.js +3 -3
  88. package/dist/registries/abstract.d.ts +22 -0
  89. package/dist/registries/abstract.js +38 -0
  90. package/dist/registries/confluent-schema-registry.d.ts +41 -0
  91. package/dist/registries/confluent-schema-registry.js +222 -0
  92. package/dist/registries/index.d.ts +2 -0
  93. package/dist/registries/index.js +2 -0
  94. package/dist/typescript-4/dist/apis/admin/create-acls-v2.d.ts +16 -0
  95. package/dist/typescript-4/dist/apis/admin/delete-acls-v2.d.ts +21 -0
  96. package/dist/typescript-4/dist/apis/admin/describe-acls-v2.d.ts +17 -0
  97. package/dist/typescript-4/dist/apis/admin/describe-cluster-v0.d.ts +23 -0
  98. package/dist/typescript-4/dist/apis/admin/describe-log-dirs-v2.d.ts +32 -0
  99. package/dist/typescript-4/dist/apis/admin/describe-log-dirs-v3.d.ts +32 -0
  100. package/dist/typescript-4/dist/apis/admin/index.d.ts +7 -0
  101. package/dist/typescript-4/dist/apis/admin/list-transactions-v0.d.ts +18 -0
  102. package/dist/typescript-4/dist/apis/consumer/index.d.ts +8 -0
  103. package/dist/typescript-4/dist/apis/consumer/join-group-v6.d.ts +27 -0
  104. package/dist/typescript-4/dist/apis/consumer/join-group-v7.d.ts +27 -0
  105. package/dist/typescript-4/dist/apis/consumer/join-group-v8.d.ts +27 -0
  106. package/dist/typescript-4/dist/apis/consumer/leave-group-v4.d.ts +22 -0
  107. package/dist/typescript-4/dist/apis/consumer/list-offsets-v5.d.ts +30 -0
  108. package/dist/typescript-4/dist/apis/consumer/list-offsets-v6.d.ts +30 -0
  109. package/dist/typescript-4/dist/apis/consumer/list-offsets-v7.d.ts +30 -0
  110. package/dist/typescript-4/dist/apis/consumer/sync-group-v4.d.ts +18 -0
  111. package/dist/typescript-4/dist/apis/enumerations.d.ts +5 -5
  112. package/dist/typescript-4/dist/apis/producer/add-offsets-to-txn-v1.d.ts +10 -0
  113. package/dist/typescript-4/dist/apis/producer/add-offsets-to-txn-v2.d.ts +10 -0
  114. package/dist/typescript-4/dist/apis/producer/index.d.ts +3 -0
  115. package/dist/typescript-4/dist/apis/producer/init-producer-id-v3.d.ts +21 -0
  116. package/dist/typescript-4/dist/clients/admin/options.d.ts +9 -9
  117. package/dist/typescript-4/dist/clients/consumer/messages-stream.d.ts +2 -2
  118. package/dist/typescript-4/dist/clients/consumer/options.d.ts +24 -0
  119. package/dist/typescript-4/dist/clients/consumer/types.d.ts +4 -1
  120. package/dist/typescript-4/dist/clients/producer/index.d.ts +1 -0
  121. package/dist/typescript-4/dist/clients/producer/options.d.ts +66 -19
  122. package/dist/typescript-4/dist/clients/producer/producer-stream.d.ts +19 -0
  123. package/dist/typescript-4/dist/clients/producer/producer.d.ts +6 -3
  124. package/dist/typescript-4/dist/clients/producer/types.d.ts +29 -2
  125. package/dist/typescript-4/dist/clients/serde.d.ts +11 -6
  126. package/dist/typescript-4/dist/diagnostic.d.ts +2 -2
  127. package/dist/typescript-4/dist/errors.d.ts +5 -5
  128. package/dist/typescript-4/dist/index.d.ts +2 -1
  129. package/dist/typescript-4/dist/network/connection.d.ts +7 -6
  130. package/dist/typescript-4/dist/protocol/compression.d.ts +1 -1
  131. package/dist/typescript-4/dist/protocol/crc32c.d.ts +1 -1
  132. package/dist/typescript-4/dist/protocol/definitions.d.ts +1 -1
  133. package/dist/typescript-4/dist/protocol/index.d.ts +0 -2
  134. package/dist/typescript-4/dist/protocol/reader.d.ts +2 -2
  135. package/dist/typescript-4/dist/protocol/records.d.ts +11 -22
  136. package/dist/typescript-4/dist/protocol/sasl/oauth-bearer.d.ts +3 -3
  137. package/dist/typescript-4/dist/protocol/sasl/plain.d.ts +3 -3
  138. package/dist/typescript-4/dist/protocol/sasl/scram-sha.d.ts +3 -3
  139. package/dist/typescript-4/dist/protocol/sasl/utils.d.ts +3 -3
  140. package/dist/typescript-4/dist/protocol/writer.d.ts +1 -1
  141. package/dist/typescript-4/dist/registries/abstract.d.ts +22 -0
  142. package/dist/typescript-4/dist/registries/confluent-schema-registry.d.ts +41 -0
  143. package/dist/typescript-4/dist/registries/index.d.ts +2 -0
  144. package/dist/typescript-4/dist/utils.d.ts +3 -2
  145. package/dist/utils.d.ts +2 -1
  146. package/dist/utils.js +3 -0
  147. package/dist/version.js +1 -1
  148. package/package.json +14 -11
  149. package/dist/protocol/dynamic-buffer.d.ts +0 -65
  150. package/dist/protocol/dynamic-buffer.js +0 -563
  151. package/dist/protocol/varint.d.ts +0 -12
  152. package/dist/protocol/varint.js +0 -36
  153. package/dist/typescript-4/dist/protocol/dynamic-buffer.d.ts +0 -65
  154. package/dist/typescript-4/dist/protocol/varint.d.ts +0 -12
@@ -2,7 +2,6 @@ export * from './apis.ts';
2
2
  export * from './compression.ts';
3
3
  export * from './crc32c.ts';
4
4
  export * from './definitions.ts';
5
- export * from './dynamic-buffer.ts';
6
5
  export * from './errors.ts';
7
6
  export * from './murmur2.ts';
8
7
  export * from './reader.ts';
@@ -11,5 +10,4 @@ export * as saslOAuthBearer from './sasl/oauth-bearer.ts';
11
10
  export * as saslPlain from './sasl/plain.ts';
12
11
  export * as saslScramSha from './sasl/scram-sha.ts';
13
12
  export * as saslUtils from './sasl/utils.ts';
14
- export * from './varint.ts';
15
13
  export * from './writer.ts';
@@ -2,7 +2,6 @@ export * from "./apis.js";
2
2
  export * from "./compression.js";
3
3
  export * from "./crc32c.js";
4
4
  export * from "./definitions.js";
5
- export * from "./dynamic-buffer.js";
6
5
  export * from "./errors.js";
7
6
  export * from "./murmur2.js";
8
7
  export * from "./reader.js";
@@ -11,5 +10,4 @@ export * as saslOAuthBearer from "./sasl/oauth-bearer.js";
11
10
  export * as saslPlain from "./sasl/plain.js";
12
11
  export * as saslScramSha from "./sasl/scram-sha.js";
13
12
  export * as saslUtils from "./sasl/utils.js";
14
- export * from "./varint.js";
15
13
  export * from "./writer.js";
@@ -1,4 +1,4 @@
1
- import { DynamicBuffer } from './dynamic-buffer.ts';
1
+ import { DynamicBuffer } from '@platformatic/dynamic-buffer';
2
2
  import { Writer } from './writer.ts';
3
3
  export type EntryReader<OutputType> = (reader: Reader, index: number) => OutputType;
4
4
  declare const instanceIdentifier: unique symbol;
@@ -48,7 +48,7 @@ export declare class Reader {
48
48
  readUUID(): string;
49
49
  readNullableBytes(compact?: boolean): Buffer | null;
50
50
  readBytes(compact?: boolean): Buffer;
51
- readVarIntBytes(): Buffer;
51
+ readVarIntBytes(): Buffer | null;
52
52
  readNullableArray<OutputType>(reader: EntryReader<OutputType>, compact?: boolean, discardTrailingTaggedFields?: boolean): OutputType[] | null;
53
53
  readNullableMap<Key, Value>(reader: EntryReader<[Key, Value]>, compact?: boolean, discardTrailingTaggedFields?: boolean): Map<Key, Value> | null;
54
54
  readArray<OutputType>(reader: EntryReader<OutputType>, compact?: boolean, discardTrailingTaggedFields?: boolean): OutputType[];
@@ -1,5 +1,5 @@
1
+ import { DynamicBuffer } from '@platformatic/dynamic-buffer';
1
2
  import { EMPTY_BUFFER, INT16_SIZE, INT32_SIZE, INT64_SIZE, INT8_SIZE, UUID_SIZE } from "./definitions.js";
2
- import { DynamicBuffer } from "./dynamic-buffer.js";
3
3
  import { Writer } from "./writer.js";
4
4
  const instanceIdentifier = Symbol('plt.kafka.reader.instanceIdentifier');
5
5
  export class Reader {
@@ -214,9 +214,9 @@ export class Reader {
214
214
  return this.readNullableBytes(compact) || EMPTY_BUFFER;
215
215
  }
216
216
  readVarIntBytes() {
217
- let length = this.readVarInt();
217
+ const length = this.readVarInt();
218
218
  if (length === -1) {
219
- length = 0;
219
+ return null;
220
220
  }
221
221
  const value = this.buffer.slice(this.position, this.position + length);
222
222
  this.position += length;
@@ -300,7 +300,7 @@ export class Reader {
300
300
  }
301
301
  return reader();
302
302
  }
303
- // TODO(ShogunPanda): Tagged fields are not supported yet
303
+ // TODO: Tagged fields are not supported yet
304
304
  readTaggedFields() {
305
305
  const length = this.readVarInt();
306
306
  if (length > 0) {
@@ -1,4 +1,4 @@
1
- import { type NumericMap } from '../utils.ts';
1
+ import type { NumericMap } from '../utils.ts';
2
2
  import { type CompressionAlgorithmValue } from './compression.ts';
3
3
  import { type NullableString } from './definitions.ts';
4
4
  import { Reader } from './reader.ts';
@@ -17,6 +17,7 @@ export interface MessageBase<Key = Buffer, Value = Buffer> {
17
17
  }
18
18
  export interface MessageToProduce<Key = Buffer, Value = Buffer, HeaderKey = Buffer, HeaderValue = Buffer> extends MessageBase<Key, Value> {
19
19
  headers?: Map<HeaderKey, HeaderValue> | Record<string, HeaderValue>;
20
+ metadata?: unknown;
20
21
  }
21
22
  export interface MessageConsumerMetadata {
22
23
  coordinatorId: number;
@@ -63,9 +64,13 @@ export interface KafkaRecord {
63
64
  attributes: number;
64
65
  timestampDelta: bigint;
65
66
  offsetDelta: number;
66
- key: Buffer;
67
- value: Buffer;
68
- headers: [Buffer, Buffer][];
67
+ key: Buffer | null;
68
+ value: Buffer | null;
69
+ headers: [Buffer | null, Buffer | null][];
70
+ }
71
+ export interface MessageToConsume extends KafkaRecord {
72
+ topic: string;
73
+ partition: number;
69
74
  }
70
75
  export interface RecordsBatch {
71
76
  firstOffset: bigint;
@@ -85,24 +90,8 @@ export interface RecordsBatch {
85
90
  export declare const messageSchema: {
86
91
  type: string;
87
92
  properties: {
88
- key: {
89
- oneOf: ({
90
- type: string;
91
- buffer?: undefined;
92
- } | {
93
- buffer: boolean;
94
- type?: undefined;
95
- })[];
96
- };
97
- value: {
98
- oneOf: ({
99
- type: string;
100
- buffer?: undefined;
101
- } | {
102
- buffer: boolean;
103
- type?: undefined;
104
- })[];
105
- };
93
+ key: boolean;
94
+ value: boolean;
106
95
  headers: {
107
96
  anyOf: ({
108
97
  map: boolean;
@@ -1,8 +1,8 @@
1
+ import { DynamicBuffer } from '@platformatic/dynamic-buffer';
1
2
  import { UnsupportedCompressionError } from "../errors.js";
2
3
  import { compressionsAlgorithms, compressionsAlgorithmsByBitmask } from "./compression.js";
3
4
  import { crc32c } from "./crc32c.js";
4
5
  import { INT32_SIZE, INT64_SIZE } from "./definitions.js";
5
- import { DynamicBuffer } from "./dynamic-buffer.js";
6
6
  import { Reader } from "./reader.js";
7
7
  import { Writer } from "./writer.js";
8
8
  export const CURRENT_RECORD_VERSION = 2;
@@ -14,12 +14,8 @@ export const BATCH_HEAD = INT64_SIZE + INT32_SIZE; // FirstOffset + Length
14
14
  export const messageSchema = {
15
15
  type: 'object',
16
16
  properties: {
17
- key: {
18
- oneOf: [{ type: 'string' }, { buffer: true }]
19
- },
20
- value: {
21
- oneOf: [{ type: 'string' }, { buffer: true }]
22
- },
17
+ key: true,
18
+ value: true,
23
19
  headers: {
24
20
  // Note: we can't use oneOf here since a Map is also a 'object'. Thanks JS.
25
21
  anyOf: [
@@ -1,6 +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
- import { type Connection, type SASLCredentialProvider } from '../../network/connection.ts';
3
+ import { type Connection, type CredentialProvider } from '../../network/connection.ts';
4
4
  export declare function jwtValidateAuthenticationBytes(authBytes: Buffer, callback: CallbackWithPromise<Buffer>): void;
5
- export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | SASLCredentialProvider, extensions: Record<string, string> | SASLCredentialProvider<Record<string, string>>, callback: CallbackWithPromise<SaslAuthenticateResponse>): void;
6
- export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | SASLCredentialProvider, extensions: Record<string, string> | SASLCredentialProvider<Record<string, string>>): Promise<SaslAuthenticateResponse>;
5
+ export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | CredentialProvider, extensions: Record<string, string> | CredentialProvider<Record<string, string>>, callback: CallbackWithPromise<SaslAuthenticateResponse>): void;
6
+ export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | CredentialProvider, extensions: Record<string, string> | CredentialProvider<Record<string, string>>): Promise<SaslAuthenticateResponse>;
@@ -1,5 +1,5 @@
1
1
  import { type CallbackWithPromise } from '../../apis/callbacks.ts';
2
2
  import { type SASLAuthenticationAPI, type SaslAuthenticateResponse } from '../../apis/security/sasl-authenticate-v2.ts';
3
- import { type Connection, type SASLCredentialProvider } from '../../network/connection.ts';
4
- export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, usernameProvider: string | SASLCredentialProvider, passwordProvider: string | SASLCredentialProvider, callback: CallbackWithPromise<SaslAuthenticateResponse>): void;
5
- export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, usernameProvider: string | SASLCredentialProvider, passwordProvider: string | SASLCredentialProvider): Promise<SaslAuthenticateResponse>;
3
+ import { type Connection, type CredentialProvider } from '../../network/connection.ts';
4
+ export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, usernameProvider: string | CredentialProvider, passwordProvider: string | CredentialProvider, callback: CallbackWithPromise<SaslAuthenticateResponse>): void;
5
+ export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, usernameProvider: string | CredentialProvider, passwordProvider: string | CredentialProvider): Promise<SaslAuthenticateResponse>;
@@ -1,6 +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
- import { type Connection, type SASLCredentialProvider } from '../../network/connection.ts';
3
+ import { type Connection, type CredentialProvider } from '../../network/connection.ts';
4
4
  export interface ScramAlgorithmDefinition {
5
5
  keyLength: number;
6
6
  algorithm: string;
@@ -35,5 +35,5 @@ export declare function hi(definition: ScramAlgorithmDefinition, password: strin
35
35
  export declare function hmac(definition: ScramAlgorithmDefinition, key: Buffer, data: string | Buffer): Buffer;
36
36
  export declare function xor(a: Buffer, b: Buffer): Buffer;
37
37
  export declare const defaultCrypto: ScramCryptoModule;
38
- export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, algorithm: ScramAlgorithm, usernameProvider: string | SASLCredentialProvider, passwordProvider: string | SASLCredentialProvider, crypto: ScramCryptoModule, callback: CallbackWithPromise<SaslAuthenticateResponse>): void;
39
- export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, algorithm: ScramAlgorithm, usernameProvider: string | SASLCredentialProvider, passwordProvider: string | SASLCredentialProvider, crypto?: ScramCryptoModule): Promise<SaslAuthenticateResponse>;
38
+ export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, algorithm: ScramAlgorithm, usernameProvider: string | CredentialProvider, passwordProvider: string | CredentialProvider, crypto: ScramCryptoModule, callback: CallbackWithPromise<SaslAuthenticateResponse>): void;
39
+ export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, algorithm: ScramAlgorithm, usernameProvider: string | CredentialProvider, passwordProvider: string | CredentialProvider, crypto?: ScramCryptoModule): Promise<SaslAuthenticateResponse>;
@@ -1,4 +1,4 @@
1
1
  import { type CallbackWithPromise } from '../../apis/index.ts';
2
- import { type SASLCredentialProvider } from '../../network/connection.ts';
3
- export declare function getCredential<T>(label: string, credentialOrProvider: T | SASLCredentialProvider<T>, callback: CallbackWithPromise<T>): void;
4
- export declare function getCredential<T>(label: string, credentialOrProvider: T | SASLCredentialProvider<T>): Promise<T>;
2
+ import { type CredentialProvider } from '../../network/connection.ts';
3
+ export declare function getCredential<T>(label: string, credentialOrProvider: T | CredentialProvider<T>, callback: CallbackWithPromise<T>): void;
4
+ export declare function getCredential<T>(label: string, credentialOrProvider: T | CredentialProvider<T>): Promise<T>;
@@ -1,5 +1,5 @@
1
+ import { DynamicBuffer } from '@platformatic/dynamic-buffer';
1
2
  import { type NullableString } from './definitions.ts';
2
- import { DynamicBuffer } from './dynamic-buffer.ts';
3
3
  export type ChildrenWriter = (w: Writer) => void;
4
4
  export type EntryWriter<InputType> = (writer: Writer, entry: InputType, index: number) => void;
5
5
  declare const instanceIdentifier: unique symbol;
@@ -1,6 +1,6 @@
1
+ import { DynamicBuffer } from '@platformatic/dynamic-buffer';
1
2
  import { humanize } from "../utils.js";
2
3
  import { EMPTY_TAGGED_FIELDS_BUFFER, EMPTY_UUID } from "./definitions.js";
3
- import { DynamicBuffer } from "./dynamic-buffer.js";
4
4
  const instanceIdentifier = Symbol('plt.kafka.writer.instanceIdentifier');
5
5
  export class Writer {
6
6
  context;
@@ -144,7 +144,7 @@ export class Writer {
144
144
  // Note that this does not follow the wire protocol specification and thus the length is not +1ed
145
145
  appendVarIntBytes(value) {
146
146
  if (value == null) {
147
- return this.appendVarInt(0);
147
+ return this.appendVarInt(-1);
148
148
  }
149
149
  this.appendVarInt(value.length);
150
150
  this.#buffer.append(value);
@@ -210,7 +210,7 @@ export class Writer {
210
210
  }
211
211
  return this;
212
212
  }
213
- // TODO(ShogunPanda): Tagged fields are not supported yet
213
+ // TODO: Tagged fields are not supported yet
214
214
  appendTaggedFields(_ = []) {
215
215
  return this.append(EMPTY_TAGGED_FIELDS_BUFFER);
216
216
  }
@@ -0,0 +1,22 @@
1
+ import { type Callback } from '../apis/definitions.ts';
2
+ import { type BeforeDeserializationHook, type BeforeHookPayloadType, type BeforeSerializationHook, type Deserializers, type Serializers } from '../clients/serde.ts';
3
+ import { type MessageToProduce } from '../protocol/records.ts';
4
+ export interface SchemaRegistry<Id = unknown, Schema = unknown, Key = Buffer, Value = Buffer, HeaderKey = Buffer, HeaderValue = Buffer> {
5
+ get(id: Id): Schema | undefined;
6
+ fetch(id: Id, callback?: (error?: Error) => void): void | Promise<void>;
7
+ getSchemaId(payload: Buffer | MessageToProduce<Key, Value, HeaderKey, HeaderValue>, type?: BeforeHookPayloadType): Id;
8
+ getSerializers(): Serializers<Key, Value, HeaderKey, HeaderValue>;
9
+ getDeserializers(): Deserializers<Key, Value, HeaderKey, HeaderValue>;
10
+ getBeforeSerializationHook(): BeforeSerializationHook<Key, Value, HeaderKey, HeaderValue>;
11
+ getBeforeDeserializationHook(): BeforeDeserializationHook;
12
+ }
13
+ export declare function runAsyncSeries<V>(operation: (item: V, cb: Callback<void>) => void | Promise<void>, collection: V[], index: number, callback: Callback<void>): void;
14
+ export declare class AbstractSchemaRegistry<Id = unknown, Schema = unknown, Key = Buffer, Value = Buffer, HeaderKey = Buffer, HeaderValue = Buffer> implements SchemaRegistry<Id, Schema, Key, Value, HeaderKey, HeaderValue> {
15
+ get(_: Id): Schema | undefined;
16
+ fetch(_i: unknown, _c?: (error?: Error) => void): void | Promise<void>;
17
+ getSchemaId(_p: Buffer | MessageToProduce<Key, Value, HeaderKey, HeaderValue>, _t?: BeforeHookPayloadType): Id;
18
+ getSerializers(): Serializers<Key, Value, HeaderKey, HeaderValue>;
19
+ getDeserializers(): Deserializers<Key, Value, HeaderKey, HeaderValue>;
20
+ getBeforeSerializationHook(): BeforeSerializationHook<Key, Value, HeaderKey, HeaderValue>;
21
+ getBeforeDeserializationHook(): BeforeDeserializationHook;
22
+ }
@@ -0,0 +1,38 @@
1
+ export function runAsyncSeries(operation, collection, index, callback) {
2
+ operation(collection[index], error => {
3
+ if (error) {
4
+ callback(error);
5
+ return;
6
+ }
7
+ else if (index === collection.length - 1) {
8
+ callback(null);
9
+ return;
10
+ }
11
+ runAsyncSeries(operation, collection, index + 1, callback);
12
+ });
13
+ }
14
+ /* c8 ignore start */
15
+ export class AbstractSchemaRegistry {
16
+ get(_) {
17
+ throw new Error('AbstractSchemaRegistry.get() should be implemented in subclasses.');
18
+ }
19
+ fetch(_i, _c) {
20
+ throw new Error('AbstractSchemaRegistry.fetch() should be implemented in subclasses.');
21
+ }
22
+ getSchemaId(_p, _t) {
23
+ throw new Error('AbstractSchemaRegistry.getSchemaId() should be implemented in subclasses.');
24
+ }
25
+ getSerializers() {
26
+ throw new Error('AbstractSchemaRegistry.getSerializers() should be implemented in subclasses.');
27
+ }
28
+ getDeserializers() {
29
+ throw new Error('AbstractSchemaRegistry.getDeserializers() should be implemented in subclasses.');
30
+ }
31
+ getBeforeSerializationHook() {
32
+ throw new Error('AbstractSchemaRegistry.getBeforeSerializationHook() should be implemented in subclasses.');
33
+ }
34
+ getBeforeDeserializationHook() {
35
+ throw new Error('AbstractSchemaRegistry.getBeforeDeserializationHook() should be implemented in subclasses.');
36
+ }
37
+ }
38
+ /* c8 ignore end */
@@ -0,0 +1,41 @@
1
+ import { type ValidateFunction } from 'ajv';
2
+ import { type Type } from 'avsc';
3
+ import { type Root } from 'protobufjs';
4
+ import { type Callback } from '../apis/definitions.ts';
5
+ import { type BeforeDeserializationHook, type BeforeHookPayloadType, type BeforeSerializationHook, type Deserializers, type Serializers } from '../clients/serde.ts';
6
+ import { type CredentialProvider } from '../index.ts';
7
+ import { type MessageToConsume, type MessageToProduce } from '../protocol/records.ts';
8
+ import { AbstractSchemaRegistry } from './abstract.ts';
9
+ type ConfluentSchemaRegistryMessageToProduce = MessageToProduce<unknown, unknown, unknown, unknown>;
10
+ export interface ConfluentSchemaRegistryMetadata {
11
+ schemas?: Record<BeforeHookPayloadType, number>;
12
+ }
13
+ export type ConfluentSchemaRegistryProtobufTypeMapper = (id: number, type: BeforeHookPayloadType, context: ConfluentSchemaRegistryMessageToProduce | MessageToConsume) => string;
14
+ export interface ConfluentSchemaRegistryOptions {
15
+ url: string;
16
+ auth?: {
17
+ username?: string | CredentialProvider;
18
+ password?: string | CredentialProvider;
19
+ token?: string | CredentialProvider;
20
+ };
21
+ protobufTypeMapper?: ConfluentSchemaRegistryProtobufTypeMapper;
22
+ jsonValidateSend?: boolean;
23
+ }
24
+ export interface Schema {
25
+ id: number;
26
+ type: 'avro' | 'protobuf' | 'json';
27
+ schema: Type | Root | ValidateFunction;
28
+ }
29
+ export declare function defaultProtobufTypeMapper(_: number, type: BeforeHookPayloadType, context: ConfluentSchemaRegistryMessageToProduce | MessageToConsume): string;
30
+ export declare class ConfluentSchemaRegistry<Key = Buffer, Value = Buffer, HeaderKey = Buffer, HeaderValue = Buffer> extends AbstractSchemaRegistry<number | undefined, Schema, Key, Value, HeaderKey, HeaderValue> {
31
+ #private;
32
+ constructor(options: ConfluentSchemaRegistryOptions);
33
+ getSchemaId(message: Buffer | MessageToProduce<Key, Value, HeaderKey, HeaderValue>, type?: BeforeHookPayloadType): number | undefined;
34
+ get(id: number): Schema | undefined;
35
+ fetchSchema(id: number, callback: Callback<void>): Promise<void>;
36
+ getSerializers(): Serializers<Key, Value, HeaderKey, HeaderValue>;
37
+ getDeserializers(): Deserializers<Key, Value, HeaderKey, HeaderValue>;
38
+ getBeforeSerializationHook(): BeforeSerializationHook<Key, Value, HeaderKey, HeaderValue>;
39
+ getBeforeDeserializationHook(): BeforeDeserializationHook;
40
+ }
41
+ export {};
@@ -0,0 +1,222 @@
1
+ import avro from 'avsc';
2
+ import { createRequire } from 'node:module';
3
+ import { jsonDeserializer, jsonSerializer, stringDeserializer, stringSerializer } from "../clients/serde.js";
4
+ import { ajv, EMPTY_BUFFER, UnsupportedFormatError, UserError } from "../index.js";
5
+ import { getCredential } from "../protocol/sasl/utils.js";
6
+ import { AbstractSchemaRegistry } from "./abstract.js";
7
+ const require = createRequire(import.meta.url);
8
+ /* c8 ignore next 8 */
9
+ export function defaultProtobufTypeMapper(_, type, context) {
10
+ // Confluent Schema Registry convention
11
+ return `${context.topic}-${type}`;
12
+ }
13
+ // TODO(ShogunPanda): Authentication support
14
+ export class ConfluentSchemaRegistry extends AbstractSchemaRegistry {
15
+ #url;
16
+ #schemas;
17
+ #protobufParse;
18
+ #protobufTypeMapper;
19
+ #jsonValidateSend;
20
+ #auth;
21
+ constructor(options) {
22
+ super();
23
+ this.#url = options.url;
24
+ this.#schemas = new Map();
25
+ this.#protobufTypeMapper = options.protobufTypeMapper ?? defaultProtobufTypeMapper;
26
+ this.#jsonValidateSend = options.jsonValidateSend ?? false;
27
+ this.#auth = options.auth;
28
+ }
29
+ getSchemaId(message, type) {
30
+ if (Buffer.isBuffer(message)) {
31
+ if (type !== 'value') {
32
+ return undefined;
33
+ }
34
+ return message.readInt32BE(1);
35
+ }
36
+ return message.metadata?.schemas?.[type];
37
+ }
38
+ get(id) {
39
+ return this.#schemas.get(id);
40
+ }
41
+ async fetchSchema(id, callback) {
42
+ try {
43
+ const requestInit = {};
44
+ if (this.#auth) {
45
+ if (this.#auth.token) {
46
+ const token = await getCredential('token', this.#auth.token);
47
+ requestInit.headers = {
48
+ Authorization: `Bearer ${token}`
49
+ };
50
+ }
51
+ else {
52
+ const username = await getCredential('username', this.#auth.username);
53
+ const password = await getCredential('password', this.#auth.password);
54
+ requestInit.headers = {
55
+ Authorization: `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`
56
+ };
57
+ }
58
+ }
59
+ const response = await fetch(`${this.#url}/schemas/ids/${id}`, requestInit);
60
+ if (!response.ok) {
61
+ throw new UserError(`Failed to fetch a schema: [HTTP ${response.status}]`, { response: await response.text() });
62
+ }
63
+ const responseBody = await response.json();
64
+ const { schema, schemaType } = responseBody;
65
+ switch (schemaType) {
66
+ case 'AVRO':
67
+ this.#schemas.set(id, { id, type: 'avro', schema: avro.Type.forSchema(JSON.parse(schema)) });
68
+ break;
69
+ case 'PROTOBUF':
70
+ this.#protobufParse ??= this.#loadProtobuf();
71
+ this.#schemas.set(id, { id, type: 'protobuf', schema: this.#protobufParse(schema).root });
72
+ break;
73
+ case 'JSON':
74
+ this.#schemas.set(id, { id, type: 'json', schema: ajv.compile(JSON.parse(schema)) });
75
+ break;
76
+ }
77
+ process.nextTick(callback);
78
+ }
79
+ catch (err) {
80
+ process.nextTick(() => callback(err));
81
+ }
82
+ }
83
+ getSerializers() {
84
+ return {
85
+ key: this.#schemaSerializer.bind(this, 'key', stringSerializer),
86
+ value: this.#schemaSerializer.bind(this, 'value', jsonSerializer),
87
+ headerKey: this.#schemaSerializer.bind(this, 'headerKey', stringSerializer),
88
+ headerValue: this.#schemaSerializer.bind(this, 'headerValue', jsonSerializer)
89
+ };
90
+ }
91
+ getDeserializers() {
92
+ return {
93
+ key: this.#schemaDeserializer.bind(this, 'key', stringDeserializer),
94
+ value: this.#schemaDeserializer.bind(this, 'value', jsonDeserializer),
95
+ headerKey: this.#schemaDeserializer.bind(this, 'headerKey', stringDeserializer),
96
+ headerValue: this.#schemaDeserializer.bind(this, 'headerValue', jsonDeserializer)
97
+ };
98
+ }
99
+ getBeforeSerializationHook() {
100
+ const registry = this;
101
+ return function beforeSerialization(_, type, message, callback) {
102
+ // Extract the schema ID from the message metadata
103
+ const schemaId = registry.getSchemaId(message, type);
104
+ // When no schema ID is found, nothing to do
105
+ if (!schemaId) {
106
+ callback(null);
107
+ return;
108
+ }
109
+ // The schema is already fetch
110
+ if (registry.get(schemaId)) {
111
+ callback(null);
112
+ return;
113
+ }
114
+ registry.fetchSchema(schemaId, callback);
115
+ };
116
+ }
117
+ getBeforeDeserializationHook() {
118
+ const registry = this;
119
+ return function beforeDeserialization(payload, type, _message, callback) {
120
+ // Extract the schema ID from the message metadata
121
+ const schemaId = registry.getSchemaId(payload, type);
122
+ // When no schema ID is found, nothing to do
123
+ if (!schemaId) {
124
+ callback(null);
125
+ return;
126
+ }
127
+ // The schema is already fetch
128
+ if (registry.get(schemaId)) {
129
+ callback(null);
130
+ return;
131
+ }
132
+ registry.fetchSchema(schemaId, callback);
133
+ };
134
+ }
135
+ #schemaSerializer(type, fallbackSerializer, data, headers, message) {
136
+ /* c8 ignore next 3 - Hard to test */
137
+ if (typeof data === 'undefined') {
138
+ return EMPTY_BUFFER;
139
+ }
140
+ if (type === 'headerKey' || type === 'headerValue') {
141
+ message = headers;
142
+ }
143
+ const schemaId = message?.metadata?.schemas?.[type];
144
+ if (!schemaId) {
145
+ return fallbackSerializer(data);
146
+ }
147
+ const schema = this.#schemas.get(schemaId);
148
+ if (!schema) {
149
+ throw new UserError(`Schema with ID ${schemaId} not found.`, { missingSchema: schemaId });
150
+ }
151
+ let encodedMessage;
152
+ switch (schema.type) {
153
+ case 'avro':
154
+ encodedMessage = schema.schema.toBuffer(data);
155
+ break;
156
+ case 'protobuf':
157
+ {
158
+ const typeName = this.#protobufTypeMapper(schemaId, type, message);
159
+ const Type = schema.schema.lookupType(typeName);
160
+ encodedMessage = Buffer.from(Type.encode(Type.create(data)).finish());
161
+ }
162
+ break;
163
+ case 'json':
164
+ if (this.#jsonValidateSend) {
165
+ const validate = schema.schema;
166
+ const valid = validate(data);
167
+ if (!valid) {
168
+ throw new UserError(`JSON Schema validation failed before serialization: ${ajv.errorsText(validate.errors)}`, { type, data, headers, validationErrors: validate.errors });
169
+ }
170
+ }
171
+ encodedMessage = Buffer.from(JSON.stringify(data));
172
+ break;
173
+ }
174
+ const header = Buffer.alloc(5);
175
+ header.writeInt32BE(schemaId, 1);
176
+ return Buffer.concat([header, encodedMessage]);
177
+ }
178
+ #schemaDeserializer(type, fallbackDeserializer, data, headers, message) {
179
+ /* c8 ignore next 3 - Hard to test */
180
+ if (typeof data === 'undefined' || data.length === 0) {
181
+ return EMPTY_BUFFER;
182
+ }
183
+ if (type === 'headerKey' || type === 'headerValue') {
184
+ message = headers;
185
+ }
186
+ const schemaId = this.getSchemaId(data, type);
187
+ if (!schemaId) {
188
+ return fallbackDeserializer(data);
189
+ }
190
+ const schema = this.#schemas.get(schemaId);
191
+ if (!schema) {
192
+ throw new UserError(`Schema with ID ${schemaId} not found.`, { missingSchema: schemaId });
193
+ }
194
+ switch (schema.type) {
195
+ case 'avro':
196
+ return schema.schema.fromBuffer(data.subarray(5));
197
+ case 'protobuf': {
198
+ const typeName = this.#protobufTypeMapper(schemaId, type, message);
199
+ const Type = schema.schema.lookupType(typeName);
200
+ return Type.decode(data.subarray(5));
201
+ }
202
+ case 'json': {
203
+ const parsed = JSON.parse(data.subarray(5).toString('utf-8'));
204
+ const validate = schema.schema;
205
+ const valid = validate(parsed);
206
+ if (!valid) {
207
+ throw new UserError(`JSON Schema validation failed before deserialization: ${ajv.errorsText(validate.errors)}`, { type, data: parsed, headers, validationErrors: validate.errors });
208
+ }
209
+ return parsed;
210
+ }
211
+ }
212
+ }
213
+ #loadProtobuf() {
214
+ try {
215
+ return require('protobufjs').parse;
216
+ /* c8 ignore next 5 - In tests protobufjs is always available */
217
+ }
218
+ catch (e) {
219
+ throw new UnsupportedFormatError('Cannot load protobufjs module, which is an optionalDependency. Please check your local installation.');
220
+ }
221
+ }
222
+ }
@@ -0,0 +1,2 @@
1
+ export * from './abstract.ts';
2
+ export * from './confluent-schema-registry.ts';
@@ -0,0 +1,2 @@
1
+ export * from "./abstract.js";
2
+ export * from "./confluent-schema-registry.js";
@@ -0,0 +1,16 @@
1
+ import { type NullableString } from "../../protocol/definitions";
2
+ import { type Reader } from "../../protocol/reader";
3
+ import { Writer } from "../../protocol/writer";
4
+ import { type Acl } from "../types";
5
+ export type CreateAclsRequest = Parameters<typeof createRequest>;
6
+ export interface CreateAclsResponseResult {
7
+ errorCode: number;
8
+ errorMessage: NullableString;
9
+ }
10
+ export interface CreateAclsResponse {
11
+ throttleTimeMs: number;
12
+ results: CreateAclsResponseResult[];
13
+ }
14
+ export declare function createRequest(creations: Acl[]): Writer;
15
+ export declare function parseResponse(_correlationId: number, apiKey: number, apiVersion: number, reader: Reader): CreateAclsResponse;
16
+ export declare const api: import("../definitions").API<[creations: Acl[]], CreateAclsResponse>;
@@ -0,0 +1,21 @@
1
+ import { type NullableString } from "../../protocol/definitions";
2
+ import { type Reader } from "../../protocol/reader";
3
+ import { Writer } from "../../protocol/writer";
4
+ import { type Acl, type AclFilter } from "../types";
5
+ export type DeleteAclsRequest = Parameters<typeof createRequest>;
6
+ export interface DeleteAclsResponseMatchingAcl extends Acl {
7
+ errorCode: number;
8
+ errorMessage: NullableString;
9
+ }
10
+ export interface DeleteAclsResponseFilterResults {
11
+ errorCode: number;
12
+ errorMessage: NullableString;
13
+ matchingAcls: DeleteAclsResponseMatchingAcl[];
14
+ }
15
+ export interface DeleteAclsResponse {
16
+ throttleTimeMs: number;
17
+ filterResults: DeleteAclsResponseFilterResults[];
18
+ }
19
+ export declare function createRequest(filters: AclFilter[]): Writer;
20
+ export declare function parseResponse(_correlationId: number, apiKey: number, apiVersion: number, reader: Reader): DeleteAclsResponse;
21
+ export declare const api: import("../definitions").API<[filters: AclFilter[]], DeleteAclsResponse>;
@@ -0,0 +1,17 @@
1
+ import { type NullableString } from "../../protocol/definitions";
2
+ import { type Reader } from "../../protocol/reader";
3
+ import { Writer } from "../../protocol/writer";
4
+ import { type AclPermission, type AclTarget, type AclFilter } from "../types";
5
+ export type DescribeAclsRequest = Parameters<typeof createRequest>;
6
+ export interface DescribeAclsResponseResource extends AclTarget {
7
+ acls: AclPermission[];
8
+ }
9
+ export interface DescribeAclsResponse {
10
+ throttleTimeMs: number;
11
+ errorCode: number;
12
+ errorMessage: NullableString;
13
+ resources: DescribeAclsResponseResource[];
14
+ }
15
+ export declare function createRequest(filter: AclFilter): Writer;
16
+ export declare function parseResponse(_correlationId: number, apiKey: number, apiVersion: number, reader: Reader): DescribeAclsResponse;
17
+ export declare const api: import("../definitions").API<[filter: AclFilter], DescribeAclsResponse>;