/** * Factory for creating identity manager instances */ import { LoggerComponent } from 'ior:gitea:gitea.metatrom.net:universal-components/logger@1.0.0'; import { AsyncStorageAdapter } from './implementations/AsyncStorageAdapter'; import { IdentityManager } from './implementations/IdentityManager'; import type { IdentityConfig, IIdentityFactory, IIdentityManager, IIdentityStorage, } from './interfaces/IIdentity'; // Platform interface for dependency injection interface IPlatform { OS: string; } export class IdentityFactory implements IIdentityFactory { private static instance?: IdentityFactory; private identityManager?: IIdentityManager; private storage?: IIdentityStorage; private logger = new LoggerComponent('IdentityFactory'); private platform?: IPlatform; private asyncStorage?: any; private constructor(platform?: IPlatform, asyncStorage?: any) { this.platform = platform; this.asyncStorage = asyncStorage; } static getInstance(platform?: IPlatform, asyncStorage?: any): IdentityFactory { if (!IdentityFactory.instance) { IdentityFactory.instance = new IdentityFactory(platform, asyncStorage); } return IdentityFactory.instance; } create(config?: IdentityConfig): IIdentityManager { // Use singleton pattern for identity manager if (!this.identityManager) { const storage = this.getStorage(); // Enhanced config with platform-specific device name provider const enhancedConfig: IdentityConfig = { ...config, deviceNameProvider: config?.deviceNameProvider || this.getDeviceNameProvider(), }; this.identityManager = new IdentityManager(storage, enhancedConfig); } return this.identityManager; } private getStorage(): IIdentityStorage { if (!this.storage) { if (!this.asyncStorage) { throw new Error('AsyncStorage not provided. Please provide AsyncStorage when creating the factory.'); } // Use AsyncStorage for React Native this.storage = new AsyncStorageAdapter(this.asyncStorage); } return this.storage; } private getDeviceNameProvider(): () => Promise { return async () => { try { // Try to use react-native-device-info if available const DeviceInfo = require('react-native-device-info').default; if (DeviceInfo?.getDeviceName) { const name = await DeviceInfo.getDeviceName(); return name || this.getFallbackDeviceName(); } } catch (_error) { // Module not available, use fallback this.logger.debug('react-native-device-info not available, using fallback device name'); } return this.getFallbackDeviceName(); }; } private getFallbackDeviceName(): string { const platform = this.platform?.OS || 'unknown'; const timestamp = Date.now().toString(36).substring(-4); switch (platform) { case 'ios': return `iPhone-${timestamp}`; case 'android': return `Android-${timestamp}`; default: return `Device-${timestamp}`; } } /** * Reset the singleton instance (useful for testing) */ static reset(): void { if (IdentityFactory.instance?.identityManager) { IdentityFactory.instance.identityManager = undefined; } IdentityFactory.instance = undefined; } } // Export singleton instance creator with dependency injection export const createIdentityManager = ( config?: IdentityConfig, platform?: IPlatform, asyncStorage?: any ): IIdentityManager => { return IdentityFactory.getInstance(platform, asyncStorage).create(config); };