UNPKG

@deepkit/framework

Version:

449 lines 21.9 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DebugController = void 0; const __ΩPick = ['T', 'K', 'Pick', 'l+e#!e"!fRb!b"Pde""N#!w#y']; function __assignType(fn, args) { fn.__type = args; return fn; } /* * Deepkit Framework * Copyright (C) 2021 Deepkit UG, Marc J. Schmidt * * This program is free software: you can redistribute it and/or modify * it under the terms of the MIT License. * * You should have received a copy of the MIT License along with this program. */ const framework_debug_api_1 = require("@deepkit/framework-debug-api"); const rpc_1 = require("@deepkit/rpc"); const http_1 = require("@deepkit/http"); const core_1 = require("@deepkit/core"); const event_1 = require("@deepkit/event"); const orm_1 = require("@deepkit/orm"); const fs_1 = require("fs"); const path_1 = require("path"); const module_config_js_1 = require("../module.config.js"); const store_js_1 = require("./stopwatch/store.js"); const rxjs_1 = require("rxjs"); const promises_1 = require("fs/promises"); const injector_1 = require("@deepkit/injector"); const app_1 = require("@deepkit/app"); const rpc_js_1 = require("../rpc.js"); const type_1 = require("@deepkit/type"); const filesystem_js_1 = require("../filesystem.js"); const stopwatch_1 = require("@deepkit/stopwatch"); let DebugController = class DebugController { constructor(serviceContainer, eventDispatcher, router, config, rpcControllers, databaseRegistry, filesystemRegistry, stopwatchStore) { this.serviceContainer = serviceContainer; this.eventDispatcher = eventDispatcher; this.router = router; this.config = config; this.rpcControllers = rpcControllers; this.databaseRegistry = databaseRegistry; this.filesystemRegistry = filesystemRegistry; this.stopwatchStore = stopwatchStore; this.reservedTokenIds = (Map.Ω = [['Token', '"w!'], ['\'']], new Map()); this.idToTokenMap = (Map.Ω = [['\''], ['Token', '"w!']], new Map()); } async subscribeStopwatchFramesData() { if (!this.stopwatchStore || !this.stopwatchStore.frameDataChannel) throw new Error('not enabled'); const subject = (rxjs_1.Subject.Ω = [['W']], new rxjs_1.Subject()); const close = await this.stopwatchStore.frameDataChannel.subscribe(__assignType((v) => { subject.next(v); }, ['v', '', 'P"2!"/"'])); subject.subscribe().add(() => { close(); }); return subject; } async subscribeStopwatchFrames() { if (!this.stopwatchStore || !this.stopwatchStore.frameChannel) throw new Error('not enabled'); const subject = (rxjs_1.Subject.Ω = [['W']], new rxjs_1.Subject()); const close = await this.stopwatchStore.frameChannel.subscribe(__assignType((v) => { subject.next(v); }, ['v', '', 'P"2!"/"'])); subject.subscribe().add(() => { close(); }); return subject; } resetProfilerFrames() { const path = (0, path_1.join)(this.config.varPath, this.config.debugStorePath); (0, promises_1.unlink)((0, path_1.join)(path, 'frames.bin')).catch(); (0, promises_1.unlink)((0, path_1.join)(path, 'frames-data.bin')).catch(); } getProfilerFrames() { const framesPath = (0, path_1.join)(this.config.varPath, this.config.debugStorePath, 'frames.bin'); const frameDataPath = (0, path_1.join)(this.config.varPath, this.config.debugStorePath, 'frames-data.bin'); const analyticsPath = (0, path_1.join)(this.config.varPath, this.config.debugStorePath, 'analytics.bin'); for (const file of [framesPath, frameDataPath, analyticsPath]) { try { const stat = (0, fs_1.statSync)(file); if (stat.size > 1000000) { //make sure that file is not too big (0, fs_1.truncateSync)(file); } } catch { } } return [ (0, fs_1.existsSync)(framesPath) ? (0, fs_1.readFileSync)(framesPath) : new Uint8Array(), (0, fs_1.existsSync)(frameDataPath) ? (0, fs_1.readFileSync)(frameDataPath) : new Uint8Array(), (0, fs_1.existsSync)(frameDataPath) ? (0, fs_1.readFileSync)(frameDataPath) : new Uint8Array(), ]; } getFrames() { const framesPath = (0, path_1.join)(this.config.varPath, this.config.debugStorePath, 'frames.bin'); return (0, fs_1.readFileSync)(framesPath); } getFramesData() { const frameDataPath = (0, path_1.join)(this.config.varPath, this.config.debugStorePath, 'frames-data.bin'); return (0, fs_1.readFileSync)(frameDataPath); } httpRequests() { const requests = {}; (0, framework_debug_api_1.decodeFrames)(this.getFrames(), __assignType((frame) => { if (frame.type === stopwatch_1.FrameType.start) { if (frame.category !== stopwatch_1.FrameCategory.http) return; requests[frame.cid] = new framework_debug_api_1.DebugRequest(frame.cid, frame.timestamp, '', '', ''); } else if (frame.type === stopwatch_1.FrameType.end) { const r = requests[frame.cid]; if (!r) return; r.ended = frame.timestamp; } }, ['frame', '', 'P"2!"/"'])); (0, framework_debug_api_1.decodeFrameData)(this.getFramesData(), __assignType((frame) => { const r = requests[frame.cid]; if (!r) return; const data = (0, framework_debug_api_1.deserializeFrameData)(frame); if (data.clientIp) r.clientIp = data.clientIp; if (data.method) r.method = data.method; if (data.url) r.url = data.url; if (data.responseStatus) r.statusCode = data.responseStatus; }, ['frame', '', 'P"2!"/"'])); return Object.values(requests); } databases() { if (!this.databaseRegistry) return []; const databases = []; for (const db of this.databaseRegistry.getDatabases()) { const entities = []; for (const classSchema of db.entityRegistry.all()) { entities.push({ name: classSchema.name, className: classSchema.getClassName() }); } databases.push({ name: db.name, entities, adapter: db.adapter.getName() }); } return databases; } filesystems() { const filesystems = []; for (const fs of this.filesystemRegistry.getFilesystems()) { filesystems.push({ name: (0, core_1.getClassName)(fs), adapter: (0, core_1.getClassName)(fs.adapter), options: {} }); } return filesystems; } events() { const events = []; for (const token of this.eventDispatcher.getTokens()) { const listeners = this.eventDispatcher.getListeners(token); for (const listener of listeners) { if ((0, event_1.isEventListenerContainerEntryService)(listener)) { events.push({ event: token.id, controller: (0, core_1.getClassName)(listener.classType), methodName: listener.methodName, priority: listener.order, }); } } } return events; } routes() { const routes = []; for (const route of this.router.getRoutes()) { const routeD = { path: route.getFullPath(), httpMethods: route.httpMethods, parameters: [], groups: route.groups, category: route.category, controller: route.action.type === 'controller' ? (0, core_1.getClassName)(route.action.controller) + '.' + route.action.methodName : route.action.fn.name, description: route.description, }; const parsedRoute = (0, http_1.parseRouteControllerAction)(route); const queryParameters = []; for (const parameter of parsedRoute.getParameters()) { if (parameter.body || parameter.bodyValidation) { routeD.bodyType = (0, type_1.stringifyType)(parameter.getType()); } else if (parameter.query) { routeD.parameters.push({ name: parameter.getName(), type: 'query', stringType: (0, type_1.stringifyType)(parameter.parameter.parameter), }); queryParameters.push(`${parameter.getName()}=TODO`); // queryParameters.push(`${parameter.getName()}=${stringifyType(parameter.parameter.type)}`); } else if (parameter.isPartOfPath()) { routeD.parameters.push({ name: parameter.getName(), type: 'url', stringType: (0, type_1.stringifyType)(parameter.parameter.parameter), }); } else { //its a dependency injection token } } if (queryParameters.length) { routeD.path += '?' + queryParameters.join('&'); } routes.push(routeD); } return routes; } configuration() { const appConfig = []; if (this.serviceContainer.appModule.configDefinition) { const schema = type_1.ReflectionClass.from(this.serviceContainer.appModule.configDefinition); for (const [name, value] of Object.entries(this.serviceContainer.appModule.getConfig())) { const property = schema.getProperty(name); appConfig.push({ name: name, value: value, defaultValue: property.getDefaultValue(), description: property.getDescription(), type: (0, type_1.stringifyType)(property.property), }); } } const modulesConfig = []; for (const module of this.serviceContainer.appModule.getImports()) { if (!module.configDefinition) continue; const schema = type_1.ReflectionClass.from(module.configDefinition); for (const [name, value] of Object.entries(module.getConfig())) { const property = schema.getProperty(name); modulesConfig.push({ name: module.getName() + '.' + name, value: value, defaultValue: property.getDefaultValue(), description: property.getDescription(), type: (0, type_1.stringifyType)(property.property), }); } } return (0, core_1.changeClass)({ appConfig, modulesConfig, }, framework_debug_api_1.Config); } actions() { const result = []; for (const { controller } of this.rpcControllers.controllers.values()) { const rpcConfig = rpc_1.rpcClass._fetch(controller); if (!rpcConfig) continue; for (const action of rpcConfig.actions.values()) { const parameters = []; for (const parameter of type_1.ReflectionClass.from(controller).getMethodParameters(action.name || '')) { parameters.push(new framework_debug_api_1.RpcActionParameter(parameter.name, (0, type_1.stringifyType)(parameter.parameter))); } result.push({ path: rpcConfig.getPath(), controller: (0, core_1.getClassName)(controller), methodName: action.name || '', parameters: parameters, }); } } return result; } getWorkflow(name) { const w = this.serviceContainer.workflowRegistry.get(name); return (0, core_1.changeClass)({ places: Object.keys(w.places), transitions: w.transitions, }, framework_debug_api_1.Workflow); } // @rpc.action() // httpRequests(): Promise<Collection<DebugRequest>> { // return this.liveDatabase.query(DebugRequest).find(); // } modules() { const injectorContext = this.serviceContainer.getInjectorContext(); const getTokenId = __assignType((token) => { const found = this.reservedTokenIds.get(token); if (found === undefined) { const id = this.reservedTokenIds.size; this.idToTokenMap.set(id, token); this.reservedTokenIds.set(token, id); return id; } return found; }, ['Token', 'token', '', 'P"w!2"\'/#']); function getTokenLabel(token) { if ((0, core_1.isClass)(token)) return (0, core_1.getClassName)(token); if ((0, type_1.isType)(token)) return (0, type_1.stringifyType)(token); return String(token); } getTokenLabel.__type = ['Token', 'token', 'getTokenLabel', 'P"w!2"&/#']; function extract(module) { const moduleApi = new framework_debug_api_1.ModuleApi(module.name, module.id, (0, core_1.getClassName)(module)); moduleApi.config = module.getConfig(); if (module.configDefinition) { moduleApi.configSchemas = (0, type_1.serializeType)(type_1.ReflectionClass.from(module.configDefinition).type); } for (const provider of module.getProviders()) { const token = (0, injector_1.resolveToken)(provider); const service = new framework_debug_api_1.ModuleService(getTokenId(token), getTokenLabel(token)); service.scope = (0, injector_1.getScope)(provider); service.instantiations = injectorContext.instantiationCount(token, module, service.scope); if ((0, core_1.isClass)(token) && module.controllers.includes(token)) { service.type = 'controller'; } else if ((0, core_1.isClass)(token) && module.listeners.includes(token)) { service.type = 'listener'; } moduleApi.services.push(service); service.exported = module.isExported(token); service.forRoot = module.root; } const builtPreparedProviders = module.getBuiltPreparedProviders(); if (builtPreparedProviders) { for (const preparedProvider of builtPreparedProviders) { const token = preparedProvider.token; //We want to know which token has been imported by whom if (preparedProvider.modules[0] !== module) { //was imported from originally preparedProvider.modules[0] moduleApi.importedServices.push(new framework_debug_api_1.ModuleImportedService(getTokenId(token), getTokenLabel(token), (0, core_1.getClassName)(preparedProvider.modules[0]))); } else if (preparedProvider.modules.length > 1) { //was imported and overwritten by this module moduleApi.importedServices.push(new framework_debug_api_1.ModuleImportedService(getTokenId(token), getTokenLabel(token), (0, core_1.getClassName)(preparedProvider.modules[1]))); } } } for (const m of module.getImports()) { moduleApi.imports.push(extract(m)); } return moduleApi; } extract.__type = [() => app_1.AppModule, 'module', () => framework_debug_api_1.ModuleApi, 'extract', 'PP"7!2"P7#/$']; return extract(this.serviceContainer.appModule); } }; exports.DebugController = DebugController; DebugController.__type = ['reservedTokenIds', function () { return (Map.Ω = [['Token', '"w!'], ['\'']], new Map()); }, 'idToTokenMap', function () { return (Map.Ω = [['\''], ['Token', '"w!']], new Map()); }, () => app_1.ServiceContainer, 'serviceContainer', () => event_1.EventDispatcher, 'eventDispatcher', () => http_1.HttpRouter, 'router', () => __ΩPick, () => module_config_js_1.FrameworkConfig, "varPath", "debugStorePath", 'config', () => rpc_js_1.RpcControllers, 'rpcControllers', () => orm_1.DatabaseRegistry, 'databaseRegistry', () => filesystem_js_1.FilesystemRegistry, 'filesystemRegistry', () => store_js_1.FileStopwatchStore, 'stopwatchStore', 'constructor', () => rxjs_1.Subject, 'subscribeStopwatchFramesData', () => rxjs_1.Subject, 'subscribeStopwatchFrames', 'resetProfilerFrames', 'getProfilerFrames', 'getFrames', 'getFramesData', () => framework_debug_api_1.DebugRequest, 'httpRequests', () => framework_debug_api_1.Database, 'databases', () => framework_debug_api_1.Filesystem, 'filesystems', () => framework_debug_api_1.Event, 'events', () => framework_debug_api_1.Route, 'routes', () => framework_debug_api_1.Config, 'configuration', () => framework_debug_api_1.RpcAction, 'actions', 'name', () => framework_debug_api_1.Workflow, 'getWorkflow', () => framework_debug_api_1.ModuleApi, 'modules', 'DebugController', '!3!<>"!3#<>$PP7%2&<P7\'2(<P7)2*<P7,P.-..Jo+#2/<P7021<P7223<P7425<P76278<"08PPW79`0:PPW7;`0<P$0=PPWWWG0>P"0?<P"0@<PP7AF0BPP7CF0DPP7EF0FPP7GF0HPP7IF0JPP7K0LPP7MF0NP&2OP7P0QPP7R0S5!x"wT']; __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], DebugController.prototype, "subscribeStopwatchFramesData", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], DebugController.prototype, "subscribeStopwatchFrames", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], DebugController.prototype, "resetProfilerFrames", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], DebugController.prototype, "getProfilerFrames", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], DebugController.prototype, "httpRequests", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], DebugController.prototype, "databases", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], DebugController.prototype, "filesystems", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], DebugController.prototype, "events", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], DebugController.prototype, "routes", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", framework_debug_api_1.Config) ], DebugController.prototype, "configuration", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], DebugController.prototype, "actions", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", framework_debug_api_1.Workflow) ], DebugController.prototype, "getWorkflow", null); __decorate([ rpc_1.rpc.action(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", framework_debug_api_1.ModuleApi) ], DebugController.prototype, "modules", null); exports.DebugController = DebugController = __decorate([ rpc_1.rpc.controller(framework_debug_api_1.DebugControllerInterface), __metadata("design:paramtypes", [app_1.ServiceContainer, event_1.EventDispatcher, http_1.HttpRouter, Object, rpc_js_1.RpcControllers, orm_1.DatabaseRegistry, filesystem_js_1.FilesystemRegistry, store_js_1.FileStopwatchStore]) ], DebugController); //# sourceMappingURL=debug.controller.js.map