@cinnabun/core 0.0.1 → 0.0.2
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/dist/__tests__/autowired.test.d.ts +1 -0
- package/dist/__tests__/autowired.test.js +109 -0
- package/dist/__tests__/autowired.test.js.map +1 -0
- package/dist/__tests__/cinnabun-application.test.d.ts +1 -0
- package/dist/__tests__/cinnabun-application.test.js +96 -0
- package/dist/__tests__/cinnabun-application.test.js.map +1 -0
- package/dist/__tests__/cinnabun-factory.test.d.ts +1 -0
- package/dist/__tests__/cinnabun-factory.test.js +269 -0
- package/dist/__tests__/cinnabun-factory.test.js.map +1 -0
- package/dist/__tests__/circular-dependency.test.d.ts +1 -0
- package/dist/__tests__/circular-dependency.test.js +318 -0
- package/dist/__tests__/circular-dependency.test.js.map +1 -0
- package/dist/__tests__/compression.test.d.ts +1 -0
- package/dist/__tests__/compression.test.js +459 -0
- package/dist/__tests__/compression.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +1 -0
- package/dist/__tests__/config.test.js +86 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/cors.test.d.ts +1 -0
- package/dist/__tests__/cors.test.js +575 -0
- package/dist/__tests__/cors.test.js.map +1 -0
- package/dist/__tests__/env-config.test.d.ts +1 -0
- package/dist/__tests__/env-config.test.js +367 -0
- package/dist/__tests__/env-config.test.js.map +1 -0
- package/dist/__tests__/exception.test.d.ts +1 -0
- package/dist/__tests__/exception.test.js +207 -0
- package/dist/__tests__/exception.test.js.map +1 -0
- package/dist/__tests__/guards-interceptors.test.d.ts +1 -0
- package/dist/__tests__/guards-interceptors.test.js +660 -0
- package/dist/__tests__/guards-interceptors.test.js.map +1 -0
- package/dist/__tests__/health-check.test.d.ts +1 -0
- package/dist/__tests__/health-check.test.js +240 -0
- package/dist/__tests__/health-check.test.js.map +1 -0
- package/dist/__tests__/http.test.d.ts +1 -0
- package/dist/__tests__/http.test.js +629 -0
- package/dist/__tests__/http.test.js.map +1 -0
- package/dist/__tests__/integration/e2e.test.d.ts +1 -0
- package/dist/__tests__/integration/e2e.test.js +192 -0
- package/dist/__tests__/integration/e2e.test.js.map +1 -0
- package/dist/__tests__/integration/performance.bench.d.ts +1 -0
- package/dist/__tests__/integration/performance.bench.js +129 -0
- package/dist/__tests__/integration/performance.bench.js.map +1 -0
- package/dist/__tests__/integration/validation.test.d.ts +1 -0
- package/dist/__tests__/integration/validation.test.js +133 -0
- package/dist/__tests__/integration/validation.test.js.map +1 -0
- package/dist/__tests__/lifecycle-management.test.d.ts +1 -0
- package/dist/__tests__/lifecycle-management.test.js +688 -0
- package/dist/__tests__/lifecycle-management.test.js.map +1 -0
- package/dist/__tests__/lifecycle.test.d.ts +1 -0
- package/dist/__tests__/lifecycle.test.js +196 -0
- package/dist/__tests__/lifecycle.test.js.map +1 -0
- package/dist/__tests__/logger.test.d.ts +1 -0
- package/dist/__tests__/logger.test.js +109 -0
- package/dist/__tests__/logger.test.js.map +1 -0
- package/dist/__tests__/middleware.test.d.ts +1 -0
- package/dist/__tests__/middleware.test.js +329 -0
- package/dist/__tests__/middleware.test.js.map +1 -0
- package/dist/__tests__/module.test.d.ts +1 -0
- package/dist/__tests__/module.test.js +280 -0
- package/dist/__tests__/module.test.js.map +1 -0
- package/dist/__tests__/plugin.test.d.ts +1 -0
- package/dist/__tests__/plugin.test.js +283 -0
- package/dist/__tests__/plugin.test.js.map +1 -0
- package/dist/__tests__/request-logger.test.d.ts +1 -0
- package/dist/__tests__/request-logger.test.js +342 -0
- package/dist/__tests__/request-logger.test.js.map +1 -0
- package/dist/__tests__/request-mapping.test.d.ts +1 -0
- package/dist/__tests__/request-mapping.test.js +201 -0
- package/dist/__tests__/request-mapping.test.js.map +1 -0
- package/dist/__tests__/routes.test.d.ts +1 -0
- package/dist/__tests__/routes.test.js +119 -0
- package/dist/__tests__/routes.test.js.map +1 -0
- package/dist/__tests__/scan-fixtures/controllers/hello.controller.d.ts +4 -0
- package/dist/__tests__/scan-fixtures/controllers/hello.controller.js +28 -0
- package/dist/__tests__/scan-fixtures/controllers/hello.controller.js.map +1 -0
- package/dist/__tests__/scan-fixtures/modules/feature.module.d.ts +6 -0
- package/dist/__tests__/scan-fixtures/modules/feature.module.js +28 -0
- package/dist/__tests__/scan-fixtures/modules/feature.module.js.map +1 -0
- package/dist/__tests__/scan-fixtures/services/greeting.service.d.ts +4 -0
- package/dist/__tests__/scan-fixtures/services/greeting.service.js +18 -0
- package/dist/__tests__/scan-fixtures/services/greeting.service.js.map +1 -0
- package/dist/__tests__/scanner.test.d.ts +1 -0
- package/dist/__tests__/scanner.test.js +49 -0
- package/dist/__tests__/scanner.test.js.map +1 -0
- package/dist/__tests__/validation.test.d.ts +1 -0
- package/dist/__tests__/validation.test.js +561 -0
- package/dist/__tests__/validation.test.js.map +1 -0
- package/dist/__tests__/websocket-auth.test.d.ts +1 -0
- package/dist/__tests__/websocket-auth.test.js +431 -0
- package/dist/__tests__/websocket-auth.test.js.map +1 -0
- package/dist/__tests__/websocket-decorators.test.d.ts +1 -0
- package/dist/__tests__/websocket-decorators.test.js +173 -0
- package/dist/__tests__/websocket-decorators.test.js.map +1 -0
- package/dist/__tests__/websocket-validation.test.d.ts +1 -0
- package/dist/__tests__/websocket-validation.test.js +827 -0
- package/dist/__tests__/websocket-validation.test.js.map +1 -0
- package/dist/__tests__/websocket.test.d.ts +1 -0
- package/dist/__tests__/websocket.test.js +415 -0
- package/dist/__tests__/websocket.test.js.map +1 -0
- package/dist/config/config.module.d.ts +2 -0
- package/dist/config/config.module.js +18 -0
- package/dist/config/config.module.js.map +1 -0
- package/dist/config/config.service.d.ts +15 -0
- package/dist/config/config.service.js +58 -0
- package/dist/config/config.service.js.map +1 -0
- package/dist/config/schemas.d.ts +107 -0
- package/dist/config/schemas.js +87 -0
- package/dist/config/schemas.js.map +1 -0
- package/dist/core/app.d.ts +44 -0
- package/dist/core/app.js +178 -0
- package/dist/core/app.js.map +1 -0
- package/dist/core/cinnabun-factory.d.ts +5 -0
- package/dist/core/cinnabun-factory.js +130 -0
- package/dist/core/cinnabun-factory.js.map +1 -0
- package/dist/core/config-loader.d.ts +2 -0
- package/dist/core/config-loader.js +76 -0
- package/dist/core/config-loader.js.map +1 -0
- package/dist/core/config.d.ts +12 -0
- package/dist/core/config.js +27 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/container.d.ts +10 -0
- package/dist/core/container.js +82 -0
- package/dist/core/container.js.map +1 -0
- package/dist/core/dependency-validator.d.ts +12 -0
- package/dist/core/dependency-validator.js +76 -0
- package/dist/core/dependency-validator.js.map +1 -0
- package/dist/core/guard.d.ts +3 -0
- package/dist/core/guard.js +2 -0
- package/dist/core/guard.js.map +1 -0
- package/dist/core/interceptor.d.ts +4 -0
- package/dist/core/interceptor.js +2 -0
- package/dist/core/interceptor.js.map +1 -0
- package/dist/core/logger.d.ts +15 -0
- package/dist/core/logger.js +71 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/module-resolver.d.ts +6 -0
- package/dist/core/module-resolver.js +67 -0
- package/dist/core/module-resolver.js.map +1 -0
- package/dist/core/plugin.d.ts +12 -0
- package/dist/core/plugin.js +2 -0
- package/dist/core/plugin.js.map +1 -0
- package/dist/core/router.d.ts +38 -0
- package/dist/core/router.js +406 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/scanner.d.ts +7 -0
- package/dist/core/scanner.js +83 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/shutdown-manager.d.ts +15 -0
- package/dist/core/shutdown-manager.js +68 -0
- package/dist/core/shutdown-manager.js.map +1 -0
- package/dist/core/websocket-handler.d.ts +41 -0
- package/dist/core/websocket-handler.js +242 -0
- package/dist/core/websocket-handler.js.map +1 -0
- package/dist/decorators/autowired.d.ts +3 -0
- package/dist/decorators/autowired.js +11 -0
- package/dist/decorators/autowired.js.map +1 -0
- package/dist/decorators/cinnabun-application.d.ts +14 -0
- package/dist/decorators/cinnabun-application.js +17 -0
- package/dist/decorators/cinnabun-application.js.map +1 -0
- package/dist/decorators/lifecycle.d.ts +2 -0
- package/dist/decorators/lifecycle.js +12 -0
- package/dist/decorators/lifecycle.js.map +1 -0
- package/dist/decorators/middleware.d.ts +2 -0
- package/dist/decorators/middleware.js +12 -0
- package/dist/decorators/middleware.js.map +1 -0
- package/dist/decorators/module.d.ts +10 -0
- package/dist/decorators/module.js +13 -0
- package/dist/decorators/module.js.map +1 -0
- package/dist/decorators/on-shutdown.d.ts +1 -0
- package/dist/decorators/on-shutdown.js +10 -0
- package/dist/decorators/on-shutdown.js.map +1 -0
- package/dist/decorators/params.d.ts +6 -0
- package/dist/decorators/params.js +31 -0
- package/dist/decorators/params.js.map +1 -0
- package/dist/decorators/request-mapping.d.ts +7 -0
- package/dist/decorators/request-mapping.js +34 -0
- package/dist/decorators/request-mapping.js.map +1 -0
- package/dist/decorators/response.d.ts +2 -0
- package/dist/decorators/response.js +17 -0
- package/dist/decorators/response.js.map +1 -0
- package/dist/decorators/rest-controller.d.ts +1 -0
- package/dist/decorators/rest-controller.js +19 -0
- package/dist/decorators/rest-controller.js.map +1 -0
- package/dist/decorators/routes.d.ts +5 -0
- package/dist/decorators/routes.js +19 -0
- package/dist/decorators/routes.js.map +1 -0
- package/dist/decorators/service.d.ts +1 -0
- package/dist/decorators/service.js +7 -0
- package/dist/decorators/service.js.map +1 -0
- package/dist/decorators/use-guard.d.ts +2 -0
- package/dist/decorators/use-guard.js +12 -0
- package/dist/decorators/use-guard.js.map +1 -0
- package/dist/decorators/use-interceptor.d.ts +2 -0
- package/dist/decorators/use-interceptor.js +12 -0
- package/dist/decorators/use-interceptor.js.map +1 -0
- package/dist/decorators/validate.d.ts +12 -0
- package/dist/decorators/validate.js +7 -0
- package/dist/decorators/validate.js.map +1 -0
- package/dist/decorators/websocket.d.ts +9 -0
- package/dist/decorators/websocket.js +38 -0
- package/dist/decorators/websocket.js.map +1 -0
- package/dist/decorators/ws-event.d.ts +28 -0
- package/dist/decorators/ws-event.js +37 -0
- package/dist/decorators/ws-event.js.map +1 -0
- package/dist/decorators/ws-gateway.d.ts +18 -0
- package/dist/decorators/ws-gateway.js +24 -0
- package/dist/decorators/ws-gateway.js.map +1 -0
- package/dist/dev/index.d.ts +6 -0
- package/dist/dev/index.js +28 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/exceptions/circular-dependency-error.d.ts +5 -0
- package/dist/exceptions/circular-dependency-error.js +16 -0
- package/dist/exceptions/circular-dependency-error.js.map +1 -0
- package/dist/exceptions/http-exception.d.ts +41 -0
- package/dist/exceptions/http-exception.js +96 -0
- package/dist/exceptions/http-exception.js.map +1 -0
- package/dist/guards/jwt-websocket.guard.d.ts +11 -0
- package/dist/guards/jwt-websocket.guard.js +37 -0
- package/dist/guards/jwt-websocket.guard.js.map +1 -0
- package/dist/guards/websocket-auth.guard.d.ts +16 -0
- package/dist/guards/websocket-auth.guard.js +43 -0
- package/dist/guards/websocket-auth.guard.js.map +1 -0
- package/dist/health/health-check.service.d.ts +45 -0
- package/dist/health/health-check.service.js +95 -0
- package/dist/health/health-check.service.js.map +1 -0
- package/dist/health/health.controller.d.ts +15 -0
- package/dist/health/health.controller.js +63 -0
- package/dist/health/health.controller.js.map +1 -0
- package/dist/health/health.module.d.ts +2 -0
- package/dist/health/health.module.js +20 -0
- package/dist/health/health.module.js.map +1 -0
- package/dist/index.d.ts +74 -11
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata/storage.d.ts +171 -0
- package/dist/metadata/storage.js +257 -0
- package/dist/metadata/storage.js.map +1 -0
- package/dist/middleware/compression.middleware.d.ts +32 -0
- package/dist/middleware/compression.middleware.js +113 -0
- package/dist/middleware/compression.middleware.js.map +1 -0
- package/dist/middleware/cors.middleware.d.ts +18 -0
- package/dist/middleware/cors.middleware.js +79 -0
- package/dist/middleware/cors.middleware.js.map +1 -0
- package/dist/middleware/performance-tracker.middleware.d.ts +35 -0
- package/dist/middleware/performance-tracker.middleware.js +79 -0
- package/dist/middleware/performance-tracker.middleware.js.map +1 -0
- package/dist/middleware/request-logger.middleware.d.ts +32 -0
- package/dist/middleware/request-logger.middleware.js +125 -0
- package/dist/middleware/request-logger.middleware.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/validation/helpers.d.ts +36 -0
- package/dist/validation/helpers.js +27 -0
- package/dist/validation/helpers.js.map +1 -0
- package/dist/websocket/error.d.ts +27 -0
- package/dist/websocket/error.js +38 -0
- package/dist/websocket/error.js.map +1 -0
- package/package.json +38 -5
- package/LICENSE +0 -9
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Middleware } from "../core/router.js";
|
|
2
|
+
export interface RequestLoggerOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Log level for requests (default: "info")
|
|
5
|
+
*/
|
|
6
|
+
level?: "debug" | "info" | "warn" | "error";
|
|
7
|
+
/**
|
|
8
|
+
* Whether to log request body (default: false for security)
|
|
9
|
+
*/
|
|
10
|
+
logBody?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Whether to log response body (default: false)
|
|
13
|
+
*/
|
|
14
|
+
logResponse?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Skip logging for specific paths (e.g., health checks)
|
|
17
|
+
*/
|
|
18
|
+
skip?: (req: Request) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Custom request ID header name (default: "x-request-id")
|
|
21
|
+
*/
|
|
22
|
+
requestIdHeader?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare class RequestLoggerMiddleware implements Middleware {
|
|
25
|
+
private logger;
|
|
26
|
+
private options;
|
|
27
|
+
constructor(options?: RequestLoggerOptions);
|
|
28
|
+
use(req: Request, next: () => Promise<Response>): Promise<Response>;
|
|
29
|
+
private generateRequestId;
|
|
30
|
+
private sanitizeHeaders;
|
|
31
|
+
private getLogLevel;
|
|
32
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Logger } from "../core/logger.js";
|
|
2
|
+
export class RequestLoggerMiddleware {
|
|
3
|
+
logger = new Logger("HTTP");
|
|
4
|
+
options;
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
this.options = {
|
|
7
|
+
level: options.level ?? "info",
|
|
8
|
+
logBody: options.logBody ?? false,
|
|
9
|
+
logResponse: options.logResponse ?? false,
|
|
10
|
+
skip: options.skip ?? (() => false),
|
|
11
|
+
requestIdHeader: options.requestIdHeader ?? "x-request-id",
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async use(req, next) {
|
|
15
|
+
// Skip if configured
|
|
16
|
+
if (this.options.skip(req)) {
|
|
17
|
+
return next();
|
|
18
|
+
}
|
|
19
|
+
const url = new URL(req.url);
|
|
20
|
+
const startTime = Date.now();
|
|
21
|
+
// Generate or extract request ID
|
|
22
|
+
const requestId = req.headers.get(this.options.requestIdHeader) ||
|
|
23
|
+
this.generateRequestId();
|
|
24
|
+
// Log incoming request
|
|
25
|
+
const requestLog = {
|
|
26
|
+
requestId,
|
|
27
|
+
method: req.method,
|
|
28
|
+
path: url.pathname,
|
|
29
|
+
query: Object.fromEntries(url.searchParams),
|
|
30
|
+
headers: this.sanitizeHeaders(req.headers),
|
|
31
|
+
ip: req.headers.get("x-forwarded-for") || req.headers.get("x-real-ip") || "unknown",
|
|
32
|
+
};
|
|
33
|
+
if (this.options.logBody && req.method !== "GET") {
|
|
34
|
+
try {
|
|
35
|
+
// Clone request to read body without consuming it
|
|
36
|
+
const cloned = req.clone();
|
|
37
|
+
const contentType = req.headers.get("content-type");
|
|
38
|
+
if (contentType?.includes("application/json")) {
|
|
39
|
+
requestLog.body = await cloned.json();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
// Ignore body parsing errors
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
this.logger.info("→ Incoming request", requestLog);
|
|
47
|
+
// Execute request
|
|
48
|
+
let response;
|
|
49
|
+
let error;
|
|
50
|
+
try {
|
|
51
|
+
response = await next();
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
error = err instanceof Error ? err : new Error(String(err));
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
const duration = Date.now() - startTime;
|
|
59
|
+
// Log response
|
|
60
|
+
const responseLog = {
|
|
61
|
+
requestId,
|
|
62
|
+
method: req.method,
|
|
63
|
+
path: url.pathname,
|
|
64
|
+
status: response?.status || 500,
|
|
65
|
+
duration: `${duration}ms`,
|
|
66
|
+
};
|
|
67
|
+
if (error) {
|
|
68
|
+
responseLog.error = {
|
|
69
|
+
message: error.message,
|
|
70
|
+
type: error.name,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (this.options.logResponse && response) {
|
|
74
|
+
try {
|
|
75
|
+
const cloned = response.clone();
|
|
76
|
+
const contentType = response.headers.get("content-type");
|
|
77
|
+
if (contentType?.includes("application/json")) {
|
|
78
|
+
responseLog.body = await cloned.json();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
// Ignore body parsing errors
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Log at appropriate level based on status code
|
|
86
|
+
const logLevel = this.getLogLevel(response?.status || 500);
|
|
87
|
+
this.logger[logLevel]("← Response", responseLog);
|
|
88
|
+
// Add request ID to response headers
|
|
89
|
+
if (response) {
|
|
90
|
+
const headers = new Headers(response.headers);
|
|
91
|
+
headers.set(this.options.requestIdHeader, requestId);
|
|
92
|
+
response = new Response(response.body, {
|
|
93
|
+
status: response.status,
|
|
94
|
+
statusText: response.statusText,
|
|
95
|
+
headers,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
generateRequestId() {
|
|
102
|
+
return `req_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
103
|
+
}
|
|
104
|
+
sanitizeHeaders(headers) {
|
|
105
|
+
const sanitized = {};
|
|
106
|
+
const sensitiveHeaders = ["authorization", "cookie", "x-api-key"];
|
|
107
|
+
for (const [key, value] of headers.entries()) {
|
|
108
|
+
if (sensitiveHeaders.includes(key.toLowerCase())) {
|
|
109
|
+
sanitized[key] = "[REDACTED]";
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
sanitized[key] = value;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return sanitized;
|
|
116
|
+
}
|
|
117
|
+
getLogLevel(status) {
|
|
118
|
+
if (status >= 500)
|
|
119
|
+
return "error";
|
|
120
|
+
if (status >= 400)
|
|
121
|
+
return "warn";
|
|
122
|
+
return this.options.level;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=request-logger.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-logger.middleware.js","sourceRoot":"","sources":["../../src/middleware/request-logger.middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility types for better TypeScript experience
|
|
3
|
+
*/
|
|
4
|
+
export type Constructor<T = any> = new (...args: any[]) => T;
|
|
5
|
+
export type Promisable<T> = T | Promise<T>;
|
|
6
|
+
export type DeepPartial<T> = {
|
|
7
|
+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
8
|
+
};
|
|
9
|
+
export type Prettify<T> = {
|
|
10
|
+
[K in keyof T]: T[K];
|
|
11
|
+
} & {};
|
|
12
|
+
export type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
|
|
13
|
+
export type { ZodSchema } from "zod";
|
|
14
|
+
export type { ServerWebSocket } from "bun";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Common validation schemas
|
|
4
|
+
*/
|
|
5
|
+
export declare const ValidationSchemas: {
|
|
6
|
+
email: z.ZodString;
|
|
7
|
+
password: z.ZodString;
|
|
8
|
+
uuid: z.ZodString;
|
|
9
|
+
url: z.ZodString;
|
|
10
|
+
positiveInt: z.ZodNumber;
|
|
11
|
+
dateString: z.ZodString;
|
|
12
|
+
nonEmptyString: z.ZodString;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Pagination schema
|
|
16
|
+
*/
|
|
17
|
+
export declare const PaginationSchema: z.ZodObject<{
|
|
18
|
+
page: z.ZodDefault<z.ZodNumber>;
|
|
19
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
page: number;
|
|
22
|
+
limit: number;
|
|
23
|
+
}, {
|
|
24
|
+
page?: number | undefined;
|
|
25
|
+
limit?: number | undefined;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* ID parameter schema
|
|
29
|
+
*/
|
|
30
|
+
export declare const IdSchema: z.ZodObject<{
|
|
31
|
+
id: z.ZodString;
|
|
32
|
+
}, "strip", z.ZodTypeAny, {
|
|
33
|
+
id: string;
|
|
34
|
+
}, {
|
|
35
|
+
id: string;
|
|
36
|
+
}>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Common validation schemas
|
|
4
|
+
*/
|
|
5
|
+
export const ValidationSchemas = {
|
|
6
|
+
email: z.string().email("Invalid email address"),
|
|
7
|
+
password: z.string().min(8, "Password must be at least 8 characters"),
|
|
8
|
+
uuid: z.string().uuid("Invalid UUID format"),
|
|
9
|
+
url: z.string().url("Invalid URL format"),
|
|
10
|
+
positiveInt: z.number().int().positive("Must be a positive integer"),
|
|
11
|
+
dateString: z.string().datetime("Invalid ISO 8601 date format"),
|
|
12
|
+
nonEmptyString: z.string().min(1, "Cannot be empty"),
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Pagination schema
|
|
16
|
+
*/
|
|
17
|
+
export const PaginationSchema = z.object({
|
|
18
|
+
page: z.number().int().positive().default(1),
|
|
19
|
+
limit: z.number().int().positive().max(100).default(10),
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* ID parameter schema
|
|
23
|
+
*/
|
|
24
|
+
export const IdSchema = z.object({
|
|
25
|
+
id: z.string().uuid("Invalid ID format"),
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/validation/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,uBAAuB,CAAC;IAEhD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,wCAAwC,CAAC;IAErE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC;IAE5C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAEzC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IAEpE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;IAE/D,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,iBAAiB,CAAC;CACrD,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACxD,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC;CACzC,CAAC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured WebSocket error response format
|
|
3
|
+
*/
|
|
4
|
+
export interface WsErrorResponse {
|
|
5
|
+
type: "error";
|
|
6
|
+
error: string;
|
|
7
|
+
message: string;
|
|
8
|
+
errorId?: string;
|
|
9
|
+
errors?: Record<string, string[]>;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Error thrown when WebSocket message validation fails
|
|
14
|
+
*/
|
|
15
|
+
export declare class WsValidationError extends Error {
|
|
16
|
+
readonly event: string;
|
|
17
|
+
readonly errors: Record<string, string[]>;
|
|
18
|
+
constructor(event: string, errors: Record<string, string[]>);
|
|
19
|
+
/**
|
|
20
|
+
* Convert to WebSocket error response format
|
|
21
|
+
*/
|
|
22
|
+
toResponse(): WsErrorResponse;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Helper to create a WebSocket error response
|
|
26
|
+
*/
|
|
27
|
+
export declare function createWsError(error: string, message: string, errorId?: string): WsErrorResponse;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error thrown when WebSocket message validation fails
|
|
3
|
+
*/
|
|
4
|
+
export class WsValidationError extends Error {
|
|
5
|
+
event;
|
|
6
|
+
errors;
|
|
7
|
+
constructor(event, errors) {
|
|
8
|
+
super("WebSocket message validation failed");
|
|
9
|
+
this.event = event;
|
|
10
|
+
this.errors = errors;
|
|
11
|
+
this.name = "WsValidationError";
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Convert to WebSocket error response format
|
|
15
|
+
*/
|
|
16
|
+
toResponse() {
|
|
17
|
+
return {
|
|
18
|
+
type: "error",
|
|
19
|
+
error: "ValidationError",
|
|
20
|
+
message: `Invalid message format for event: ${this.event}`,
|
|
21
|
+
errors: this.errors,
|
|
22
|
+
timestamp: new Date().toISOString(),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Helper to create a WebSocket error response
|
|
28
|
+
*/
|
|
29
|
+
export function createWsError(error, message, errorId) {
|
|
30
|
+
return {
|
|
31
|
+
type: "error",
|
|
32
|
+
error,
|
|
33
|
+
message,
|
|
34
|
+
errorId,
|
|
35
|
+
timestamp: new Date().toISOString(),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/websocket/error.ts"],"names":[],"mappings":"AAYA;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAExB;IACA;IAFlB,YACkB,KAAa,EACb,MAAgC;QAEhD,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAH7B,UAAK,GAAL,KAAK,CAAQ;QACb,WAAM,GAAN,MAAM,CAA0B;QAGhD,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO;YACL,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,iBAAiB;YACxB,OAAO,EAAE,qCAAqC,IAAI,CAAC,KAAK,EAAE;YAC1D,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAa,EACb,OAAe,EACf,OAAgB;IAEhB,OAAO;QACL,IAAI,EAAE,OAAO;QACb,KAAK;QACL,OAAO;QACP,OAAO;QACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cinnabun/core",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Production-ready TypeScript framework for Bun with decorators, DI, and type safety",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -9,16 +9,49 @@
|
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
|
-
"
|
|
12
|
+
"test": "bun test",
|
|
13
|
+
"build": "tsc",
|
|
13
14
|
"prepublishOnly": "bun run build"
|
|
14
15
|
},
|
|
15
16
|
"keywords": [
|
|
16
17
|
"bun",
|
|
17
18
|
"framework",
|
|
18
|
-
"backend"
|
|
19
|
+
"backend",
|
|
20
|
+
"typescript",
|
|
21
|
+
"decorators",
|
|
22
|
+
"dependency-injection",
|
|
23
|
+
"ioc",
|
|
24
|
+
"rest-api",
|
|
25
|
+
"websocket",
|
|
26
|
+
"spring-boot"
|
|
19
27
|
],
|
|
28
|
+
"author": "",
|
|
20
29
|
"license": "MIT",
|
|
30
|
+
"homepage": "https://github.com/cinnabunjs/cinnabun#readme",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/cinnabunjs/cinnabun.git"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/cinnabunjs/cinnabun/issues"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"bun": ">=1.0.0"
|
|
40
|
+
},
|
|
21
41
|
"devDependencies": {
|
|
22
|
-
"
|
|
42
|
+
"@types/bun": "latest",
|
|
43
|
+
"typescript": "^5.9.3",
|
|
44
|
+
"zod": "^3.24.0"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"reflect-metadata": "^0.2.2"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"zod": "^3.0.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependenciesMeta": {
|
|
53
|
+
"zod": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
23
56
|
}
|
|
24
57
|
}
|
package/LICENSE
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
(The MIT License)
|
|
2
|
-
|
|
3
|
-
Copyright © 2026 Henrique Moura Batista
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
-
|
|
7
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
-
|
|
9
|
-
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|