Warning, /firebird/firebird-ng/src/app/services/config.service.ts is written in an unsupported language. File is not indexed.
0001 import { Injectable } from '@angular/core';
0002 import {ConfigProperty} from '../utils/config-property';
0003
0004 export interface ConfigSnapshot {
0005 configs: {
0006 [key: string]: {
0007 value: any;
0008 timestamp?: number;
0009 };
0010 };
0011 version?: string;
0012 exportedAt?: string;
0013 }
0014
0015 @Injectable({
0016 providedIn: 'root',
0017 })
0018 export class ConfigService {
0019
0020 public configsByName: Map<string, ConfigProperty<any>> = new Map();
0021
0022 // Generic getter with type safety
0023
0024 public getConfig<T>(key: string): ConfigProperty<T> | undefined {
0025 return this.configsByName.get(key) as ConfigProperty<T> | undefined;
0026 }
0027
0028 public getConfigOrCreate<T>(key: string, value: T): ConfigProperty<T> {
0029 let property = this.configsByName.get(key);
0030 if (!property) {
0031 property = this.createConfig(key, value);
0032 }
0033 return property as ConfigProperty<T>;
0034 }
0035
0036 // Generic getter that throws if property doesn't exist
0037 public getConfigOrThrow<T>(key: string): ConfigProperty<T> {
0038 const property = this.configsByName.get(key);
0039 if (!property) {
0040 throw new Error(`Property '${key}' not found`);
0041 }
0042 return property as ConfigProperty<T>;
0043 }
0044
0045 // Register a property
0046 public addConfig<T>(property: ConfigProperty<T>): ConfigProperty<T> {
0047 this.configsByName.set(property.key, property);
0048 return property;
0049 }
0050
0051 // Register a property
0052 public createConfig<T>(key: string, value: T): ConfigProperty<T> {
0053 const config = new ConfigProperty(key, value);
0054 this.addConfig(config);
0055 return config;
0056 }
0057
0058 /**
0059 * Loads default values for all registered configs
0060 */
0061 public loadDefaults(): void {
0062 this.configsByName.forEach((config) => {
0063 config.setDefault();
0064 });
0065 }
0066
0067 /**
0068 * Loads default values for configs whose keys start with the specified prefix
0069 * @param prefix The prefix to filter config keys by (e.g., "ui" for all UI-related configs)
0070 */
0071 public loadDefaultsFor(prefix: string): void {
0072 this.configsByName.forEach((config, key) => {
0073 if (key.startsWith(prefix)) {
0074 config.setDefault();
0075 }
0076 });
0077 }
0078
0079 /**
0080 * Exports all config values to a JSON object
0081 * @returns A snapshot of all current config values with metadata
0082 */
0083 public saveToJson(): ConfigSnapshot {
0084 const configs: ConfigSnapshot['configs'] = {};
0085
0086 this.configsByName.forEach((config, key) => {
0087 configs[key] = {
0088 value: config.value,
0089 // We need to access the timestamp through reflection since it's private
0090 // In a real implementation, you might want to add a public getter for this
0091 timestamp: this.getConfigTimestamp(config)
0092 };
0093 });
0094
0095 return {
0096 configs,
0097 version: '1.0',
0098 exportedAt: new Date().toISOString()
0099 };
0100 }
0101
0102 /**
0103 * Loads config values from a JSON object
0104 * @param snapshot The config snapshot to load
0105 * @param overwriteNewer If true, overwrites even if existing values have newer timestamps
0106 */
0107 public loadFromJson(snapshot: ConfigSnapshot, overwriteNewer: boolean = false): void {
0108 if (!snapshot || !snapshot.configs) {
0109 throw new Error('Invalid config snapshot: missing configs object');
0110 }
0111
0112 Object.entries(snapshot.configs).forEach(([key, configData]) => {
0113 const config = this.configsByName.get(key);
0114 if (config) {
0115 if (overwriteNewer) {
0116 // Force update, bypassing timestamp-based conflict resolution
0117 config.setValue(configData.value, undefined, true);
0118 } else {
0119 // Use the stored timestamp for time-based conflict resolution
0120 config.setValue(configData.value, configData.timestamp || Date.now());
0121 }
0122 } else {
0123 console.warn(`Config key '${key}' not found in registered configs, skipping...`);
0124 }
0125 });
0126 }
0127
0128 /**
0129 * Helper method to get config timestamp
0130 */
0131 private getConfigTimestamp(config: ConfigProperty<any>): number | undefined {
0132 const timestamp = config.getTimestamp();
0133 return timestamp !== null ? timestamp : undefined;
0134 }
0135
0136 constructor() {
0137 }
0138 }