@dxheroes/local-mcp-backend 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.swcrc +22 -0
- package/.turbo/turbo-build.log +9 -0
- package/AGENTS.md +360 -0
- package/CHANGELOG.md +60 -0
- package/Dockerfile +71 -0
- package/LICENSE +94 -0
- package/dist/app.module.js +72 -0
- package/dist/app.module.js.map +1 -0
- package/dist/common/decorators/request-id.decorator.js +12 -0
- package/dist/common/decorators/request-id.decorator.js.map +1 -0
- package/dist/common/filters/all-exceptions.filter.js +61 -0
- package/dist/common/filters/all-exceptions.filter.js.map +1 -0
- package/dist/common/interceptors/logging.interceptor.js +46 -0
- package/dist/common/interceptors/logging.interceptor.js.map +1 -0
- package/dist/common/pipes/validation.pipe.js +43 -0
- package/dist/common/pipes/validation.pipe.js.map +1 -0
- package/dist/config/app.config.js +14 -0
- package/dist/config/app.config.js.map +1 -0
- package/dist/config/database.config.js +30 -0
- package/dist/config/database.config.js.map +1 -0
- package/dist/main.js +68 -0
- package/dist/main.js.map +1 -0
- package/dist/modules/database/database.module.js +27 -0
- package/dist/modules/database/database.module.js.map +1 -0
- package/dist/modules/database/prisma.service.js +122 -0
- package/dist/modules/database/prisma.service.js.map +1 -0
- package/dist/modules/debug/debug.controller.js +87 -0
- package/dist/modules/debug/debug.controller.js.map +1 -0
- package/dist/modules/debug/debug.module.js +30 -0
- package/dist/modules/debug/debug.module.js.map +1 -0
- package/dist/modules/debug/debug.service.js +126 -0
- package/dist/modules/debug/debug.service.js.map +1 -0
- package/dist/modules/health/health.controller.js +69 -0
- package/dist/modules/health/health.controller.js.map +1 -0
- package/dist/modules/health/health.module.js +23 -0
- package/dist/modules/health/health.module.js.map +1 -0
- package/dist/modules/mcp/dto/create-mcp-server.dto.js +74 -0
- package/dist/modules/mcp/dto/create-mcp-server.dto.js.map +1 -0
- package/dist/modules/mcp/dto/update-mcp-server.dto.js +74 -0
- package/dist/modules/mcp/dto/update-mcp-server.dto.js.map +1 -0
- package/dist/modules/mcp/mcp-discovery.service.js +176 -0
- package/dist/modules/mcp/mcp-discovery.service.js.map +1 -0
- package/dist/modules/mcp/mcp-registry.js +67 -0
- package/dist/modules/mcp/mcp-registry.js.map +1 -0
- package/dist/modules/mcp/mcp-seed.service.js +122 -0
- package/dist/modules/mcp/mcp-seed.service.js.map +1 -0
- package/dist/modules/mcp/mcp.controller.js +152 -0
- package/dist/modules/mcp/mcp.controller.js.map +1 -0
- package/dist/modules/mcp/mcp.module.js +70 -0
- package/dist/modules/mcp/mcp.module.js.map +1 -0
- package/dist/modules/mcp/mcp.service.js +401 -0
- package/dist/modules/mcp/mcp.service.js.map +1 -0
- package/dist/modules/oauth/oauth.controller.js +116 -0
- package/dist/modules/oauth/oauth.controller.js.map +1 -0
- package/dist/modules/oauth/oauth.module.js +31 -0
- package/dist/modules/oauth/oauth.module.js.map +1 -0
- package/dist/modules/oauth/oauth.service.js +183 -0
- package/dist/modules/oauth/oauth.service.js.map +1 -0
- package/dist/modules/profiles/profiles.controller.js +241 -0
- package/dist/modules/profiles/profiles.controller.js.map +1 -0
- package/dist/modules/profiles/profiles.module.js +34 -0
- package/dist/modules/profiles/profiles.module.js.map +1 -0
- package/dist/modules/profiles/profiles.service.js +390 -0
- package/dist/modules/profiles/profiles.service.js.map +1 -0
- package/dist/modules/proxy/proxy.controller.js +98 -0
- package/dist/modules/proxy/proxy.controller.js.map +1 -0
- package/dist/modules/proxy/proxy.module.js +36 -0
- package/dist/modules/proxy/proxy.module.js.map +1 -0
- package/dist/modules/proxy/proxy.service.js +439 -0
- package/dist/modules/proxy/proxy.service.js.map +1 -0
- package/docker-entrypoint.sh +10 -0
- package/nest-cli.json +10 -0
- package/package.json +51 -0
- package/src/app.module.ts +59 -0
- package/src/common/decorators/request-id.decorator.ts +16 -0
- package/src/common/filters/all-exceptions.filter.ts +77 -0
- package/src/common/interceptors/logging.interceptor.ts +45 -0
- package/src/common/pipes/validation.pipe.ts +31 -0
- package/src/config/app.config.ts +15 -0
- package/src/config/database.config.ts +34 -0
- package/src/main.ts +66 -0
- package/src/modules/database/database.module.ts +15 -0
- package/src/modules/database/prisma.service.ts +110 -0
- package/src/modules/debug/debug.controller.ts +53 -0
- package/src/modules/debug/debug.module.ts +16 -0
- package/src/modules/debug/debug.service.ts +143 -0
- package/src/modules/health/health.controller.ts +48 -0
- package/src/modules/health/health.module.ts +13 -0
- package/src/modules/mcp/dto/create-mcp-server.dto.ts +53 -0
- package/src/modules/mcp/dto/update-mcp-server.dto.ts +53 -0
- package/src/modules/mcp/mcp-discovery.service.ts +205 -0
- package/src/modules/mcp/mcp-registry.ts +73 -0
- package/src/modules/mcp/mcp-seed.service.ts +125 -0
- package/src/modules/mcp/mcp.controller.ts +98 -0
- package/src/modules/mcp/mcp.module.ts +48 -0
- package/src/modules/mcp/mcp.service.ts +427 -0
- package/src/modules/oauth/oauth.controller.ts +89 -0
- package/src/modules/oauth/oauth.module.ts +17 -0
- package/src/modules/oauth/oauth.service.ts +212 -0
- package/src/modules/profiles/profiles.controller.ts +177 -0
- package/src/modules/profiles/profiles.module.ts +18 -0
- package/src/modules/profiles/profiles.service.ts +421 -0
- package/src/modules/proxy/proxy.controller.ts +61 -0
- package/src/modules/proxy/proxy.module.ts +19 -0
- package/src/modules/proxy/proxy.service.ts +595 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/app.module.ts"],"sourcesContent":["/**\n * Root Application Module\n *\n * Configures all NestJS modules for the Local MCP Gateway.\n * No authentication module - immediate access to all features.\n */\n\nimport { Module } from '@nestjs/common';\nimport { ConfigModule } from '@nestjs/config';\nimport { ThrottlerModule } from '@nestjs/throttler';\nimport appConfig from './config/app.config.js';\nimport databaseConfig from './config/database.config.js';\nimport { DatabaseModule } from './modules/database/database.module.js';\nimport { DebugModule } from './modules/debug/debug.module.js';\nimport { HealthModule } from './modules/health/health.module.js';\nimport { McpModule } from './modules/mcp/mcp.module.js';\nimport { OAuthModule } from './modules/oauth/oauth.module.js';\nimport { ProfilesModule } from './modules/profiles/profiles.module.js';\nimport { ProxyModule } from './modules/proxy/proxy.module.js';\n\n@Module({\n imports: [\n // Configuration\n ConfigModule.forRoot({\n isGlobal: true,\n load: [appConfig, databaseConfig],\n envFilePath: ['../../.env', '.env.local', '.env'],\n }),\n\n // Rate limiting\n ThrottlerModule.forRoot([\n {\n name: 'short',\n ttl: 1000,\n limit: 10,\n },\n {\n name: 'medium',\n ttl: 10000,\n limit: 50,\n },\n {\n name: 'long',\n ttl: 60000,\n limit: 200,\n },\n ]),\n\n // Core modules (no authentication - immediate access)\n DatabaseModule,\n McpModule,\n ProfilesModule,\n OAuthModule, // For OAuth MCP servers, not user authentication\n ProxyModule,\n HealthModule,\n DebugModule,\n ],\n})\nexport class AppModule {}\n"],"names":["Module","ConfigModule","ThrottlerModule","appConfig","databaseConfig","DatabaseModule","DebugModule","HealthModule","McpModule","OAuthModule","ProfilesModule","ProxyModule","AppModule","imports","forRoot","isGlobal","load","envFilePath","name","ttl","limit"],"mappings":";;;;;;AAAA;;;;;CAKC,GAED,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,YAAY,QAAQ,iBAAiB;AAC9C,SAASC,eAAe,QAAQ,oBAAoB;AACpD,OAAOC,eAAe,yBAAyB;AAC/C,OAAOC,oBAAoB,8BAA8B;AACzD,SAASC,cAAc,QAAQ,wCAAwC;AACvE,SAASC,WAAW,QAAQ,kCAAkC;AAC9D,SAASC,YAAY,QAAQ,oCAAoC;AACjE,SAASC,SAAS,QAAQ,8BAA8B;AACxD,SAASC,WAAW,QAAQ,kCAAkC;AAC9D,SAASC,cAAc,QAAQ,wCAAwC;AACvE,SAASC,WAAW,QAAQ,kCAAkC;AAwC9D,OAAO,MAAMC;AAAW;;;QArCtBC,SAAS;YACP,gBAAgB;YAChBZ,aAAaa,OAAO,CAAC;gBACnBC,UAAU;gBACVC,MAAM;oBAACb;oBAAWC;iBAAe;gBACjCa,aAAa;oBAAC;oBAAc;oBAAc;iBAAO;YACnD;YAEA,gBAAgB;YAChBf,gBAAgBY,OAAO,CAAC;gBACtB;oBACEI,MAAM;oBACNC,KAAK;oBACLC,OAAO;gBACT;gBACA;oBACEF,MAAM;oBACNC,KAAK;oBACLC,OAAO;gBACT;gBACA;oBACEF,MAAM;oBACNC,KAAK;oBACLC,OAAO;gBACT;aACD;YAED,sDAAsD;YACtDf;YACAG;YACAE;YACAD;YACAE;YACAJ;YACAD;SACD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request ID Decorator
|
|
3
|
+
*
|
|
4
|
+
* Extracts request ID from the request headers.
|
|
5
|
+
*/ import { createParamDecorator } from "@nestjs/common";
|
|
6
|
+
export const RequestId = createParamDecorator((_data, ctx)=>{
|
|
7
|
+
const request = ctx.switchToHttp().getRequest();
|
|
8
|
+
const requestId = request.headers['x-request-id'];
|
|
9
|
+
return typeof requestId === 'string' ? requestId : undefined;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=request-id.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/common/decorators/request-id.decorator.ts"],"sourcesContent":["/**\n * Request ID Decorator\n *\n * Extracts request ID from the request headers.\n */\n\nimport { createParamDecorator, ExecutionContext } from '@nestjs/common';\nimport { Request } from 'express';\n\nexport const RequestId = createParamDecorator(\n (_data: unknown, ctx: ExecutionContext): string | undefined => {\n const request = ctx.switchToHttp().getRequest<Request>();\n const requestId = request.headers['x-request-id'];\n return typeof requestId === 'string' ? requestId : undefined;\n }\n);\n"],"names":["createParamDecorator","RequestId","_data","ctx","request","switchToHttp","getRequest","requestId","headers","undefined"],"mappings":"AAAA;;;;CAIC,GAED,SAASA,oBAAoB,QAA0B,iBAAiB;AAGxE,OAAO,MAAMC,YAAYD,qBACvB,CAACE,OAAgBC;IACf,MAAMC,UAAUD,IAAIE,YAAY,GAAGC,UAAU;IAC7C,MAAMC,YAAYH,QAAQI,OAAO,CAAC,eAAe;IACjD,OAAO,OAAOD,cAAc,WAAWA,YAAYE;AACrD,GACA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Global Exception Filter
|
|
9
|
+
*
|
|
10
|
+
* Catches all exceptions and formats them consistently.
|
|
11
|
+
*/ import { Catch, HttpException, HttpStatus, Logger } from "@nestjs/common";
|
|
12
|
+
export class AllExceptionsFilter {
|
|
13
|
+
catch(exception, host) {
|
|
14
|
+
const ctx = host.switchToHttp();
|
|
15
|
+
const response = ctx.getResponse();
|
|
16
|
+
const request = ctx.getRequest();
|
|
17
|
+
let status = HttpStatus.INTERNAL_SERVER_ERROR;
|
|
18
|
+
let message = 'Internal server error';
|
|
19
|
+
let error = 'Internal Server Error';
|
|
20
|
+
if (exception instanceof HttpException) {
|
|
21
|
+
status = exception.getStatus();
|
|
22
|
+
const exceptionResponse = exception.getResponse();
|
|
23
|
+
if (typeof exceptionResponse === 'string') {
|
|
24
|
+
message = exceptionResponse;
|
|
25
|
+
} else if (typeof exceptionResponse === 'object') {
|
|
26
|
+
const responseObj = exceptionResponse;
|
|
27
|
+
message = responseObj.message || message;
|
|
28
|
+
error = responseObj.error || exception.name;
|
|
29
|
+
}
|
|
30
|
+
} else if (exception instanceof Error) {
|
|
31
|
+
message = exception.message;
|
|
32
|
+
error = exception.name;
|
|
33
|
+
}
|
|
34
|
+
// Log error
|
|
35
|
+
this.logger.error(`${request.method} ${request.url} - ${status} - ${message}`, {
|
|
36
|
+
exception: exception instanceof Error ? exception.stack : String(exception),
|
|
37
|
+
requestId: request.headers['x-request-id']
|
|
38
|
+
});
|
|
39
|
+
const errorResponse = {
|
|
40
|
+
statusCode: status,
|
|
41
|
+
message,
|
|
42
|
+
error,
|
|
43
|
+
timestamp: new Date().toISOString(),
|
|
44
|
+
path: request.url
|
|
45
|
+
};
|
|
46
|
+
// Add request ID if present
|
|
47
|
+
const requestId = request.headers['x-request-id'];
|
|
48
|
+
if (typeof requestId === 'string') {
|
|
49
|
+
errorResponse.requestId = requestId;
|
|
50
|
+
}
|
|
51
|
+
response.status(status).json(errorResponse);
|
|
52
|
+
}
|
|
53
|
+
constructor(){
|
|
54
|
+
this.logger = new Logger(AllExceptionsFilter.name);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
AllExceptionsFilter = _ts_decorate([
|
|
58
|
+
Catch()
|
|
59
|
+
], AllExceptionsFilter);
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=all-exceptions.filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/common/filters/all-exceptions.filter.ts"],"sourcesContent":["/**\n * Global Exception Filter\n *\n * Catches all exceptions and formats them consistently.\n */\n\nimport {\n ArgumentsHost,\n Catch,\n ExceptionFilter,\n HttpException,\n HttpStatus,\n Logger,\n} from '@nestjs/common';\nimport { Request, Response } from 'express';\n\ninterface ErrorResponse {\n statusCode: number;\n message: string;\n error: string;\n timestamp: string;\n path: string;\n requestId?: string;\n}\n\n@Catch()\nexport class AllExceptionsFilter implements ExceptionFilter {\n private readonly logger = new Logger(AllExceptionsFilter.name);\n\n catch(exception: unknown, host: ArgumentsHost): void {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<Response>();\n const request = ctx.getRequest<Request>();\n\n let status = HttpStatus.INTERNAL_SERVER_ERROR;\n let message = 'Internal server error';\n let error = 'Internal Server Error';\n\n if (exception instanceof HttpException) {\n status = exception.getStatus();\n const exceptionResponse = exception.getResponse();\n\n if (typeof exceptionResponse === 'string') {\n message = exceptionResponse;\n } else if (typeof exceptionResponse === 'object') {\n const responseObj = exceptionResponse as Record<string, unknown>;\n message = (responseObj.message as string) || message;\n error = (responseObj.error as string) || exception.name;\n }\n } else if (exception instanceof Error) {\n message = exception.message;\n error = exception.name;\n }\n\n // Log error\n this.logger.error(`${request.method} ${request.url} - ${status} - ${message}`, {\n exception: exception instanceof Error ? exception.stack : String(exception),\n requestId: request.headers['x-request-id'],\n });\n\n const errorResponse: ErrorResponse = {\n statusCode: status,\n message,\n error,\n timestamp: new Date().toISOString(),\n path: request.url,\n };\n\n // Add request ID if present\n const requestId = request.headers['x-request-id'];\n if (typeof requestId === 'string') {\n errorResponse.requestId = requestId;\n }\n\n response.status(status).json(errorResponse);\n }\n}\n"],"names":["Catch","HttpException","HttpStatus","Logger","AllExceptionsFilter","catch","exception","host","ctx","switchToHttp","response","getResponse","request","getRequest","status","INTERNAL_SERVER_ERROR","message","error","getStatus","exceptionResponse","responseObj","name","Error","logger","method","url","stack","String","requestId","headers","errorResponse","statusCode","timestamp","Date","toISOString","path","json"],"mappings":";;;;;;AAAA;;;;CAIC,GAED,SAEEA,KAAK,EAELC,aAAa,EACbC,UAAU,EACVC,MAAM,QACD,iBAAiB;AAaxB,OAAO,MAAMC;IAGXC,MAAMC,SAAkB,EAAEC,IAAmB,EAAQ;QACnD,MAAMC,MAAMD,KAAKE,YAAY;QAC7B,MAAMC,WAAWF,IAAIG,WAAW;QAChC,MAAMC,UAAUJ,IAAIK,UAAU;QAE9B,IAAIC,SAASZ,WAAWa,qBAAqB;QAC7C,IAAIC,UAAU;QACd,IAAIC,QAAQ;QAEZ,IAAIX,qBAAqBL,eAAe;YACtCa,SAASR,UAAUY,SAAS;YAC5B,MAAMC,oBAAoBb,UAAUK,WAAW;YAE/C,IAAI,OAAOQ,sBAAsB,UAAU;gBACzCH,UAAUG;YACZ,OAAO,IAAI,OAAOA,sBAAsB,UAAU;gBAChD,MAAMC,cAAcD;gBACpBH,UAAU,AAACI,YAAYJ,OAAO,IAAeA;gBAC7CC,QAAQ,AAACG,YAAYH,KAAK,IAAeX,UAAUe,IAAI;YACzD;QACF,OAAO,IAAIf,qBAAqBgB,OAAO;YACrCN,UAAUV,UAAUU,OAAO;YAC3BC,QAAQX,UAAUe,IAAI;QACxB;QAEA,YAAY;QACZ,IAAI,CAACE,MAAM,CAACN,KAAK,CAAC,GAAGL,QAAQY,MAAM,CAAC,CAAC,EAAEZ,QAAQa,GAAG,CAAC,GAAG,EAAEX,OAAO,GAAG,EAAEE,SAAS,EAAE;YAC7EV,WAAWA,qBAAqBgB,QAAQhB,UAAUoB,KAAK,GAAGC,OAAOrB;YACjEsB,WAAWhB,QAAQiB,OAAO,CAAC,eAAe;QAC5C;QAEA,MAAMC,gBAA+B;YACnCC,YAAYjB;YACZE;YACAC;YACAe,WAAW,IAAIC,OAAOC,WAAW;YACjCC,MAAMvB,QAAQa,GAAG;QACnB;QAEA,4BAA4B;QAC5B,MAAMG,YAAYhB,QAAQiB,OAAO,CAAC,eAAe;QACjD,IAAI,OAAOD,cAAc,UAAU;YACjCE,cAAcF,SAAS,GAAGA;QAC5B;QAEAlB,SAASI,MAAM,CAACA,QAAQsB,IAAI,CAACN;IAC/B;;aAhDiBP,SAAS,IAAIpB,OAAOC,oBAAoBiB,IAAI;;AAiD/D"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Logging Interceptor
|
|
9
|
+
*
|
|
10
|
+
* Logs incoming requests and outgoing responses with timing.
|
|
11
|
+
*/ import { randomUUID } from "node:crypto";
|
|
12
|
+
import { Injectable, Logger } from "@nestjs/common";
|
|
13
|
+
import { tap } from "rxjs/operators";
|
|
14
|
+
export class LoggingInterceptor {
|
|
15
|
+
intercept(context, next) {
|
|
16
|
+
const ctx = context.switchToHttp();
|
|
17
|
+
const request = ctx.getRequest();
|
|
18
|
+
const response = ctx.getResponse();
|
|
19
|
+
// Add request ID if not present
|
|
20
|
+
if (!request.headers['x-request-id']) {
|
|
21
|
+
request.headers['x-request-id'] = randomUUID();
|
|
22
|
+
}
|
|
23
|
+
const requestId = request.headers['x-request-id'];
|
|
24
|
+
response.setHeader('x-request-id', requestId);
|
|
25
|
+
const { method, url } = request;
|
|
26
|
+
const startTime = Date.now();
|
|
27
|
+
return next.handle().pipe(tap({
|
|
28
|
+
next: ()=>{
|
|
29
|
+
const duration = Date.now() - startTime;
|
|
30
|
+
this.logger.log(`${method} ${url} ${response.statusCode} - ${duration}ms`);
|
|
31
|
+
},
|
|
32
|
+
error: ()=>{
|
|
33
|
+
const duration = Date.now() - startTime;
|
|
34
|
+
this.logger.warn(`${method} ${url} ERROR - ${duration}ms`);
|
|
35
|
+
}
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
constructor(){
|
|
39
|
+
this.logger = new Logger('HTTP');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
LoggingInterceptor = _ts_decorate([
|
|
43
|
+
Injectable()
|
|
44
|
+
], LoggingInterceptor);
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=logging.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/common/interceptors/logging.interceptor.ts"],"sourcesContent":["/**\n * Logging Interceptor\n *\n * Logs incoming requests and outgoing responses with timing.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { CallHandler, ExecutionContext, Injectable, Logger, NestInterceptor } from '@nestjs/common';\nimport { Request, Response } from 'express';\nimport { Observable } from 'rxjs';\nimport { tap } from 'rxjs/operators';\n\n@Injectable()\nexport class LoggingInterceptor implements NestInterceptor {\n private readonly logger = new Logger('HTTP');\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n const ctx = context.switchToHttp();\n const request = ctx.getRequest<Request>();\n const response = ctx.getResponse<Response>();\n\n // Add request ID if not present\n if (!request.headers['x-request-id']) {\n request.headers['x-request-id'] = randomUUID();\n }\n const requestId = request.headers['x-request-id'];\n response.setHeader('x-request-id', requestId);\n\n const { method, url } = request;\n const startTime = Date.now();\n\n return next.handle().pipe(\n tap({\n next: () => {\n const duration = Date.now() - startTime;\n this.logger.log(`${method} ${url} ${response.statusCode} - ${duration}ms`);\n },\n error: () => {\n const duration = Date.now() - startTime;\n this.logger.warn(`${method} ${url} ERROR - ${duration}ms`);\n },\n })\n );\n }\n}\n"],"names":["randomUUID","Injectable","Logger","tap","LoggingInterceptor","intercept","context","next","ctx","switchToHttp","request","getRequest","response","getResponse","headers","requestId","setHeader","method","url","startTime","Date","now","handle","pipe","duration","logger","log","statusCode","error","warn"],"mappings":";;;;;;AAAA;;;;CAIC,GAED,SAASA,UAAU,QAAQ,cAAc;AACzC,SAAwCC,UAAU,EAAEC,MAAM,QAAyB,iBAAiB;AAGpG,SAASC,GAAG,QAAQ,iBAAiB;AAGrC,OAAO,MAAMC;IAGXC,UAAUC,OAAyB,EAAEC,IAAiB,EAAuB;QAC3E,MAAMC,MAAMF,QAAQG,YAAY;QAChC,MAAMC,UAAUF,IAAIG,UAAU;QAC9B,MAAMC,WAAWJ,IAAIK,WAAW;QAEhC,gCAAgC;QAChC,IAAI,CAACH,QAAQI,OAAO,CAAC,eAAe,EAAE;YACpCJ,QAAQI,OAAO,CAAC,eAAe,GAAGd;QACpC;QACA,MAAMe,YAAYL,QAAQI,OAAO,CAAC,eAAe;QACjDF,SAASI,SAAS,CAAC,gBAAgBD;QAEnC,MAAM,EAAEE,MAAM,EAAEC,GAAG,EAAE,GAAGR;QACxB,MAAMS,YAAYC,KAAKC,GAAG;QAE1B,OAAOd,KAAKe,MAAM,GAAGC,IAAI,CACvBpB,IAAI;YACFI,MAAM;gBACJ,MAAMiB,WAAWJ,KAAKC,GAAG,KAAKF;gBAC9B,IAAI,CAACM,MAAM,CAACC,GAAG,CAAC,GAAGT,OAAO,CAAC,EAAEC,IAAI,CAAC,EAAEN,SAASe,UAAU,CAAC,GAAG,EAAEH,SAAS,EAAE,CAAC;YAC3E;YACAI,OAAO;gBACL,MAAMJ,WAAWJ,KAAKC,GAAG,KAAKF;gBAC9B,IAAI,CAACM,MAAM,CAACI,IAAI,CAAC,GAAGZ,OAAO,CAAC,EAAEC,IAAI,SAAS,EAAEM,SAAS,EAAE,CAAC;YAC3D;QACF;IAEJ;;aA7BiBC,SAAS,IAAIvB,OAAO;;AA8BvC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
function _ts_metadata(k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Zod Validation Pipe
|
|
12
|
+
*
|
|
13
|
+
* Custom validation pipe that uses Zod schemas.
|
|
14
|
+
*/ import { BadRequestException, Injectable } from "@nestjs/common";
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
export class ZodValidationPipe {
|
|
17
|
+
constructor(schema){
|
|
18
|
+
this.schema = schema;
|
|
19
|
+
}
|
|
20
|
+
transform(value) {
|
|
21
|
+
const result = this.schema.safeParse(value);
|
|
22
|
+
if (!result.success) {
|
|
23
|
+
const errors = result.error.issues.map((issue)=>({
|
|
24
|
+
path: issue.path.join('.'),
|
|
25
|
+
message: issue.message
|
|
26
|
+
}));
|
|
27
|
+
throw new BadRequestException({
|
|
28
|
+
message: 'Validation failed',
|
|
29
|
+
errors
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return result.data;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
ZodValidationPipe = _ts_decorate([
|
|
36
|
+
Injectable(),
|
|
37
|
+
_ts_metadata("design:type", Function),
|
|
38
|
+
_ts_metadata("design:paramtypes", [
|
|
39
|
+
typeof z === "undefined" || typeof z.ZodSchema === "undefined" ? Object : z.ZodSchema
|
|
40
|
+
])
|
|
41
|
+
], ZodValidationPipe);
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=validation.pipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/common/pipes/validation.pipe.ts"],"sourcesContent":["/**\n * Zod Validation Pipe\n *\n * Custom validation pipe that uses Zod schemas.\n */\n\nimport { BadRequestException, Injectable, PipeTransform } from '@nestjs/common';\nimport { z } from 'zod';\n\n@Injectable()\nexport class ZodValidationPipe implements PipeTransform {\n constructor(private schema: z.ZodSchema) {}\n\n transform(value: unknown) {\n const result = this.schema.safeParse(value);\n\n if (!result.success) {\n const errors = result.error.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n }));\n\n throw new BadRequestException({\n message: 'Validation failed',\n errors,\n });\n }\n\n return result.data;\n }\n}\n"],"names":["BadRequestException","Injectable","z","ZodValidationPipe","schema","transform","value","result","safeParse","success","errors","error","issues","map","issue","path","join","message","data"],"mappings":";;;;;;;;;AAAA;;;;CAIC,GAED,SAASA,mBAAmB,EAAEC,UAAU,QAAuB,iBAAiB;AAChF,SAASC,CAAC,QAAQ,MAAM;AAGxB,OAAO,MAAMC;IACX,YAAY,AAAQC,MAAmB,CAAE;aAArBA,SAAAA;IAAsB;IAE1CC,UAAUC,KAAc,EAAE;QACxB,MAAMC,SAAS,IAAI,CAACH,MAAM,CAACI,SAAS,CAACF;QAErC,IAAI,CAACC,OAAOE,OAAO,EAAE;YACnB,MAAMC,SAASH,OAAOI,KAAK,CAACC,MAAM,CAACC,GAAG,CAAC,CAACC,QAAW,CAAA;oBACjDC,MAAMD,MAAMC,IAAI,CAACC,IAAI,CAAC;oBACtBC,SAASH,MAAMG,OAAO;gBACxB,CAAA;YAEA,MAAM,IAAIjB,oBAAoB;gBAC5BiB,SAAS;gBACTP;YACF;QACF;QAEA,OAAOH,OAAOW,IAAI;IACpB;AACF;;;;;6CAnBgC,uCAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application configuration
|
|
3
|
+
*/ import { registerAs } from "@nestjs/config";
|
|
4
|
+
export default registerAs('app', ()=>({
|
|
5
|
+
nodeEnv: process.env.NODE_ENV || 'development',
|
|
6
|
+
port: Number.parseInt(process.env.PORT || '3001', 10),
|
|
7
|
+
corsOrigins: process.env.CORS_ORIGINS?.split(',') || [
|
|
8
|
+
'http://localhost:5173',
|
|
9
|
+
'http://localhost:3000'
|
|
10
|
+
],
|
|
11
|
+
logLevel: process.env.LOG_LEVEL || 'info'
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=app.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/config/app.config.ts"],"sourcesContent":["/**\n * Application configuration\n */\n\nimport { registerAs } from '@nestjs/config';\n\nexport default registerAs('app', () => ({\n nodeEnv: process.env.NODE_ENV || 'development',\n port: Number.parseInt(process.env.PORT || '3001', 10),\n corsOrigins: process.env.CORS_ORIGINS?.split(',') || [\n 'http://localhost:5173',\n 'http://localhost:3000',\n ],\n logLevel: process.env.LOG_LEVEL || 'info',\n}));\n"],"names":["registerAs","nodeEnv","process","env","NODE_ENV","port","Number","parseInt","PORT","corsOrigins","CORS_ORIGINS","split","logLevel","LOG_LEVEL"],"mappings":"AAAA;;CAEC,GAED,SAASA,UAAU,QAAQ,iBAAiB;AAE5C,eAAeA,WAAW,OAAO,IAAO,CAAA;QACtCC,SAASC,QAAQC,GAAG,CAACC,QAAQ,IAAI;QACjCC,MAAMC,OAAOC,QAAQ,CAACL,QAAQC,GAAG,CAACK,IAAI,IAAI,QAAQ;QAClDC,aAAaP,QAAQC,GAAG,CAACO,YAAY,EAAEC,MAAM,QAAQ;YACnD;YACA;SACD;QACDC,UAAUV,QAAQC,GAAG,CAACU,SAAS,IAAI;IACrC,CAAA,GAAI"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database configuration
|
|
3
|
+
*/ import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { registerAs } from "@nestjs/config";
|
|
6
|
+
export default registerAs('database', ()=>{
|
|
7
|
+
// Parse DATABASE_URL for path
|
|
8
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
9
|
+
// Default path if not set
|
|
10
|
+
const defaultPath = join(homedir(), '.local-mcp-gateway-data', 'local-mcp-gateway.db');
|
|
11
|
+
// Extract path from file: URL
|
|
12
|
+
let path = defaultPath;
|
|
13
|
+
if (databaseUrl?.startsWith('file:')) {
|
|
14
|
+
const filePath = databaseUrl.replace('file:', '');
|
|
15
|
+
if (!filePath.startsWith(':memory:')) {
|
|
16
|
+
// Handle relative paths (./dev.db)
|
|
17
|
+
if (filePath.startsWith('./')) {
|
|
18
|
+
path = join(process.cwd(), filePath.slice(2));
|
|
19
|
+
} else {
|
|
20
|
+
path = filePath;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
url: databaseUrl || `file:${defaultPath}`,
|
|
26
|
+
path
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=database.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/config/database.config.ts"],"sourcesContent":["/**\n * Database configuration\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { registerAs } from '@nestjs/config';\n\nexport default registerAs('database', () => {\n // Parse DATABASE_URL for path\n const databaseUrl = process.env.DATABASE_URL;\n\n // Default path if not set\n const defaultPath = join(homedir(), '.local-mcp-gateway-data', 'local-mcp-gateway.db');\n\n // Extract path from file: URL\n let path = defaultPath;\n if (databaseUrl?.startsWith('file:')) {\n const filePath = databaseUrl.replace('file:', '');\n if (!filePath.startsWith(':memory:')) {\n // Handle relative paths (./dev.db)\n if (filePath.startsWith('./')) {\n path = join(process.cwd(), filePath.slice(2));\n } else {\n path = filePath;\n }\n }\n }\n\n return {\n url: databaseUrl || `file:${defaultPath}`,\n path,\n };\n});\n"],"names":["homedir","join","registerAs","databaseUrl","process","env","DATABASE_URL","defaultPath","path","startsWith","filePath","replace","cwd","slice","url"],"mappings":"AAAA;;CAEC,GAED,SAASA,OAAO,QAAQ,UAAU;AAClC,SAASC,IAAI,QAAQ,YAAY;AACjC,SAASC,UAAU,QAAQ,iBAAiB;AAE5C,eAAeA,WAAW,YAAY;IACpC,8BAA8B;IAC9B,MAAMC,cAAcC,QAAQC,GAAG,CAACC,YAAY;IAE5C,0BAA0B;IAC1B,MAAMC,cAAcN,KAAKD,WAAW,2BAA2B;IAE/D,8BAA8B;IAC9B,IAAIQ,OAAOD;IACX,IAAIJ,aAAaM,WAAW,UAAU;QACpC,MAAMC,WAAWP,YAAYQ,OAAO,CAAC,SAAS;QAC9C,IAAI,CAACD,SAASD,UAAU,CAAC,aAAa;YACpC,mCAAmC;YACnC,IAAIC,SAASD,UAAU,CAAC,OAAO;gBAC7BD,OAAOP,KAAKG,QAAQQ,GAAG,IAAIF,SAASG,KAAK,CAAC;YAC5C,OAAO;gBACLL,OAAOE;YACT;QACF;IACF;IAEA,OAAO;QACLI,KAAKX,eAAe,CAAC,KAAK,EAAEI,aAAa;QACzCC;IACF;AACF,GAAG"}
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NestJS Application Bootstrap
|
|
3
|
+
*
|
|
4
|
+
* Entry point for the Local MCP Gateway backend.
|
|
5
|
+
* No authentication required - immediate access to all features.
|
|
6
|
+
*/ import { Logger, ValidationPipe } from "@nestjs/common";
|
|
7
|
+
import { ConfigService } from "@nestjs/config";
|
|
8
|
+
import { NestFactory } from "@nestjs/core";
|
|
9
|
+
import compression from "compression";
|
|
10
|
+
import helmet from "helmet";
|
|
11
|
+
import { AppModule } from "./app.module.js";
|
|
12
|
+
import { AllExceptionsFilter } from "./common/filters/all-exceptions.filter.js";
|
|
13
|
+
import { LoggingInterceptor } from "./common/interceptors/logging.interceptor.js";
|
|
14
|
+
async function bootstrap() {
|
|
15
|
+
const logger = new Logger('Bootstrap');
|
|
16
|
+
const app = await NestFactory.create(AppModule, {
|
|
17
|
+
logger: [
|
|
18
|
+
'error',
|
|
19
|
+
'warn',
|
|
20
|
+
'log',
|
|
21
|
+
'debug',
|
|
22
|
+
'verbose'
|
|
23
|
+
]
|
|
24
|
+
});
|
|
25
|
+
const configService = app.get(ConfigService);
|
|
26
|
+
// Security
|
|
27
|
+
app.use(helmet());
|
|
28
|
+
app.use(compression());
|
|
29
|
+
// CORS
|
|
30
|
+
const corsOrigins = configService.get('CORS_ORIGINS')?.split(',') || [
|
|
31
|
+
'http://localhost:5173',
|
|
32
|
+
'http://localhost:3000'
|
|
33
|
+
];
|
|
34
|
+
app.enableCors({
|
|
35
|
+
origin: corsOrigins,
|
|
36
|
+
credentials: true,
|
|
37
|
+
methods: [
|
|
38
|
+
'GET',
|
|
39
|
+
'POST',
|
|
40
|
+
'PUT',
|
|
41
|
+
'DELETE',
|
|
42
|
+
'PATCH',
|
|
43
|
+
'OPTIONS'
|
|
44
|
+
]
|
|
45
|
+
});
|
|
46
|
+
// Global prefix
|
|
47
|
+
app.setGlobalPrefix('api');
|
|
48
|
+
// Global pipes
|
|
49
|
+
app.useGlobalPipes(new ValidationPipe({
|
|
50
|
+
whitelist: true,
|
|
51
|
+
forbidNonWhitelisted: true,
|
|
52
|
+
transform: true,
|
|
53
|
+
transformOptions: {
|
|
54
|
+
enableImplicitConversion: true
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
// Global filters
|
|
58
|
+
app.useGlobalFilters(new AllExceptionsFilter());
|
|
59
|
+
// Global interceptors
|
|
60
|
+
app.useGlobalInterceptors(new LoggingInterceptor());
|
|
61
|
+
const port = configService.get('PORT') || 3001;
|
|
62
|
+
await app.listen(port);
|
|
63
|
+
logger.log(`Application is running on: http://localhost:${port}`);
|
|
64
|
+
logger.log(`API available at: http://localhost:${port}/api`);
|
|
65
|
+
}
|
|
66
|
+
bootstrap();
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/main.ts"],"sourcesContent":["/**\n * NestJS Application Bootstrap\n *\n * Entry point for the Local MCP Gateway backend.\n * No authentication required - immediate access to all features.\n */\n\nimport { Logger, ValidationPipe } from '@nestjs/common';\nimport { ConfigService } from '@nestjs/config';\nimport { NestFactory } from '@nestjs/core';\nimport compression from 'compression';\nimport helmet from 'helmet';\nimport { AppModule } from './app.module.js';\nimport { AllExceptionsFilter } from './common/filters/all-exceptions.filter.js';\nimport { LoggingInterceptor } from './common/interceptors/logging.interceptor.js';\n\nasync function bootstrap() {\n const logger = new Logger('Bootstrap');\n const app = await NestFactory.create(AppModule, {\n logger: ['error', 'warn', 'log', 'debug', 'verbose'],\n });\n\n const configService = app.get(ConfigService);\n\n // Security\n app.use(helmet());\n app.use(compression());\n\n // CORS\n const corsOrigins = configService.get<string>('CORS_ORIGINS')?.split(',') || [\n 'http://localhost:5173',\n 'http://localhost:3000',\n ];\n app.enableCors({\n origin: corsOrigins,\n credentials: true,\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],\n });\n\n // Global prefix\n app.setGlobalPrefix('api');\n\n // Global pipes\n app.useGlobalPipes(\n new ValidationPipe({\n whitelist: true,\n forbidNonWhitelisted: true,\n transform: true,\n transformOptions: { enableImplicitConversion: true },\n })\n );\n\n // Global filters\n app.useGlobalFilters(new AllExceptionsFilter());\n\n // Global interceptors\n app.useGlobalInterceptors(new LoggingInterceptor());\n\n const port = configService.get<number>('PORT') || 3001;\n await app.listen(port);\n\n logger.log(`Application is running on: http://localhost:${port}`);\n logger.log(`API available at: http://localhost:${port}/api`);\n}\n\nbootstrap();\n"],"names":["Logger","ValidationPipe","ConfigService","NestFactory","compression","helmet","AppModule","AllExceptionsFilter","LoggingInterceptor","bootstrap","logger","app","create","configService","get","use","corsOrigins","split","enableCors","origin","credentials","methods","setGlobalPrefix","useGlobalPipes","whitelist","forbidNonWhitelisted","transform","transformOptions","enableImplicitConversion","useGlobalFilters","useGlobalInterceptors","port","listen","log"],"mappings":"AAAA;;;;;CAKC,GAED,SAASA,MAAM,EAAEC,cAAc,QAAQ,iBAAiB;AACxD,SAASC,aAAa,QAAQ,iBAAiB;AAC/C,SAASC,WAAW,QAAQ,eAAe;AAC3C,OAAOC,iBAAiB,cAAc;AACtC,OAAOC,YAAY,SAAS;AAC5B,SAASC,SAAS,QAAQ,kBAAkB;AAC5C,SAASC,mBAAmB,QAAQ,4CAA4C;AAChF,SAASC,kBAAkB,QAAQ,+CAA+C;AAElF,eAAeC;IACb,MAAMC,SAAS,IAAIV,OAAO;IAC1B,MAAMW,MAAM,MAAMR,YAAYS,MAAM,CAACN,WAAW;QAC9CI,QAAQ;YAAC;YAAS;YAAQ;YAAO;YAAS;SAAU;IACtD;IAEA,MAAMG,gBAAgBF,IAAIG,GAAG,CAACZ;IAE9B,WAAW;IACXS,IAAII,GAAG,CAACV;IACRM,IAAII,GAAG,CAACX;IAER,OAAO;IACP,MAAMY,cAAcH,cAAcC,GAAG,CAAS,iBAAiBG,MAAM,QAAQ;QAC3E;QACA;KACD;IACDN,IAAIO,UAAU,CAAC;QACbC,QAAQH;QACRI,aAAa;QACbC,SAAS;YAAC;YAAO;YAAQ;YAAO;YAAU;YAAS;SAAU;IAC/D;IAEA,gBAAgB;IAChBV,IAAIW,eAAe,CAAC;IAEpB,eAAe;IACfX,IAAIY,cAAc,CAChB,IAAItB,eAAe;QACjBuB,WAAW;QACXC,sBAAsB;QACtBC,WAAW;QACXC,kBAAkB;YAAEC,0BAA0B;QAAK;IACrD;IAGF,iBAAiB;IACjBjB,IAAIkB,gBAAgB,CAAC,IAAItB;IAEzB,sBAAsB;IACtBI,IAAImB,qBAAqB,CAAC,IAAItB;IAE9B,MAAMuB,OAAOlB,cAAcC,GAAG,CAAS,WAAW;IAClD,MAAMH,IAAIqB,MAAM,CAACD;IAEjBrB,OAAOuB,GAAG,CAAC,CAAC,4CAA4C,EAAEF,MAAM;IAChErB,OAAOuB,GAAG,CAAC,CAAC,mCAAmC,EAAEF,KAAK,IAAI,CAAC;AAC7D;AAEAtB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Database Module
|
|
9
|
+
*
|
|
10
|
+
* Global module providing Prisma client for database operations.
|
|
11
|
+
*/ import { Global, Module } from "@nestjs/common";
|
|
12
|
+
import { PrismaService } from "./prisma.service.js";
|
|
13
|
+
export class DatabaseModule {
|
|
14
|
+
}
|
|
15
|
+
DatabaseModule = _ts_decorate([
|
|
16
|
+
Global(),
|
|
17
|
+
Module({
|
|
18
|
+
providers: [
|
|
19
|
+
PrismaService
|
|
20
|
+
],
|
|
21
|
+
exports: [
|
|
22
|
+
PrismaService
|
|
23
|
+
]
|
|
24
|
+
})
|
|
25
|
+
], DatabaseModule);
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=database.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/database/database.module.ts"],"sourcesContent":["/**\n * Database Module\n *\n * Global module providing Prisma client for database operations.\n */\n\nimport { Global, Module } from '@nestjs/common';\nimport { PrismaService } from './prisma.service.js';\n\n@Global()\n@Module({\n providers: [PrismaService],\n exports: [PrismaService],\n})\nexport class DatabaseModule {}\n"],"names":["Global","Module","PrismaService","DatabaseModule","providers","exports"],"mappings":";;;;;;AAAA;;;;CAIC,GAED,SAASA,MAAM,EAAEC,MAAM,QAAQ,iBAAiB;AAChD,SAASC,aAAa,QAAQ,sBAAsB;AAOpD,OAAO,MAAMC;AAAgB;;;;QAH3BC,WAAW;YAACF;SAAc;QAC1BG,SAAS;YAACH;SAAc"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
function _ts_metadata(k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Prisma Service
|
|
12
|
+
*
|
|
13
|
+
* NestJS service wrapping Prisma Client with lifecycle management.
|
|
14
|
+
*/ import { createPrismaAdapter } from "@dxheroes/local-mcp-database";
|
|
15
|
+
import { PrismaClient } from "@dxheroes/local-mcp-database/generated/prisma";
|
|
16
|
+
import { Injectable, Logger } from "@nestjs/common";
|
|
17
|
+
export class PrismaService extends PrismaClient {
|
|
18
|
+
constructor(){
|
|
19
|
+
super({
|
|
20
|
+
adapter: createPrismaAdapter(),
|
|
21
|
+
log: process.env.NODE_ENV === 'development' ? [
|
|
22
|
+
{
|
|
23
|
+
emit: 'event',
|
|
24
|
+
level: 'query'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
emit: 'stdout',
|
|
28
|
+
level: 'info'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
emit: 'stdout',
|
|
32
|
+
level: 'warn'
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
emit: 'stdout',
|
|
36
|
+
level: 'error'
|
|
37
|
+
}
|
|
38
|
+
] : [
|
|
39
|
+
{
|
|
40
|
+
emit: 'stdout',
|
|
41
|
+
level: 'error'
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}), this.logger = new Logger(PrismaService.name);
|
|
45
|
+
}
|
|
46
|
+
async onModuleInit() {
|
|
47
|
+
this.logger.log('Connecting to database...');
|
|
48
|
+
await this.$connect();
|
|
49
|
+
this.logger.log('Database connected');
|
|
50
|
+
// Seed default data on first run
|
|
51
|
+
await this.seedDefaultData();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Seed default data if database is empty (first run only)
|
|
55
|
+
* Only seeds if no profiles exist - respects user data
|
|
56
|
+
*/ async seedDefaultData() {
|
|
57
|
+
// Check if any profiles exist - if so, user has data, don't seed
|
|
58
|
+
const profileCount = await this.profile.count();
|
|
59
|
+
if (profileCount > 0) {
|
|
60
|
+
this.logger.debug('Database has existing data, skipping seed');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.logger.log('First run detected, seeding default data...');
|
|
64
|
+
// Create default profile
|
|
65
|
+
const defaultProfile = await this.profile.create({
|
|
66
|
+
data: {
|
|
67
|
+
name: 'default',
|
|
68
|
+
description: 'Default MCP profile for general use'
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
this.logger.log(`Created default profile: ${defaultProfile.id}`);
|
|
72
|
+
// Create Context7 MCP server
|
|
73
|
+
const context7 = await this.mcpServer.create({
|
|
74
|
+
data: {
|
|
75
|
+
name: 'Context7',
|
|
76
|
+
type: 'remote_http',
|
|
77
|
+
config: JSON.stringify({
|
|
78
|
+
url: 'https://mcp.context7.com/mcp'
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
this.logger.log(`Created Context7 MCP server: ${context7.id}`);
|
|
83
|
+
// Link Context7 to default profile
|
|
84
|
+
await this.profileMcpServer.create({
|
|
85
|
+
data: {
|
|
86
|
+
profileId: defaultProfile.id,
|
|
87
|
+
mcpServerId: context7.id,
|
|
88
|
+
order: 0
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
this.logger.log('Linked Context7 to default profile');
|
|
92
|
+
this.logger.log('Default data seeding complete');
|
|
93
|
+
}
|
|
94
|
+
async onModuleDestroy() {
|
|
95
|
+
this.logger.log('Disconnecting from database...');
|
|
96
|
+
await this.$disconnect();
|
|
97
|
+
this.logger.log('Database disconnected');
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Clean database (for testing only)
|
|
101
|
+
*/ async cleanDatabase() {
|
|
102
|
+
if (process.env.NODE_ENV !== 'test') {
|
|
103
|
+
throw new Error('cleanDatabase can only be called in test environment');
|
|
104
|
+
}
|
|
105
|
+
const tablenames = await this.$queryRaw`
|
|
106
|
+
SELECT name FROM sqlite_master
|
|
107
|
+
WHERE type='table'
|
|
108
|
+
AND name NOT LIKE '_prisma%'
|
|
109
|
+
AND name NOT LIKE 'sqlite%'
|
|
110
|
+
`;
|
|
111
|
+
for (const { name } of tablenames){
|
|
112
|
+
await this.$executeRawUnsafe(`DELETE FROM "${name}"`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
PrismaService = _ts_decorate([
|
|
117
|
+
Injectable(),
|
|
118
|
+
_ts_metadata("design:type", Function),
|
|
119
|
+
_ts_metadata("design:paramtypes", [])
|
|
120
|
+
], PrismaService);
|
|
121
|
+
|
|
122
|
+
//# sourceMappingURL=prisma.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/database/prisma.service.ts"],"sourcesContent":["/**\n * Prisma Service\n *\n * NestJS service wrapping Prisma Client with lifecycle management.\n */\n\nimport { createPrismaAdapter } from '@dxheroes/local-mcp-database';\nimport { PrismaClient } from '@dxheroes/local-mcp-database/generated/prisma';\nimport { Injectable, Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';\n\n@Injectable()\nexport class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger(PrismaService.name);\n\n constructor() {\n super({\n adapter: createPrismaAdapter(),\n log:\n process.env.NODE_ENV === 'development'\n ? [\n { emit: 'event', level: 'query' },\n { emit: 'stdout', level: 'info' },\n { emit: 'stdout', level: 'warn' },\n { emit: 'stdout', level: 'error' },\n ]\n : [{ emit: 'stdout', level: 'error' }],\n });\n }\n\n async onModuleInit() {\n this.logger.log('Connecting to database...');\n await this.$connect();\n this.logger.log('Database connected');\n\n // Seed default data on first run\n await this.seedDefaultData();\n }\n\n /**\n * Seed default data if database is empty (first run only)\n * Only seeds if no profiles exist - respects user data\n */\n private async seedDefaultData() {\n // Check if any profiles exist - if so, user has data, don't seed\n const profileCount = await this.profile.count();\n if (profileCount > 0) {\n this.logger.debug('Database has existing data, skipping seed');\n return;\n }\n\n this.logger.log('First run detected, seeding default data...');\n\n // Create default profile\n const defaultProfile = await this.profile.create({\n data: {\n name: 'default',\n description: 'Default MCP profile for general use',\n },\n });\n this.logger.log(`Created default profile: ${defaultProfile.id}`);\n\n // Create Context7 MCP server\n const context7 = await this.mcpServer.create({\n data: {\n name: 'Context7',\n type: 'remote_http',\n config: JSON.stringify({ url: 'https://mcp.context7.com/mcp' }),\n },\n });\n this.logger.log(`Created Context7 MCP server: ${context7.id}`);\n\n // Link Context7 to default profile\n await this.profileMcpServer.create({\n data: {\n profileId: defaultProfile.id,\n mcpServerId: context7.id,\n order: 0,\n },\n });\n this.logger.log('Linked Context7 to default profile');\n\n this.logger.log('Default data seeding complete');\n }\n\n async onModuleDestroy() {\n this.logger.log('Disconnecting from database...');\n await this.$disconnect();\n this.logger.log('Database disconnected');\n }\n\n /**\n * Clean database (for testing only)\n */\n async cleanDatabase() {\n if (process.env.NODE_ENV !== 'test') {\n throw new Error('cleanDatabase can only be called in test environment');\n }\n\n const tablenames = await this.$queryRaw<Array<{ name: string }>>`\n SELECT name FROM sqlite_master\n WHERE type='table'\n AND name NOT LIKE '_prisma%'\n AND name NOT LIKE 'sqlite%'\n `;\n\n for (const { name } of tablenames) {\n await this.$executeRawUnsafe(`DELETE FROM \"${name}\"`);\n }\n }\n}\n"],"names":["createPrismaAdapter","PrismaClient","Injectable","Logger","PrismaService","adapter","log","process","env","NODE_ENV","emit","level","logger","name","onModuleInit","$connect","seedDefaultData","profileCount","profile","count","debug","defaultProfile","create","data","description","id","context7","mcpServer","type","config","JSON","stringify","url","profileMcpServer","profileId","mcpServerId","order","onModuleDestroy","$disconnect","cleanDatabase","Error","tablenames","$queryRaw","$executeRawUnsafe"],"mappings":";;;;;;;;;AAAA;;;;CAIC,GAED,SAASA,mBAAmB,QAAQ,+BAA+B;AACnE,SAASC,YAAY,QAAQ,gDAAgD;AAC7E,SAASC,UAAU,EAAEC,MAAM,QAAuC,iBAAiB;AAGnF,OAAO,MAAMC,sBAAsBH;IAGjC,aAAc;QACZ,KAAK,CAAC;YACJI,SAASL;YACTM,KACEC,QAAQC,GAAG,CAACC,QAAQ,KAAK,gBACrB;gBACE;oBAAEC,MAAM;oBAASC,OAAO;gBAAQ;gBAChC;oBAAED,MAAM;oBAAUC,OAAO;gBAAO;gBAChC;oBAAED,MAAM;oBAAUC,OAAO;gBAAO;gBAChC;oBAAED,MAAM;oBAAUC,OAAO;gBAAQ;aAClC,GACD;gBAAC;oBAAED,MAAM;oBAAUC,OAAO;gBAAQ;aAAE;QAC5C,SAdeC,SAAS,IAAIT,OAAOC,cAAcS,IAAI;IAevD;IAEA,MAAMC,eAAe;QACnB,IAAI,CAACF,MAAM,CAACN,GAAG,CAAC;QAChB,MAAM,IAAI,CAACS,QAAQ;QACnB,IAAI,CAACH,MAAM,CAACN,GAAG,CAAC;QAEhB,iCAAiC;QACjC,MAAM,IAAI,CAACU,eAAe;IAC5B;IAEA;;;GAGC,GACD,MAAcA,kBAAkB;QAC9B,iEAAiE;QACjE,MAAMC,eAAe,MAAM,IAAI,CAACC,OAAO,CAACC,KAAK;QAC7C,IAAIF,eAAe,GAAG;YACpB,IAAI,CAACL,MAAM,CAACQ,KAAK,CAAC;YAClB;QACF;QAEA,IAAI,CAACR,MAAM,CAACN,GAAG,CAAC;QAEhB,yBAAyB;QACzB,MAAMe,iBAAiB,MAAM,IAAI,CAACH,OAAO,CAACI,MAAM,CAAC;YAC/CC,MAAM;gBACJV,MAAM;gBACNW,aAAa;YACf;QACF;QACA,IAAI,CAACZ,MAAM,CAACN,GAAG,CAAC,CAAC,yBAAyB,EAAEe,eAAeI,EAAE,EAAE;QAE/D,6BAA6B;QAC7B,MAAMC,WAAW,MAAM,IAAI,CAACC,SAAS,CAACL,MAAM,CAAC;YAC3CC,MAAM;gBACJV,MAAM;gBACNe,MAAM;gBACNC,QAAQC,KAAKC,SAAS,CAAC;oBAAEC,KAAK;gBAA+B;YAC/D;QACF;QACA,IAAI,CAACpB,MAAM,CAACN,GAAG,CAAC,CAAC,6BAA6B,EAAEoB,SAASD,EAAE,EAAE;QAE7D,mCAAmC;QACnC,MAAM,IAAI,CAACQ,gBAAgB,CAACX,MAAM,CAAC;YACjCC,MAAM;gBACJW,WAAWb,eAAeI,EAAE;gBAC5BU,aAAaT,SAASD,EAAE;gBACxBW,OAAO;YACT;QACF;QACA,IAAI,CAACxB,MAAM,CAACN,GAAG,CAAC;QAEhB,IAAI,CAACM,MAAM,CAACN,GAAG,CAAC;IAClB;IAEA,MAAM+B,kBAAkB;QACtB,IAAI,CAACzB,MAAM,CAACN,GAAG,CAAC;QAChB,MAAM,IAAI,CAACgC,WAAW;QACtB,IAAI,CAAC1B,MAAM,CAACN,GAAG,CAAC;IAClB;IAEA;;GAEC,GACD,MAAMiC,gBAAgB;QACpB,IAAIhC,QAAQC,GAAG,CAACC,QAAQ,KAAK,QAAQ;YACnC,MAAM,IAAI+B,MAAM;QAClB;QAEA,MAAMC,aAAa,MAAM,IAAI,CAACC,SAAS,AAAyB,CAAC;;;;;IAKjE,CAAC;QAED,KAAK,MAAM,EAAE7B,IAAI,EAAE,IAAI4B,WAAY;YACjC,MAAM,IAAI,CAACE,iBAAiB,CAAC,CAAC,aAAa,EAAE9B,KAAK,CAAC,CAAC;QACtD;IACF;AACF"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
function _ts_metadata(k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
}
|
|
10
|
+
function _ts_param(paramIndex, decorator) {
|
|
11
|
+
return function(target, key) {
|
|
12
|
+
decorator(target, key, paramIndex);
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Debug Controller
|
|
17
|
+
*
|
|
18
|
+
* REST API endpoints for debug log management.
|
|
19
|
+
*/ import { Controller, Delete, Get, HttpCode, HttpStatus, Query } from "@nestjs/common";
|
|
20
|
+
import { DebugService } from "./debug.service.js";
|
|
21
|
+
export class DebugController {
|
|
22
|
+
constructor(debugService){
|
|
23
|
+
this.debugService = debugService;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get debug logs with optional filters
|
|
27
|
+
*/ async getLogs(profileId, mcpServerId, status, since, until, limit, offset) {
|
|
28
|
+
const filter = {
|
|
29
|
+
profileId,
|
|
30
|
+
mcpServerId,
|
|
31
|
+
status,
|
|
32
|
+
since: since ? new Date(since) : undefined,
|
|
33
|
+
until: until ? new Date(until) : undefined
|
|
34
|
+
};
|
|
35
|
+
return this.debugService.getLogs(filter, limit ? Number.parseInt(limit, 10) : 100, offset ? Number.parseInt(offset, 10) : 0);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Clear debug logs
|
|
39
|
+
*/ async clearLogs(profileId, mcpServerId) {
|
|
40
|
+
await this.debugService.clearLogs({
|
|
41
|
+
profileId,
|
|
42
|
+
mcpServerId
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
_ts_decorate([
|
|
47
|
+
Get('logs'),
|
|
48
|
+
_ts_param(0, Query('profileId')),
|
|
49
|
+
_ts_param(1, Query('mcpServerId')),
|
|
50
|
+
_ts_param(2, Query('status')),
|
|
51
|
+
_ts_param(3, Query('since')),
|
|
52
|
+
_ts_param(4, Query('until')),
|
|
53
|
+
_ts_param(5, Query('limit')),
|
|
54
|
+
_ts_param(6, Query('offset')),
|
|
55
|
+
_ts_metadata("design:type", Function),
|
|
56
|
+
_ts_metadata("design:paramtypes", [
|
|
57
|
+
String,
|
|
58
|
+
String,
|
|
59
|
+
String,
|
|
60
|
+
String,
|
|
61
|
+
String,
|
|
62
|
+
String,
|
|
63
|
+
String
|
|
64
|
+
]),
|
|
65
|
+
_ts_metadata("design:returntype", Promise)
|
|
66
|
+
], DebugController.prototype, "getLogs", null);
|
|
67
|
+
_ts_decorate([
|
|
68
|
+
Delete('logs'),
|
|
69
|
+
HttpCode(HttpStatus.NO_CONTENT),
|
|
70
|
+
_ts_param(0, Query('profileId')),
|
|
71
|
+
_ts_param(1, Query('mcpServerId')),
|
|
72
|
+
_ts_metadata("design:type", Function),
|
|
73
|
+
_ts_metadata("design:paramtypes", [
|
|
74
|
+
String,
|
|
75
|
+
String
|
|
76
|
+
]),
|
|
77
|
+
_ts_metadata("design:returntype", Promise)
|
|
78
|
+
], DebugController.prototype, "clearLogs", null);
|
|
79
|
+
DebugController = _ts_decorate([
|
|
80
|
+
Controller('debug'),
|
|
81
|
+
_ts_metadata("design:type", Function),
|
|
82
|
+
_ts_metadata("design:paramtypes", [
|
|
83
|
+
typeof DebugService === "undefined" ? Object : DebugService
|
|
84
|
+
])
|
|
85
|
+
], DebugController);
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=debug.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/debug/debug.controller.ts"],"sourcesContent":["/**\n * Debug Controller\n *\n * REST API endpoints for debug log management.\n */\n\nimport { Controller, Delete, Get, HttpCode, HttpStatus, Query } from '@nestjs/common';\nimport { DebugService } from './debug.service.js';\n\n@Controller('debug')\nexport class DebugController {\n constructor(private readonly debugService: DebugService) {}\n\n /**\n * Get debug logs with optional filters\n */\n @Get('logs')\n async getLogs(\n @Query('profileId') profileId?: string,\n @Query('mcpServerId') mcpServerId?: string,\n @Query('status') status?: 'pending' | 'success' | 'error',\n @Query('since') since?: string,\n @Query('until') until?: string,\n @Query('limit') limit?: string,\n @Query('offset') offset?: string\n ) {\n const filter = {\n profileId,\n mcpServerId,\n status,\n since: since ? new Date(since) : undefined,\n until: until ? new Date(until) : undefined,\n };\n\n return this.debugService.getLogs(\n filter,\n limit ? Number.parseInt(limit, 10) : 100,\n offset ? Number.parseInt(offset, 10) : 0\n );\n }\n\n /**\n * Clear debug logs\n */\n @Delete('logs')\n @HttpCode(HttpStatus.NO_CONTENT)\n async clearLogs(\n @Query('profileId') profileId?: string,\n @Query('mcpServerId') mcpServerId?: string\n ) {\n await this.debugService.clearLogs({ profileId, mcpServerId });\n }\n}\n"],"names":["Controller","Delete","Get","HttpCode","HttpStatus","Query","DebugService","DebugController","debugService","getLogs","profileId","mcpServerId","status","since","until","limit","offset","filter","Date","undefined","Number","parseInt","clearLogs","NO_CONTENT"],"mappings":";;;;;;;;;;;;;;AAAA;;;;CAIC,GAED,SAASA,UAAU,EAAEC,MAAM,EAAEC,GAAG,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,KAAK,QAAQ,iBAAiB;AACtF,SAASC,YAAY,QAAQ,qBAAqB;AAGlD,OAAO,MAAMC;IACX,YAAY,AAAiBC,YAA0B,CAAE;aAA5BA,eAAAA;IAA6B;IAE1D;;GAEC,GACD,MACMC,QACJ,AAAoBC,SAAkB,EACtC,AAAsBC,WAAoB,EAC1C,AAAiBC,MAAwC,EACzD,AAAgBC,KAAc,EAC9B,AAAgBC,KAAc,EAC9B,AAAgBC,KAAc,EAC9B,AAAiBC,MAAe,EAChC;QACA,MAAMC,SAAS;YACbP;YACAC;YACAC;YACAC,OAAOA,QAAQ,IAAIK,KAAKL,SAASM;YACjCL,OAAOA,QAAQ,IAAII,KAAKJ,SAASK;QACnC;QAEA,OAAO,IAAI,CAACX,YAAY,CAACC,OAAO,CAC9BQ,QACAF,QAAQK,OAAOC,QAAQ,CAACN,OAAO,MAAM,KACrCC,SAASI,OAAOC,QAAQ,CAACL,QAAQ,MAAM;IAE3C;IAEA;;GAEC,GACD,MAEMM,UACJ,AAAoBZ,SAAkB,EACtC,AAAsBC,WAAoB,EAC1C;QACA,MAAM,IAAI,CAACH,YAAY,CAACc,SAAS,CAAC;YAAEZ;YAAWC;QAAY;IAC7D;AACF;;;;;;;;;;;;;;;;;;;;;;;;wBAPuBY"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Debug Module
|
|
9
|
+
*
|
|
10
|
+
* Debug logging endpoints for MCP traffic inspection.
|
|
11
|
+
*/ import { Module } from "@nestjs/common";
|
|
12
|
+
import { DebugController } from "./debug.controller.js";
|
|
13
|
+
import { DebugService } from "./debug.service.js";
|
|
14
|
+
export class DebugModule {
|
|
15
|
+
}
|
|
16
|
+
DebugModule = _ts_decorate([
|
|
17
|
+
Module({
|
|
18
|
+
controllers: [
|
|
19
|
+
DebugController
|
|
20
|
+
],
|
|
21
|
+
providers: [
|
|
22
|
+
DebugService
|
|
23
|
+
],
|
|
24
|
+
exports: [
|
|
25
|
+
DebugService
|
|
26
|
+
]
|
|
27
|
+
})
|
|
28
|
+
], DebugModule);
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=debug.module.js.map
|