import { TSinjex } from "../classes/mod.ts"; import { InitializationError } from "../interfaces/mod.ts"; import { Identifier, InitDelegate } from "../types/mod.ts"; export function Inject( identifier: Identifier, init?: InitDelegate, isNecessary = true, ): ( target: undefined, context: ClassFieldDecoratorContext, ) => (initialValue: FieldType) => FieldType { return function ( _target: undefined, context: ClassFieldDecoratorContext, ): (initialValue: FieldType) => FieldType { if (context.kind !== "field") { throw new Error("Inject decorator can only be used on fields."); } const initializer = () => { let instance: DependencyType | FieldType | undefined; const dependency: DependencyType | undefined = TSinjex.getInstance() .resolve(identifier, isNecessary); if (init == null || dependency == null) { instance = dependency; } else { try { instance = init(dependency); } catch (error) { if (isNecessary) { throw new InitializationError( identifier, error instanceof Error ? error : new Error(String(error)), ); } else { console.warn( `Error initializing not necessary dependency ${identifier.toString()}: ${error}`, ); instance = undefined; } } } return instance as FieldType; }; return function (_initialValue: FieldType): FieldType { return initializer(); }; }; }