UNPKG

@wearesage/schema

Version:

A flexible schema definition and validation system for TypeScript with multi-database support

148 lines (126 loc) 4.14 kB
import { EntityOptions, PropertyOptions, RelationshipOptions } from "./types"; /** * MetadataRegistry is responsible for storing and retrieving schema metadata * about entities, properties, and relationships. * * This class is designed to be instantiated directly rather than used as a singleton, * allowing for better testing and composition. It's typically used with a SchemaBuilder * to register metadata from decorated classes. */ export class MetadataRegistry { private entities = new Map<Function, EntityOptions>(); private properties = new Map<Function, Map<string, PropertyOptions>>(); private ids = new Map<Function, Set<string>>(); private relationships = new Map<Function, Map<string, RelationshipOptions>>(); constructor() {} // Entity registration registerEntity(target: Function, options: EntityOptions = {}): void { this.entities.set(target, options); } // Property registration registerProperty( target: Function, propertyKey: string, options: PropertyOptions = {} ): void { if (!this.properties.has(target)) { this.properties.set(target, new Map()); } this.properties.get(target)!.set(propertyKey, options); } // ID registration registerIdProperty(target: Function, propertyKey: string): void { if (!this.ids.has(target)) { this.ids.set(target, new Set()); } this.ids.get(target)!.add(propertyKey); } // Relationship registration registerRelationship( target: Function, propertyKey: string, options: RelationshipOptions ): void { if (!this.relationships.has(target)) { this.relationships.set(target, new Map()); } this.relationships.get(target)!.set(propertyKey, options); } // Getters getEntityMetadata(target: Function): EntityOptions | undefined { return this.entities.get(target); } getPropertyMetadata( target: Function, propertyKey: string ): PropertyOptions | undefined { return this.properties.get(target)?.get(propertyKey); } getAllProperties(target: Function): Map<string, PropertyOptions> | undefined { return this.properties.get(target); } getIdProperties(target: Function): Set<string> | undefined { return this.ids.get(target); } getRelationshipMetadata( target: Function, propertyKey: string ): RelationshipOptions | undefined { return this.relationships.get(target)?.get(propertyKey); } getAllRelationships( target: Function ): Map<string, RelationshipOptions> | undefined { return this.relationships.get(target); } getAllEntities(): Map<Function, EntityOptions> { return this.entities; } /** * Create a clone of this registry * Useful for creating modified copies without changing the original */ clone(): MetadataRegistry { const cloned = new MetadataRegistry(); // Clone entities this.entities.forEach((options, target) => { cloned.entities.set(target, { ...options }); }); // Clone properties this.properties.forEach((propertyMap, target) => { const clonedPropertyMap = new Map<string, PropertyOptions>(); propertyMap.forEach((options, key) => { clonedPropertyMap.set(key, { ...options }); }); cloned.properties.set(target, clonedPropertyMap); }); // Clone IDs this.ids.forEach((idSet, target) => { cloned.ids.set(target, new Set<string>(idSet)); }); // Clone relationships this.relationships.forEach((relationshipMap, target) => { const clonedRelationshipMap = new Map<string, RelationshipOptions>(); relationshipMap.forEach((options, key) => { clonedRelationshipMap.set(key, { ...options }); }); cloned.relationships.set(target, clonedRelationshipMap); }); return cloned; } /** * Get all registered entity types */ getRegisteredEntities(): Type<any>[] { return Array.from(this.entities.keys()); } /** * Clear all metadata from this registry */ clear(): void { this.entities.clear(); this.properties.clear(); this.ids.clear(); this.relationships.clear(); } }