UNPKG

@thinkeloquent/core-configure

Version:

Entity configuration management with deep merging, validation, and entity definitions

342 lines (266 loc) 7.01 kB
# @thinkeloquent/core-configure Entity configuration management with deep merging, validation, and entity definitions for the MTA Framework v2.0. ## Features - **Layered Configuration**: Support for multiple configuration sources with priority-based merging - **Merge Strategies**: Three strategies (override, merge, extend) for flexible configuration composition - **Entity Definitions**: Registry for managing entity metadata and lifecycle - **Schema Validation**: Zod-based runtime validation for all configurations - **Type Safety**: Full TypeScript support with strict mode - **Caching**: Optional configuration caching for performance - **Result Pattern**: Functional error handling with `Result<T,E>` ## Installation ```bash pnpm install @thinkeloquent/core-configure ``` ## Quick Start ```typescript import { EntityConfigurationManager, ConfigSource, MergeStrategy, } from '@thinkeloquent/core-configure'; // Create manager const manager = new EntityConfigurationManager({ defaultMergeStrategy: MergeStrategy.MERGE, enableValidation: true, enableCaching: true, }); // Set default configuration manager.setConfig('tenant-1', 'tenant', { plugins: ['auth', 'logging'], settings: { theme: 'dark' } }, ConfigSource.DEFAULT); // Override with runtime configuration manager.setConfig('tenant-1', 'tenant', { settings: { apiKey: 'secret-key' } }, ConfigSource.RUNTIME); // Get merged configuration const result = manager.getConfig('tenant-1', 'tenant'); if (result.isOk()) { console.log(result.value); // { // plugins: ['auth', 'logging'], // settings: { theme: 'dark', apiKey: 'secret-key' } // } } ``` ## Configuration Sources Configurations are layered with the following priority (highest to lowest): 1. **RUNTIME** - Runtime overrides (priority 4) 2. **CONTROL_PLANE** - Control plane configuration (priority 3) 3. **FILESYSTEM** - File-based configuration (priority 2) 4. **DEFAULT** - Default values (priority 1) Higher priority sources override lower priority sources during merging. ## Merge Strategies ### OVERRIDE Completely replaces the target configuration with the source. ```typescript const target = { plugins: ['p1'], settings: { a: 1 } }; const source = { plugins: ['p2'], settings: { b: 2 } }; // Result: { plugins: ['p2'], settings: { b: 2 } } ``` ### MERGE Deep merges objects and concatenates arrays. ```typescript const target = { plugins: ['p1'], settings: { a: 1 } }; const source = { plugins: ['p2'], settings: { b: 2 } }; // Result: { plugins: ['p1', 'p2'], settings: { a: 1, b: 2 } } ``` ### EXTEND Adds new keys without replacing existing ones. ```typescript const target = { plugins: ['p1'], settings: { a: 1 } }; const source = { plugins: ['p2'], settings: { a: 999, b: 2 } }; // Result: { plugins: ['p1', 'p2'], settings: { a: 1, b: 2 } } // Note: 'a' keeps its original value ``` ## Entity Definitions Manage entity metadata separately from configuration: ```typescript const registry = manager.getDefinitionRegistry(); // Register entity definition registry.register({ id: 'tenant-acme', type: 'tenant', name: 'Acme Corporation', description: 'Production tenant', enabled: true, metadata: { region: 'us-east-1', tier: 'enterprise', }, }); // Get definition const defResult = registry.get('tenant-acme', 'tenant'); // Update definition registry.update({ id: 'tenant-acme', type: 'tenant', description: 'Updated description', }); // Enable/disable registry.enable('tenant-acme', 'tenant'); registry.disable('tenant-acme', 'tenant'); // Query const allTenants = registry.getByType('tenant'); const enabledOnly = registry.getEnabled(); ``` ## API Reference ### EntityConfigurationManager #### Constructor ```typescript new EntityConfigurationManager(options?: Partial<ConfigurationManagerOptions>) ``` Options: - `defaultMergeStrategy`: Default merge strategy (default: `MERGE`) - `enableValidation`: Enable Zod validation (default: `true`) - `enableCaching`: Enable configuration caching (default: `true`) - `persistenceEnabled`: Enable filesystem persistence (default: `false`) - `persistencePath`: Path for persistence (optional) #### Methods **setConfig** ```typescript setConfig( entityId: string, entityType: string, config: EntityConfig, source?: ConfigSource ): Result<void, Error> ``` **getConfig** ```typescript getConfig(entityId: string, entityType: string): Result<EntityConfig, Error> ``` **getConfigBySource** ```typescript getConfigBySource( entityId: string, entityType: string, source: ConfigSource ): Result<EntityConfig, Error> ``` **mergeConfig** ```typescript mergeConfig( entityId: string, entityType: string, additionalConfig: EntityConfig, options?: MergeOptions ): Result<EntityConfig, Error> ``` **removeConfig** ```typescript removeConfig( entityId: string, entityType: string, source?: ConfigSource ): Result<void, Error> ``` **hasConfig** ```typescript hasConfig(entityId: string, entityType: string): boolean ``` **getMetadata** ```typescript getMetadata(entityId: string, entityType: string): Result<ConfigMetadata, Error> ``` **validateConfig** ```typescript validateConfig(config: EntityConfig): ValidationResult ``` **clearCache** ```typescript clearCache(): void ``` **clear** ```typescript clear(): void ``` ### EntityDefinitionRegistry **register** ```typescript register(definition: EntityDefinition): Result<void, Error> ``` **get** ```typescript get(id: string, type: string): Result<EntityDefinition, Error> ``` **update** ```typescript update(definition: Partial<EntityDefinition> & { id: string; type: string }): Result<void, Error> ``` **remove** ```typescript remove(id: string, type: string): Result<void, Error> ``` **getAll** ```typescript getAll(): EntityDefinition[] ``` **getByType** ```typescript getByType(type: string): EntityDefinition[] ``` **getEnabled** ```typescript getEnabled(): EntityDefinition[] ``` **enable / disable** ```typescript enable(id: string, type: string): Result<void, Error> disable(id: string, type: string): Result<void, Error> ``` ## TypeScript Types ```typescript interface EntityConfig { plugins?: string[]; routes?: string[]; services?: string[]; schemas?: string[]; settings?: Record<string, unknown>; security?: { allowedOrigins?: string[]; rateLimit?: { max?: number; timeWindow?: number; }; jwtSecret?: string; }; database?: { url?: string; pool?: { min?: number; max?: number; }; }; } interface EntityDefinition { id: string; type: string; name: string; description?: string; enabled: boolean; metadata?: Record<string, unknown>; createdAt?: Date; updatedAt?: Date; } ``` ## Testing ```bash # Run tests pnpm test # Watch mode pnpm run test:watch # Coverage pnpm run test:coverage ``` ## Coverage This module maintains >95% code coverage: - Lines: >95% - Functions: >95% - Branches: >95% - Statements: >95% ## License MIT ## Author ThinkEloquent