@confluentinc/schemaregistry
Version:
Node.js client for Confluent Schema Registry
361 lines (360 loc) • 14.9 kB
TypeScript
import { Client, Rule, RuleMode, RulePhase, RuleSet, SchemaInfo, SchemaMetadata } from "../schemaregistry-client";
import { RuleRegistry } from "./rule-registry";
import { ClientConfig } from "../rest-service";
import { IHeaders } from "../../types/kafkajs";
export declare enum SerdeType {
KEY = "KEY",
VALUE = "VALUE"
}
export declare const MAGIC_BYTE: Buffer<ArrayBuffer>;
export declare const MAGIC_BYTE_V0: Buffer<ArrayBuffer>;
export declare const MAGIC_BYTE_V1: Buffer<ArrayBuffer>;
export declare const KEY_SCHEMA_ID_HEADER = "__key_schema_id";
export declare const VALUE_SCHEMA_ID_HEADER = "__value_schema_id";
export declare class SchemaId {
schemaType: string;
id?: number;
guid?: string;
messageIndexes?: number[];
constructor(schemaType: string, id?: number, guid?: string, messageIndexes?: number[]);
fromBytes(payload: Buffer): number;
stringifyUuid(arr: Uint8Array, offset?: number): string;
idToBytes(): Buffer;
guidToBytes(): Buffer;
parseUuid(uuid: string): Uint8Array;
readMessageIndexes(payload: Buffer): [number, number[]];
writeMessageIndexes(msgIndexes: number[]): Buffer;
}
/**
* SerializationError represents a serialization error
*/
export declare class SerializationError extends Error {
constructor(message?: string);
}
export declare enum SubjectNameStrategyType {
NONE = "NONE",
TOPIC = "TOPIC",
RECORD = "RECORD",
TOPIC_RECORD = "TOPIC_RECORD",
ASSOCIATED = "ASSOCIATED"
}
export interface SerdeConfig {
useLatestVersion?: boolean;
useLatestWithMetadata?: {
[key: string]: string;
};
cacheCapacity?: number;
cacheLatestTtlSecs?: number;
ruleConfig?: {
[key: string]: string;
};
subjectNameStrategyType?: SubjectNameStrategyType;
subjectNameStrategyConfig?: {
[key: string]: string;
};
subjectNameStrategy?: SubjectNameStrategyFunc;
}
export type RefResolver = (client: Client, info: SchemaInfo) => Promise<Map<string, string>>;
/**
* Serde represents a serializer/deserializer
*/
export declare abstract class Serde {
client: Client;
serdeType: SerdeType;
conf: SerdeConfig;
fieldTransformer: FieldTransformer | null;
ruleRegistry: RuleRegistry;
protected constructor(client: Client, serdeType: SerdeType, conf: SerdeConfig, ruleRegistry?: RuleRegistry);
abstract config(): SerdeConfig;
close(): void;
subjectName(topic: string, info?: SchemaInfo): Promise<string>;
/**
* Configures the subject name strategy based on the strategy type.
* Defaults to ASSOCIATED (with TOPIC fallback) when no type is specified.
* @param strategyType - the type of subject name strategy
* @param config - configuration options for the strategy
* @param getRecordName - function to extract record name from schema
*/
configureSubjectNameStrategy(strategyType: SubjectNameStrategyType | null | undefined, config: {
[key: string]: string;
}, getRecordName: RecordNameFunc): void;
resolveReferences(client: Client, schema: SchemaInfo, deps: Map<string, string>, format?: string): Promise<void>;
executeRules(subject: string, topic: string, ruleMode: RuleMode, source: SchemaInfo | null, target: SchemaInfo | null, msg: any, inlineTags: Map<string, Set<string>> | null): Promise<any>;
executeRulesWithPhase(subject: string, topic: string, rulePhase: RulePhase, ruleMode: RuleMode, source: SchemaInfo | null, target: SchemaInfo | null, msg: any, inlineTags: Map<string, Set<string>> | null): Promise<any>;
getOnSuccess(rule: Rule): string | undefined;
getOnFailure(rule: Rule): string | undefined;
isDisabled(ctx: RuleContext, rule: Rule): boolean | undefined;
runAction(ctx: RuleContext, ruleMode: RuleMode, rule: Rule, action: string | undefined, msg: any, err: Error | null, defaultAction: string): Promise<void>;
getRuleActionName(rule: Rule, ruleMode: RuleMode, actionName: string | undefined): string | null;
getRuleAction(ctx: RuleContext, actionName: string): RuleAction | undefined;
}
/**
* SerializerConfig represents a serializer configuration
*/
export interface SerializerConfig extends SerdeConfig {
autoRegisterSchemas?: boolean;
useSchemaId?: number;
normalizeSchemas?: boolean;
schemaIdSerializer?: SchemaIdSerializerFunc;
}
/**
* Serializer represents a serializer
*/
export declare abstract class Serializer extends Serde {
protected constructor(client: Client, serdeType: SerdeType, conf: SerializerConfig, ruleRegistry?: RuleRegistry);
config(): SerializerConfig;
/**
* Serialize serializes a message
* @param topic - the topic
* @param msg - the message
* @param headers - optional headers
*/
abstract serialize(topic: string, msg: any, headers?: IHeaders): Promise<Buffer>;
getSchemaId(schemaType: string, topic: string, msg: any, info?: SchemaInfo, format?: string): Promise<[SchemaId, SchemaInfo]>;
serializeSchemaId(topic: string, payload: Buffer, schemaId: SchemaId, headers?: IHeaders): Buffer;
}
/**
* DeserializerConfig represents a deserializer configuration
*/
export interface DeserializerConfig extends SerdeConfig {
schemaIdDeserializer?: SchemaIdDeserializerFunc;
}
/**
* Migration represents a migration
*/
export interface Migration {
ruleMode: RuleMode;
source: SchemaMetadata | null;
target: SchemaMetadata | null;
}
/**
* Deserializer represents a deserializer
*/
export declare abstract class Deserializer extends Serde {
protected constructor(client: Client, serdeType: SerdeType, conf: DeserializerConfig, ruleRegistry?: RuleRegistry);
config(): DeserializerConfig;
/**
* Deserialize deserializes a message
* @param topic - the topic
* @param payload - the payload
* @param headers - optional headers
*/
abstract deserialize(topic: string, payload: Buffer, headers?: IHeaders): Promise<any>;
deserializeSchemaId(topic: string, payload: Buffer, schemaId: SchemaId, headers?: IHeaders): number;
getWriterSchema(topic: string, payload: Buffer, schemaId: SchemaId, headers?: IHeaders, format?: string): Promise<[SchemaInfo, number]>;
getReaderSchema(subject: string, format?: string): Promise<SchemaMetadata | null>;
hasRules(ruleSet: RuleSet, phase: RulePhase, mode: RuleMode): boolean;
checkRules(rules: Rule[] | undefined, filter: (ruleMode: RuleMode) => boolean): boolean;
getMigrations(subject: string, sourceInfo: SchemaInfo, target: SchemaMetadata, format?: string): Promise<Migration[]>;
getSchemasBetween(subject: string, first: SchemaMetadata, last: SchemaMetadata, format?: string): Promise<SchemaMetadata[]>;
executeMigrations(migrations: Migration[], subject: string, topic: string, msg: any): Promise<any>;
}
/**
* SubjectNameStrategyFunc determines the subject from the given parameters
*/
export type SubjectNameStrategyFunc = (topic: string, serdeType: SerdeType, schema?: SchemaInfo) => string | Promise<string>;
/**
* RecordNameFunc extracts the record name from a schema
*/
export type RecordNameFunc = (schema?: SchemaInfo) => Promise<string>;
/**
* RecordNameStrategy creates a subject name from the record name.
* @param getRecordName - function to extract record name from schema
*/
export declare const RecordNameStrategy: (getRecordName: RecordNameFunc) => SubjectNameStrategyFunc;
/**
* TopicRecordNameStrategy creates a subject name from the topic and record name.
* @param getRecordName - function to extract record name from schema
*/
export declare const TopicRecordNameStrategy: (getRecordName: RecordNameFunc) => SubjectNameStrategyFunc;
/**
* Converts a SubjectNameStrategyType to a SubjectNameStrategyFunc.
* This helper centralizes strategy resolution logic.
*
* @param type - the strategy type
* @param getRecordName - optional function to extract record name from schema (required for RECORD/TOPIC_RECORD)
* @returns the corresponding strategy function, or null for NONE
*/
export declare function strategyFromType(type: SubjectNameStrategyType, getRecordName?: RecordNameFunc): SubjectNameStrategyFunc | null;
/**
* Configuration key for the Kafka cluster ID.
* If set, this value will be passed as the resource namespace to schema registry.
*/
export declare const KAFKA_CLUSTER_ID = "subject.name.strategy.kafka.cluster.id";
/**
* Wildcard value for namespace when kafka cluster ID is not configured.
*/
export declare const NAMESPACE_WILDCARD = "-";
/**
* Configuration key for the fallback subject name strategy type.
* Valid values: TOPIC, RECORD, TOPIC_RECORD, NONE.
* Defaults to TOPIC if not specified.
*/
export declare const FALLBACK_TYPE = "subject.name.strategy.fallback.type";
/**
* AssociatedNameStrategy returns a strategy that retrieves the associated subject name from schema registry.
* The topic is passed as the resource name to schema registry. If there is a configuration property
* named "subject.name.strategy.kafka.cluster.id", then its value will be passed as the resource namespace;
* otherwise the value "-" will be passed as the resource namespace.
* If more than one subject is returned from the query, an exception will be thrown.
* If no subjects are returned from the query, then the behavior will fall back to TopicNameStrategy,
* unless the configuration property "subject.name.strategy.fallback.type" is set to "RECORD",
* "TOPIC_RECORD", or "NONE".
*
* @param client - the schema registry client
* @param config - configuration options
* @param getRecordName - optional function to extract record name from schema (required for RECORD/TOPIC_RECORD fallback)
*/
export declare const AssociatedNameStrategy: (client: Client, config: {
[key: string]: string;
}, getRecordName?: RecordNameFunc) => SubjectNameStrategyFunc;
/**
* TopicNameStrategy creates a subject name by appending -[key|value] to the topic name.
* @param topic - the topic name
* @param serdeType - the serde type
*/
export declare const TopicNameStrategy: SubjectNameStrategyFunc;
/**
* SchemaIdSerializerFunc serializes a schema ID/GUID
*/
export type SchemaIdSerializerFunc = (topic: string, serdeType: SerdeType, payload: Buffer, schemaId: SchemaId, headers?: IHeaders) => Buffer;
export declare const HeaderSchemaIdSerializer: SchemaIdSerializerFunc;
export declare const PrefixSchemaIdSerializer: SchemaIdSerializerFunc;
/**
* SchemaIdDeserializerFunc serializes a schema ID/GUID
*/
export type SchemaIdDeserializerFunc = (topic: string, serdeType: SerdeType, payload: Buffer, schemaId: SchemaId, headers?: IHeaders) => number;
export declare const DualSchemaIdDeserializer: SchemaIdDeserializerFunc;
export declare const PrefixSchemaIdDeserializer: SchemaIdDeserializerFunc;
/**
* RuleContext represents a rule context
*/
export declare class RuleContext {
enabledEnv: string | undefined;
source: SchemaInfo | null;
target: SchemaInfo;
subject: string;
topic: string;
isKey: boolean;
ruleMode: RuleMode;
rule: Rule;
index: number;
rules: Rule[];
inlineTags: Map<string, Set<string>> | null;
fieldTransformer: FieldTransformer;
private fieldContexts;
constructor(enabledEnv: string | undefined, source: SchemaInfo | null, target: SchemaInfo, subject: string, topic: string, isKey: boolean, ruleMode: RuleMode, rule: Rule, index: number, rules: Rule[], inlineTags: Map<string, Set<string>> | null, fieldTransformer: FieldTransformer);
getParameter(name: string): string | null;
getInlineTags(name: string): Set<string>;
currentField(): FieldContext | null;
enterField(containingMessage: any, fullName: string, name: string, fieldType: FieldType, tags: Set<string> | null): FieldContext;
getTags(fullName: string): Set<string>;
leaveField(): void;
}
export interface RuleBase {
configure(clientConfig: ClientConfig, config: Map<string, string>): void;
type(): string;
close(): void;
}
/**
* RuleExecutor represents a rule executor
*/
export interface RuleExecutor extends RuleBase {
transform(ctx: RuleContext, msg: any): Promise<any>;
}
/**
* FieldTransformer represents a field transformer
*/
export type FieldTransformer = (ctx: RuleContext, fieldTransform: FieldTransform, msg: any) => any;
/**
* FieldTransform represents a field transform
*/
export interface FieldTransform {
transform(ctx: RuleContext, fieldCtx: FieldContext, fieldValue: any): Promise<any>;
}
/**
* FieldRuleExecutor represents a field rule executor
*/
export declare abstract class FieldRuleExecutor implements RuleExecutor {
config: Map<string, string> | null;
abstract configure(clientConfig: ClientConfig, config: Map<string, string>): void;
abstract type(): string;
abstract newTransform(ctx: RuleContext): FieldTransform;
transform(ctx: RuleContext, msg: any): Promise<any>;
abstract close(): void;
}
/**
* FieldContext represents a field context
*/
export declare class FieldContext {
containingMessage: any;
fullName: string;
name: string;
type: FieldType;
tags: Set<string>;
constructor(containingMessage: any, fullName: string, name: string, fieldType: FieldType, tags: Set<string>);
isPrimitive(): boolean;
typeName(): string;
}
export declare enum FieldType {
RECORD = "RECORD",
ENUM = "ENUM",
ARRAY = "ARRAY",
MAP = "MAP",
COMBINED = "COMBINED",
FIXED = "FIXED",
STRING = "STRING",
BYTES = "BYTES",
INT = "INT",
LONG = "LONG",
FLOAT = "FLOAT",
DOUBLE = "DOUBLE",
BOOLEAN = "BOOLEAN",
NULL = "NULL"
}
/**
* RuleAction represents a rule action
*/
export interface RuleAction extends RuleBase {
run(ctx: RuleContext, msg: any, err: Error | null): Promise<void>;
}
/**
* ErrorAction represents an error action
*/
export declare class ErrorAction implements RuleAction {
configure(clientConfig: ClientConfig, config: Map<string, string>): void;
type(): string;
run(ctx: RuleContext, msg: any, err: Error): Promise<void>;
close(): void;
}
/**
* NoneAction represents a no-op action
*/
export declare class NoneAction implements RuleAction {
configure(clientConfig: ClientConfig, config: Map<string, string>): void;
type(): string;
run(ctx: RuleContext, msg: any, err: Error): Promise<void>;
close(): void;
}
/**
* RuleError represents a rule error
*/
export declare class RuleError extends Error {
/**
* Creates a new rule error.
* @param message - The error message.
*/
constructor(message?: string);
}
/**
* RuleConditionError represents a rule condition error
*/
export declare class RuleConditionError extends RuleError {
rule: Rule;
/**
* Creates a new rule condition error.
* @param rule - The rule.
*/
constructor(rule: Rule);
static error(rule: Rule): string;
}