123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.AvroSchemaValidator = void 0;
- class AvroSchemaValidator {
- constructor() {
- this.namedSchemas = new Map();
- }
- validateSchema(schema) {
- this.namedSchemas.clear();
- return this.validateSchemaInternal(schema);
- }
- validateValue(value, schema) {
- this.namedSchemas.clear();
- this.validateSchemaInternal(schema);
- return this.validateValueAgainstSchema(value, schema);
- }
- validateSchemaInternal(schema) {
- if (typeof schema === 'string') {
- return this.validateStringSchema(schema);
- }
- if (Array.isArray(schema)) {
- return this.validateUnionSchema(schema);
- }
- if (typeof schema === 'object' && schema !== null) {
- switch (schema.type) {
- case 'null':
- return this.validateNullSchema(schema);
- case 'boolean':
- return this.validateBooleanSchema(schema);
- case 'int':
- return this.validateIntSchema(schema);
- case 'long':
- return this.validateLongSchema(schema);
- case 'float':
- return this.validateFloatSchema(schema);
- case 'double':
- return this.validateDoubleSchema(schema);
- case 'bytes':
- return this.validateBytesSchema(schema);
- case 'string':
- return this.validateStringTypeSchema(schema);
- case 'record':
- return this.validateRecordSchema(schema);
- case 'enum':
- return this.validateEnumSchema(schema);
- case 'array':
- return this.validateArraySchema(schema);
- case 'map':
- return this.validateMapSchema(schema);
- case 'fixed':
- return this.validateFixedSchema(schema);
- default:
- return false;
- }
- }
- return false;
- }
- validateStringSchema(schema) {
- const primitiveTypes = ['null', 'boolean', 'int', 'long', 'float', 'double', 'bytes', 'string'];
- return primitiveTypes.includes(schema) || this.namedSchemas.has(schema);
- }
- validateUnionSchema(schema) {
- if (schema.length === 0)
- return false;
- const typeSet = new Set();
- for (const subSchema of schema) {
- if (!this.validateSchemaInternal(subSchema))
- return false;
- const typeName = this.getSchemaTypeName(subSchema);
- if (typeSet.has(typeName))
- return false;
- typeSet.add(typeName);
- }
- return true;
- }
- validateNullSchema(schema) {
- return schema.type === 'null';
- }
- validateBooleanSchema(schema) {
- return schema.type === 'boolean';
- }
- validateIntSchema(schema) {
- return schema.type === 'int';
- }
- validateLongSchema(schema) {
- return schema.type === 'long';
- }
- validateFloatSchema(schema) {
- return schema.type === 'float';
- }
- validateDoubleSchema(schema) {
- return schema.type === 'double';
- }
- validateBytesSchema(schema) {
- return schema.type === 'bytes';
- }
- validateStringTypeSchema(schema) {
- return schema.type === 'string';
- }
- validateRecordSchema(schema) {
- if (schema.type !== 'record' || !schema.name || !Array.isArray(schema.fields))
- return false;
- const fullName = this.getFullName(schema.name, schema.namespace);
- if (this.namedSchemas.has(fullName))
- return false;
- this.namedSchemas.set(fullName, schema);
- const fieldNames = new Set();
- for (const field of schema.fields) {
- if (!this.validateRecordField(field))
- return false;
- if (fieldNames.has(field.name))
- return false;
- fieldNames.add(field.name);
- }
- return true;
- }
- validateRecordField(field) {
- return typeof field.name === 'string' && field.name.length > 0 && this.validateSchemaInternal(field.type);
- }
- validateEnumSchema(schema) {
- if (schema.type !== 'enum' || !schema.name || !Array.isArray(schema.symbols))
- return false;
- const fullName = this.getFullName(schema.name, schema.namespace);
- if (this.namedSchemas.has(fullName))
- return false;
- this.namedSchemas.set(fullName, schema);
- if (schema.symbols.length === 0)
- return false;
- const symbolSet = new Set();
- for (const symbol of schema.symbols) {
- if (typeof symbol !== 'string' || symbolSet.has(symbol))
- return false;
- symbolSet.add(symbol);
- }
- if (schema.default !== undefined && !schema.symbols.includes(schema.default))
- return false;
- return true;
- }
- validateArraySchema(schema) {
- return schema.type === 'array' && this.validateSchemaInternal(schema.items);
- }
- validateMapSchema(schema) {
- return schema.type === 'map' && this.validateSchemaInternal(schema.values);
- }
- validateFixedSchema(schema) {
- if (schema.type !== 'fixed' || !schema.name || typeof schema.size !== 'number')
- return false;
- if (schema.size < 0)
- return false;
- const fullName = this.getFullName(schema.name, schema.namespace);
- if (this.namedSchemas.has(fullName))
- return false;
- this.namedSchemas.set(fullName, schema);
- return true;
- }
- validateValueAgainstSchema(value, schema) {
- if (typeof schema === 'string') {
- return this.validateValueAgainstStringSchema(value, schema);
- }
- if (Array.isArray(schema)) {
- return schema.some((subSchema) => this.validateValueAgainstSchema(value, subSchema));
- }
- if (typeof schema === 'object' && schema !== null) {
- switch (schema.type) {
- case 'null':
- return value === null;
- case 'boolean':
- return typeof value === 'boolean';
- case 'int':
- return typeof value === 'number' && Number.isInteger(value) && value >= -2147483648 && value <= 2147483647;
- case 'long':
- return (typeof value === 'number' && Number.isInteger(value)) || typeof value === 'bigint';
- case 'float':
- case 'double':
- return typeof value === 'number';
- case 'bytes':
- return value instanceof Uint8Array;
- case 'string':
- return typeof value === 'string';
- case 'record':
- return this.validateValueAgainstRecord(value, schema);
- case 'enum':
- return this.validateValueAgainstEnum(value, schema);
- case 'array':
- return this.validateValueAgainstArray(value, schema);
- case 'map':
- return this.validateValueAgainstMap(value, schema);
- case 'fixed':
- return this.validateValueAgainstFixed(value, schema);
- default:
- return false;
- }
- }
- return false;
- }
- validateValueAgainstStringSchema(value, schema) {
- switch (schema) {
- case 'null':
- return value === null;
- case 'boolean':
- return typeof value === 'boolean';
- case 'int':
- return typeof value === 'number' && Number.isInteger(value) && value >= -2147483648 && value <= 2147483647;
- case 'long':
- return (typeof value === 'number' && Number.isInteger(value)) || typeof value === 'bigint';
- case 'float':
- case 'double':
- return typeof value === 'number';
- case 'bytes':
- return value instanceof Uint8Array;
- case 'string':
- return typeof value === 'string';
- default:
- const namedSchema = this.namedSchemas.get(schema);
- return namedSchema ? this.validateValueAgainstSchema(value, namedSchema) : false;
- }
- }
- validateValueAgainstRecord(value, schema) {
- if (typeof value !== 'object' || value === null)
- return false;
- const obj = value;
- for (const field of schema.fields) {
- const fieldValue = obj[field.name];
- if (fieldValue === undefined && field.default === undefined)
- return false;
- if (fieldValue !== undefined && !this.validateValueAgainstSchema(fieldValue, field.type))
- return false;
- }
- return true;
- }
- validateValueAgainstEnum(value, schema) {
- return typeof value === 'string' && schema.symbols.includes(value);
- }
- validateValueAgainstArray(value, schema) {
- if (!Array.isArray(value))
- return false;
- return value.every((item) => this.validateValueAgainstSchema(item, schema.items));
- }
- validateValueAgainstMap(value, schema) {
- if (typeof value !== 'object' || value === null)
- return false;
- const obj = value;
- return Object.values(obj).every((val) => this.validateValueAgainstSchema(val, schema.values));
- }
- validateValueAgainstFixed(value, schema) {
- return value instanceof Uint8Array && value.length === schema.size;
- }
- getSchemaTypeName(schema) {
- if (typeof schema === 'string')
- return schema;
- if (Array.isArray(schema))
- return 'union';
- return schema.type;
- }
- getFullName(name, namespace) {
- return namespace ? `${namespace}.${name}` : name;
- }
- }
- exports.AvroSchemaValidator = AvroSchemaValidator;
- //# sourceMappingURL=AvroSchemaValidator.js.map
|