UNPKG

@wocker/core

Version:
148 lines (147 loc) 5.98 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Scanner = void 0; require("reflect-metadata"); const cli_1 = require("@kearisp/cli"); const Container_1 = require("./Container"); const ModuleWrapper_1 = require("./ModuleWrapper"); const env_1 = require("../env"); class Scanner { constructor() { this.container = new Container_1.Container(); } scan(moduleType) { return __awaiter(this, void 0, void 0, function* () { this.scanModule(moduleType); yield this.scanDynamicModules(); this.scanRoutes(); }); } scanModule(moduleType) { let module = this.container.hasModule(moduleType) ? this.container.getModule(moduleType) : null; if (!module) { module = new ModuleWrapper_1.ModuleWrapper(this.container, moduleType); this.container.addModule(moduleType, module); this.scanImports(module); this.scanControllers(module); this.scanProviders(module); this.scanExports(module); } return module; } scanControllers(module) { const controllers = Reflect.getMetadata(env_1.MODULE_METADATA.CONTROLLERS, module.type) || []; controllers.forEach((controller) => { module.addController(controller); }); } scanProviders(module) { const providers = Reflect.getMetadata(env_1.MODULE_METADATA.PROVIDERS, module.type) || []; providers.forEach((provider) => { module.addProvider(provider); }); } scanImports(module) { const imports = Reflect.getMetadata(env_1.MODULE_METADATA.IMPORTS, module.type) || []; imports.forEach((importType) => { const subModule = this.scanModule(importType); subModule.exports.forEach((type) => { const provider = subModule.providers.get(type); if (!provider) { return; } module.providers.set(type, provider); }); }); } scanExports(module) { const exports = Reflect.getMetadata(env_1.MODULE_METADATA.EXPORTS, module.type) || []; const isGlobal = Reflect.getMetadata(env_1.IS_GLOBAL_METADATA, module.type) || false; exports.forEach((type) => { module.addExport(type); if (isGlobal) { const wrapper = module.getWrapper(type); if (wrapper) { this.container.addProvider(type, wrapper); } } }); } scanRoutes() { const cliWrapper = this.container.globalProviders.get(cli_1.Cli); if (!cliWrapper) { return; } const cli = cliWrapper.instance; for (const [, module] of this.container.modules) { for (const [, controller] of module.controllers) { if (!controller.instance) { continue; } this.scanControllerRoutes(cli, controller); } } } scanControllerRoutes(cli, wrapper) { for (const route of wrapper.commands) { for (const commandName of route.commandNames) { const command = cli.command(commandName); if (route.description) { command.help({ description: route.description }); } command.action((input) => { return wrapper.run(route, input); }); for (const arg of route.args) { if (arg.type === "option") { command.option(arg.name, arg.params); } command.completion(arg.name, (input) => { const [completion] = wrapper.getCompletionCommands(arg.name, commandName); if (!completion) { return []; } return wrapper.run(completion, input); }); } } } } scanDynamicModules() { return __awaiter(this, void 0, void 0, function* () { const promises = ([...this.container.modules.keys()]).map((type) => __awaiter(this, void 0, void 0, function* () { if (!type.prototype.load) { return; } const parentModule = this.container.modules.get(type); const { [env_1.MODULE_METADATA.IMPORTS]: imports = [] } = yield type.prototype.load(this.container); for (const subModuleType of imports) { const module = this.scanModule(subModuleType); module.exports.forEach((type) => { const provider = module.getWrapper(type); if (!provider) { return; } // @ts-ignore parentModule.providers.set(type, provider); }); } })); yield Promise.all(promises); }); } } exports.Scanner = Scanner;