<commit_before>import 'reflect-metadata';
import { CtorT } from './ctor';
import { ProvideMetadata, ProvideMetadataClassSource, ProvideMetadataValueSource, ProvideMetadataCallbackSource } from '../metadata';
import { Logger } from '../services/logger';
import { Server } from '../server/server';
import { clc } from '../util/clc';

export class Injector {
    constructor(private server: Server) {
        this.cache.set(Server, () => this.server);
        this.cache.set(Logger, () => this.logger);
    }
    
    private get logger() {
        return this.server.logger;
    }
    
    private temporaryValue = Symbol.for('recursive-injection');
    private cache: Map<CtorT<any>, any> = new Map<CtorT<any>, any>();
    resolveInjectable<T>(ctorFn: CtorT<T>): T | undefined {
        if (!ctorFn) {
            this.logger.error('injector', 'Attempted to inject a falsey type.');
            return;
        }
        if (this.cache.get(ctorFn) === this.temporaryValue) {
            this.logger.error('injector', `Detected circular dependency. Recursive injection of type ${ctorFn.name || ctorFn}`);
            return;
        }
        if (this.cache.has(ctorFn)) {
            return this.cache.get(ctorFn)();
        }
        this.cache.set(ctorFn, this.temporaryValue);
        
        let inst = this.construct(ctorFn);
        this.cache.set(ctorFn, () => inst);
        return inst;
    }
    private construct<T>(ctorFn: CtorT<T>): T {
        let types: any[] = Reflect.getOwnMetadata('design:paramtypes', ctorFn);
        if (!types) throw new Error(`Could not dependency inject ${ctorFn.name || ctorFn}. No design-time metadata could be reflected.`);<commit_msg>feat(injector): allow user to inject classes with no explicit constructor<commit_after>import 'reflect-metadata';
import { CtorT } from './ctor';
import { ProvideMetadata, ProvideMetadataClassSource, ProvideMetadataValueSource, ProvideMetadataCallbackSource } from '../metadata';
import { Logger } from '../services/logger';
import { Server } from '../server/server';
import { clc } from '../util/clc';

export class Injector {
    constructor(private server: Server) {
        this.cache.set(Server, () => this.server);
        this.cache.set(Logger, () => this.logger);
    }
    
    private get logger() {
        return this.server.logger;
    }
    
    private temporaryValue = Symbol.for('recursive-injection');
    private cache: Map<CtorT<any>, any> = new Map<CtorT<any>, any>();
    resolveInjectable<T>(ctorFn: CtorT<T>): T | undefined {
        if (!ctorFn) {
            this.logger.error('injector', 'Attempted to inject a falsey type.');
            return;
        }
        if (this.cache.get(ctorFn) === this.temporaryValue) {
            this.logger.error('injector', `Detected circular dependency. Recursive injection of type ${ctorFn.name || ctorFn}`);
            return;
        }
        if (this.cache.has(ctorFn)) {
            return this.cache.get(ctorFn)();
        }
        this.cache.set(ctorFn, this.temporaryValue);
        
        let inst = this.construct(ctorFn);
        this.cache.set(ctorFn, () => inst);
        return inst;
    }
    private construct<T>(ctorFn: CtorT<T>): T {
        let types: any[] = Reflect.getOwnMetadata('design:paramtypes', ctorFn);
        if (!types) types = [];
        if (types.find(type => type == Object)) throw new Error(`Could not dependency inject ${ctorFn.name || ctorFn}. Failed to resolve constructor types. Reflected: [${types.map(type => type.name || type).join(', ')}]`);
{'fraction_non_alphanumeric': 0.14794908062234796, 'fraction_numerical': 0.0, 'mean_word_length': 2.8434782608695652, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7351074', 'n_tokens_mistral': 1036, 'n_tokens_neox': 1034, 'n_words': 248}