import type { Provider } from '@nestjs/common'; import { type Constructor, isClass } from '@wener/utils'; // import { getMetadataStorage } from 'type-graphql'; type _ServiceClass = Constructor & { name: `${string}Service` | `${string}Impl` }; type _ResolverClass = Constructor & { name: `${string}Resolver` }; type EntityClass = Constructor & { name: `${string}Entity` }; type AnyConstructor = Constructor & { EntityType?: Function; ServiceType?: Function }; type Provide = AnyConstructor | Provider; export function resolveProvides(_all: Array): { resolvers: Constructor[]; // type graphql entities: Constructor[]; // mikro orm services: Constructor[]; controllers: Constructor[]; provides: Constructor[]; // all providers: Provider[]; } { const providers: Provider[] = []; const all: AnyConstructor[] = _all.filter((v) => { if (isClass(v)) { return true; } providers.push(v); return false; }) as AnyConstructor[]; // const resolverSet = new Set(getMetadataStorage().resolverClasses.map((v) => v.target)); const resolvers = all.filter((v) => { // return v.name.endsWith('Resolver') || resolverSet.has(v); return v.name.endsWith('Resolver'); }); const entities = all.flatMap((v) => { // check @Entity if (v.name.endsWith('Entity')) { return v; } if (v.EntityType) { return v.EntityType; } return []; }) as Constructor[]; const services = all.flatMap((v) => { if (v.name.endsWith('Service') || v.name.endsWith('Impl')) { return v; } if (v.ServiceType) { return v.ServiceType; } return []; }) as Constructor[]; const controllers = all.filter((v) => { // fixme check @Controller return v.name.endsWith('Controller'); }); { let a = new Set(all); resolvers.forEach((v) => a.delete(v)); entities.forEach((v) => a.delete(v)); services.forEach((v) => a.delete(v)); if (a.size) { throw new Error( `Unresolved Provides: ${Array.from(a) .map((v) => v.name) .join(', ')}`, ); } } const provides = services.concat(entities, resolvers); return { resolvers: unique(resolvers), entities: unique(entities), services: unique(services), provides: unique(provides), controllers: unique(controllers), providers, }; } function unique(arr: T[]): T[] { return Array.from(new Set(arr)); }