import { InjectionToken, Injector, IPropertyDecorator, Logger, ORM_INITIALIZER, Provider, ProxyHandler } from '@notadd/core'; import { dataRangeProviders } from './data-range/token'; import { EncodeRuleMetadataKey, EncodeRuleOptions, ENCODE_RULE_HOOK } from './decorators'; import { encodeRuleElements } from './encode-rule-element'; import { CNQueryFailedError, QueryFialedErrorBase } from './error'; import { handlers } from './handlers'; import { PostgresQueryRunner } from './runner'; import { TYPEORM_ENTITIES, TYPEORM_NAME, TYPEORM_NAMING_STRATEGY, TYPEORM_OPTIONS, TYPEORM_QUERY_FAILED_ERROR } from './token'; import { Connection, ConnectionOptions, createConnection, getConnection } from './typeorm-native'; import { EntityColumnNameUtils } from './utils/entity-column-name.utils'; export function createRootProviders( options: ConnectionOptions | InjectionToken ): (Provider | Provider[])[] { return [ ...encodeRuleElements, ...handlers, ...dataRangeProviders, EntityColumnNameUtils, { provide: EncodeRuleMetadataKey, useValue: new ProxyHandler({ property: ( property: IPropertyDecorator, injector: Injector, instance: any ) => { const options = property.options; if (options) { const hook = injector.get(ENCODE_RULE_HOOK, null); if (hook) { return hook(instance, options, injector); } } }, }), }, { provide: QueryFialedErrorBase, useFactory: (injector: Injector) => { return injector.get( TYPEORM_QUERY_FAILED_ERROR, new CNQueryFailedError(injector.get(EntityColumnNameUtils)) ); }, deps: [Injector], }, { provide: TYPEORM_OPTIONS, useFactory: (injector: Injector) => { return options instanceof InjectionToken ? injector.get(options) : options; }, deps: [Injector], }, { provide: TYPEORM_NAME, useFactory: (injector: Injector) => { const options = injector.get(TYPEORM_OPTIONS); return options.name || 'default'; }, deps: [Injector], }, { provide: Connection, useFactory: (injector: Injector) => { const name = injector.get(TYPEORM_NAME); return getConnection(name); }, deps: [Injector], }, { provide: ORM_INITIALIZER, useFactory: () => { return async (injector: Injector) => { const options = injector.get(TYPEORM_OPTIONS); const logger = injector.get(Logger); const entityUtils = injector.get(EntityColumnNameUtils); const entities = [...new Set(injector.get(TYPEORM_ENTITIES, []).flat())]; entityUtils.saveEntityCache(entities); const namingStrategy = injector.get(TYPEORM_NAMING_STRATEGY, null); await createConnection({ ...options, namingStrategy, entities }) .then((res) => { options.synchronize ? logger.info(`数据库同步表结构已开启`) : logger.log(`数据库同步表结构已关闭`); logger.log(`数据库链接成功...`); res.driver.createQueryRunner = (mode: 'master' | 'slave') => { return new PostgresQueryRunner(res.driver as any, mode, injector); }; }) .catch((e) => { logger.error(`数据库链接失败...`); throw e; }); }; }, multi: true, deps: [], }, ]; }