@morojs/moro 1.3.0 → 1.5.0

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.
Files changed (86) hide show
  1. package/README.md +61 -7
  2. package/dist/core/config/index.d.ts +0 -1
  3. package/dist/core/config/index.js +0 -4
  4. package/dist/core/config/index.js.map +1 -1
  5. package/dist/core/config/loader.js +219 -226
  6. package/dist/core/config/loader.js.map +1 -1
  7. package/dist/core/config/schema.d.ts +30 -335
  8. package/dist/core/config/schema.js +133 -224
  9. package/dist/core/config/schema.js.map +1 -1
  10. package/dist/core/config/utils.d.ts +3 -2
  11. package/dist/core/config/utils.js.map +1 -1
  12. package/dist/core/config/validation.d.ts +17 -0
  13. package/dist/core/config/validation.js +129 -0
  14. package/dist/core/config/validation.js.map +1 -0
  15. package/dist/core/docs/index.js +1 -1
  16. package/dist/core/docs/index.js.map +1 -1
  17. package/dist/core/docs/openapi-generator.js +6 -6
  18. package/dist/core/docs/openapi-generator.js.map +1 -1
  19. package/dist/core/docs/schema-to-openapi.d.ts +7 -0
  20. package/dist/core/docs/schema-to-openapi.js +124 -0
  21. package/dist/core/docs/schema-to-openapi.js.map +1 -0
  22. package/dist/core/docs/simple-docs.js +5 -5
  23. package/dist/core/docs/zod-to-openapi.d.ts +4 -3
  24. package/dist/core/docs/zod-to-openapi.js +28 -0
  25. package/dist/core/docs/zod-to-openapi.js.map +1 -1
  26. package/dist/core/framework.d.ts +29 -6
  27. package/dist/core/framework.js +117 -18
  28. package/dist/core/framework.js.map +1 -1
  29. package/dist/core/networking/adapters/index.d.ts +3 -0
  30. package/dist/core/networking/adapters/index.js +10 -0
  31. package/dist/core/networking/adapters/index.js.map +1 -0
  32. package/dist/core/networking/adapters/socketio-adapter.d.ts +16 -0
  33. package/dist/core/networking/adapters/socketio-adapter.js +244 -0
  34. package/dist/core/networking/adapters/socketio-adapter.js.map +1 -0
  35. package/dist/core/networking/adapters/ws-adapter.d.ts +54 -0
  36. package/dist/core/networking/adapters/ws-adapter.js +383 -0
  37. package/dist/core/networking/adapters/ws-adapter.js.map +1 -0
  38. package/dist/core/networking/websocket-adapter.d.ts +171 -0
  39. package/dist/core/networking/websocket-adapter.js +5 -0
  40. package/dist/core/networking/websocket-adapter.js.map +1 -0
  41. package/dist/core/networking/websocket-manager.d.ts +53 -17
  42. package/dist/core/networking/websocket-manager.js +184 -126
  43. package/dist/core/networking/websocket-manager.js.map +1 -1
  44. package/dist/core/routing/index.d.ts +13 -13
  45. package/dist/core/routing/index.js.map +1 -1
  46. package/dist/core/validation/adapters.d.ts +51 -0
  47. package/dist/core/validation/adapters.js +135 -0
  48. package/dist/core/validation/adapters.js.map +1 -0
  49. package/dist/core/validation/index.d.ts +12 -11
  50. package/dist/core/validation/index.js +32 -26
  51. package/dist/core/validation/index.js.map +1 -1
  52. package/dist/core/validation/schema-interface.d.ts +36 -0
  53. package/dist/core/validation/schema-interface.js +68 -0
  54. package/dist/core/validation/schema-interface.js.map +1 -0
  55. package/dist/index.d.ts +9 -2
  56. package/dist/index.js +23 -4
  57. package/dist/index.js.map +1 -1
  58. package/dist/moro.js +24 -17
  59. package/dist/moro.js.map +1 -1
  60. package/dist/types/config.d.ts +146 -0
  61. package/dist/types/config.js +4 -0
  62. package/dist/types/config.js.map +1 -0
  63. package/package.json +30 -7
  64. package/src/core/config/index.ts +0 -3
  65. package/src/core/config/loader.ts +571 -247
  66. package/src/core/config/schema.ts +146 -279
  67. package/src/core/config/utils.ts +1 -2
  68. package/src/core/config/validation.ts +140 -0
  69. package/src/core/docs/index.ts +1 -1
  70. package/src/core/docs/openapi-generator.ts +7 -6
  71. package/src/core/docs/schema-to-openapi.ts +148 -0
  72. package/src/core/docs/simple-docs.ts +5 -5
  73. package/src/core/docs/zod-to-openapi.ts +52 -20
  74. package/src/core/framework.ts +121 -28
  75. package/src/core/networking/adapters/index.ts +16 -0
  76. package/src/core/networking/adapters/socketio-adapter.ts +252 -0
  77. package/src/core/networking/adapters/ws-adapter.ts +425 -0
  78. package/src/core/networking/websocket-adapter.ts +217 -0
  79. package/src/core/networking/websocket-manager.ts +201 -143
  80. package/src/core/routing/index.ts +13 -13
  81. package/src/core/validation/adapters.ts +147 -0
  82. package/src/core/validation/index.ts +54 -38
  83. package/src/core/validation/schema-interface.ts +100 -0
  84. package/src/index.ts +36 -3
  85. package/src/moro.ts +27 -17
  86. package/src/types/config.ts +157 -0
@@ -1,7 +1,7 @@
1
1
  // Intelligent Routing System for Moro Framework
2
2
  // Schema-first with automatic middleware ordering and chainable API
3
3
 
4
- import { z, ZodSchema } from 'zod';
4
+ import { ValidationSchema } from '../validation/schema-interface';
5
5
  import { HttpRequest, HttpResponse } from '../http';
6
6
  import { createFrameworkLogger } from '../logger';
7
7
 
@@ -18,10 +18,10 @@ export type Middleware = (
18
18
 
19
19
  // Configuration interfaces
20
20
  export interface ValidationConfig {
21
- body?: ZodSchema;
22
- query?: ZodSchema;
23
- params?: ZodSchema;
24
- headers?: ZodSchema;
21
+ body?: ValidationSchema;
22
+ query?: ValidationSchema;
23
+ params?: ValidationSchema;
24
+ headers?: ValidationSchema;
25
25
  }
26
26
 
27
27
  export interface AuthConfig {
@@ -98,10 +98,10 @@ export interface ValidatedRequest<T = any> extends HttpRequest {
98
98
  export interface RouteBuilder {
99
99
  // Validation methods
100
100
  validate(config: ValidationConfig): RouteBuilder;
101
- body<T>(schema: ZodSchema<T>): RouteBuilder;
102
- query<T>(schema: ZodSchema<T>): RouteBuilder;
103
- params<T>(schema: ZodSchema<T>): RouteBuilder;
104
- headers<T>(schema: ZodSchema<T>): RouteBuilder;
101
+ body<T>(schema: ValidationSchema<T>): RouteBuilder;
102
+ query<T>(schema: ValidationSchema<T>): RouteBuilder;
103
+ params<T>(schema: ValidationSchema<T>): RouteBuilder;
104
+ headers<T>(schema: ValidationSchema<T>): RouteBuilder;
105
105
 
106
106
  // Security/Auth methods
107
107
  auth(config: AuthConfig): RouteBuilder;
@@ -148,25 +148,25 @@ export class IntelligentRouteBuilder implements RouteBuilder {
148
148
  return this;
149
149
  }
150
150
 
151
- body<T>(schema: ZodSchema<T>): RouteBuilder {
151
+ body<T>(schema: ValidationSchema<T>): RouteBuilder {
152
152
  if (!this.schema.validation) this.schema.validation = {};
153
153
  this.schema.validation.body = schema;
154
154
  return this;
155
155
  }
156
156
 
157
- query<T>(schema: ZodSchema<T>): RouteBuilder {
157
+ query<T>(schema: ValidationSchema<T>): RouteBuilder {
158
158
  if (!this.schema.validation) this.schema.validation = {};
159
159
  this.schema.validation.query = schema;
160
160
  return this;
161
161
  }
162
162
 
163
- params<T>(schema: ZodSchema<T>): RouteBuilder {
163
+ params<T>(schema: ValidationSchema<T>): RouteBuilder {
164
164
  if (!this.schema.validation) this.schema.validation = {};
165
165
  this.schema.validation.params = schema;
166
166
  return this;
167
167
  }
168
168
 
169
- headers<T>(schema: ZodSchema<T>): RouteBuilder {
169
+ headers<T>(schema: ValidationSchema<T>): RouteBuilder {
170
170
  if (!this.schema.validation) this.schema.validation = {};
171
171
  this.schema.validation.headers = schema;
172
172
  return this;
@@ -0,0 +1,147 @@
1
+ // Validation Library Adapters for Moro Framework
2
+ // Makes Joi, Yup, and other libraries compatible with ValidationSchema interface
3
+
4
+ import { ValidationSchema, ValidationError, normalizeValidationError } from './schema-interface';
5
+
6
+ /**
7
+ * Zod Compatibility Check
8
+ * Zod ALREADY implements ValidationSchema interface natively!
9
+ * No adapter needed - it just works.
10
+ */
11
+
12
+ /**
13
+ * Joi Adapter - makes Joi schemas compatible with ValidationSchema
14
+ */
15
+ export class JoiAdapter<T = any> implements ValidationSchema<T> {
16
+ constructor(private joiSchema: any) {
17
+ if (!joiSchema || typeof joiSchema.validateAsync !== 'function') {
18
+ throw new Error('Invalid Joi schema provided to JoiAdapter');
19
+ }
20
+ }
21
+
22
+ async parseAsync(data: unknown): Promise<T> {
23
+ try {
24
+ const result = await this.joiSchema.validateAsync(data, { abortEarly: false });
25
+ return result as T;
26
+ } catch (error) {
27
+ throw normalizeValidationError(error);
28
+ }
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Yup Adapter - makes Yup schemas compatible with ValidationSchema
34
+ */
35
+ export class YupAdapter<T = any> implements ValidationSchema<T> {
36
+ constructor(private yupSchema: any) {
37
+ if (!yupSchema || typeof yupSchema.validate !== 'function') {
38
+ throw new Error('Invalid Yup schema provided to YupAdapter');
39
+ }
40
+ }
41
+
42
+ async parseAsync(data: unknown): Promise<T> {
43
+ try {
44
+ const result = await this.yupSchema.validate(data, { abortEarly: false });
45
+ return result as T;
46
+ } catch (error) {
47
+ throw normalizeValidationError(error);
48
+ }
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Custom Validation Function Adapter
54
+ * Allows users to use simple validation functions
55
+ */
56
+ export class FunctionAdapter<T = any> implements ValidationSchema<T> {
57
+ constructor(
58
+ private validateFn: (data: unknown) => T | Promise<T>,
59
+ private name: string = 'custom'
60
+ ) {
61
+ if (typeof validateFn !== 'function') {
62
+ throw new Error('Validation function is required for FunctionAdapter');
63
+ }
64
+ }
65
+
66
+ async parseAsync(data: unknown): Promise<T> {
67
+ try {
68
+ return await this.validateFn(data);
69
+ } catch (error) {
70
+ throw new ValidationError([
71
+ {
72
+ path: [],
73
+ message: error instanceof Error ? error.message : String(error),
74
+ code: this.name,
75
+ },
76
+ ]);
77
+ }
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Class Validator Adapter (for TypeScript decorators)
83
+ */
84
+ export class ClassValidatorAdapter<T extends object = any> implements ValidationSchema<T> {
85
+ constructor(
86
+ private ClassType: new () => T,
87
+ private validate?: (obj: any) => Promise<any[]>
88
+ ) {
89
+ if (typeof ClassType !== 'function') {
90
+ throw new Error('Class constructor is required for ClassValidatorAdapter');
91
+ }
92
+ }
93
+
94
+ async parseAsync(data: unknown): Promise<T> {
95
+ try {
96
+ const instance = Object.assign(new this.ClassType(), data as Record<string, any>);
97
+
98
+ if (this.validate) {
99
+ const errors = await this.validate(instance);
100
+ if (errors && errors.length > 0) {
101
+ throw new ValidationError(
102
+ errors.map((error: any, index: number) => ({
103
+ path: error.property ? [error.property] : [index],
104
+ message: Object.values(error.constraints || {}).join(', ') || 'Validation failed',
105
+ code: 'class_validator',
106
+ }))
107
+ );
108
+ }
109
+ }
110
+
111
+ return instance as T;
112
+ } catch (error) {
113
+ if (error instanceof ValidationError) throw error;
114
+ throw normalizeValidationError(error);
115
+ }
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Utility functions for creating adapters
121
+ */
122
+ export function joi<T = any>(joiSchema: any): ValidationSchema<T> {
123
+ return new JoiAdapter<T>(joiSchema);
124
+ }
125
+
126
+ export function yup<T = any>(yupSchema: any): ValidationSchema<T> {
127
+ return new YupAdapter<T>(yupSchema);
128
+ }
129
+
130
+ export function fn<T = any>(
131
+ validateFn: (data: unknown) => T | Promise<T>,
132
+ name?: string
133
+ ): ValidationSchema<T> {
134
+ return new FunctionAdapter<T>(validateFn, name);
135
+ }
136
+
137
+ export function classValidator<T extends object = any>(
138
+ ClassType: new () => T,
139
+ validate?: (obj: any) => Promise<any[]>
140
+ ): ValidationSchema<T> {
141
+ return new ClassValidatorAdapter<T>(ClassType, validate);
142
+ }
143
+
144
+ // Type helpers
145
+ export type JoiSchema<T> = ValidationSchema<T>;
146
+ export type YupSchema<T> = ValidationSchema<T>;
147
+ export type CustomValidator<T> = ValidationSchema<T>;
@@ -1,28 +1,36 @@
1
- // Functional Validation System for Moro Framework
2
- // Elegant, type-safe validation using Zod with functional composition
1
+ // Universal Validation System for Moro Framework
2
+ // Works with Zod, Joi, Yup, and any validation library via adapters
3
3
 
4
- import { z, ZodSchema, ZodError } from 'zod';
5
4
  import { HttpRequest, HttpResponse } from '../http';
6
5
  import { createFrameworkLogger } from '../logger';
6
+ import {
7
+ ValidationSchema,
8
+ ValidationError,
9
+ normalizeValidationError,
10
+ InferSchemaType,
11
+ } from './schema-interface';
12
+
13
+ // Re-export zod if available (for backward compatibility)
14
+ // The dynamic import is handled in the main index.ts
7
15
 
8
16
  const logger = createFrameworkLogger('Validation');
9
17
 
10
- // Validation configuration interface
18
+ // Universal validation configuration interface
11
19
  export interface ValidationConfig {
12
- body?: ZodSchema;
13
- query?: ZodSchema;
14
- params?: ZodSchema;
15
- headers?: ZodSchema;
20
+ body?: ValidationSchema;
21
+ query?: ValidationSchema;
22
+ params?: ValidationSchema;
23
+ headers?: ValidationSchema;
16
24
  }
17
25
 
18
26
  // Validation result types
19
27
  export interface ValidationResult<T = any> {
20
28
  success: boolean;
21
29
  data?: T;
22
- errors?: ValidationError[];
30
+ errors?: ValidationErrorDetail[];
23
31
  }
24
32
 
25
- export interface ValidationError {
33
+ export interface ValidationErrorDetail {
26
34
  field: string;
27
35
  message: string;
28
36
  code: string;
@@ -110,9 +118,9 @@ export function validate<TBody = any, TQuery = any, TParams = any>(
110
118
  };
111
119
  }
112
120
 
113
- // Validate individual field
121
+ // Validate individual field using universal schema interface
114
122
  async function validateField(
115
- schema: ZodSchema,
123
+ schema: ValidationSchema,
116
124
  data: any,
117
125
  fieldName: string
118
126
  ): Promise<ValidationResult> {
@@ -123,32 +131,32 @@ async function validateField(
123
131
  data: validated,
124
132
  };
125
133
  } catch (error) {
126
- if (error instanceof ZodError) {
127
- const errors: ValidationError[] = error.issues.map((err: any) => ({
128
- field: err.path.length > 0 ? err.path.join('.') : fieldName,
129
- message: err.message,
130
- code: err.code,
131
- }));
132
-
133
- logger.debug('Field validation failed', 'ValidationFailed', {
134
- field: fieldName,
135
- errors: errors.length,
136
- details: errors,
137
- });
138
-
139
- return {
140
- success: false,
141
- errors,
142
- };
143
- }
134
+ const normalizedError = normalizeValidationError(error);
135
+ const errors: ValidationErrorDetail[] = normalizedError.issues.map(issue => ({
136
+ field: issue.path.length > 0 ? issue.path.join('.') : fieldName,
137
+ message: issue.message,
138
+ code: issue.code,
139
+ }));
140
+
141
+ logger.debug('Field validation failed', 'ValidationFailed', {
142
+ field: fieldName,
143
+ errors: errors.length,
144
+ details: errors,
145
+ });
144
146
 
145
- // Re-throw unexpected errors
146
- throw error;
147
+ return {
148
+ success: false,
149
+ errors,
150
+ };
147
151
  }
148
152
  }
149
153
 
150
154
  // Send validation error response
151
- function sendValidationError(res: HttpResponse, errors: ValidationError[], field: string): void {
155
+ function sendValidationError(
156
+ res: HttpResponse,
157
+ errors: ValidationErrorDetail[],
158
+ field: string
159
+ ): void {
152
160
  logger.debug('Sending validation error response', 'ValidationResponse', {
153
161
  field,
154
162
  errorCount: errors.length,
@@ -163,19 +171,19 @@ function sendValidationError(res: HttpResponse, errors: ValidationError[], field
163
171
  }
164
172
 
165
173
  // Convenience functions for single-field validation
166
- export function body<T>(schema: ZodSchema<T>) {
174
+ export function body<T>(schema: ValidationSchema<T>) {
167
175
  return (handler: (req: ValidatedRequest<T>, res: HttpResponse) => any | Promise<any>) => {
168
176
  return validate({ body: schema }, handler);
169
177
  };
170
178
  }
171
179
 
172
- export function query<T>(schema: ZodSchema<T>) {
180
+ export function query<T>(schema: ValidationSchema<T>) {
173
181
  return (handler: (req: ValidatedRequest<any>, res: HttpResponse) => any | Promise<any>) => {
174
182
  return validate({ query: schema }, handler);
175
183
  };
176
184
  }
177
185
 
178
- export function params<T>(schema: ZodSchema<T>) {
186
+ export function params<T>(schema: ValidationSchema<T>) {
179
187
  return (handler: (req: ValidatedRequest<any>, res: HttpResponse) => any | Promise<any>) => {
180
188
  return validate({ params: schema }, handler);
181
189
  };
@@ -186,5 +194,13 @@ export function combineSchemas(schemas: ValidationConfig): ValidationConfig {
186
194
  return schemas;
187
195
  }
188
196
 
189
- // Re-export Zod for convenience
190
- export { z } from 'zod';
197
+ // Re-export common validation tools
198
+ export {
199
+ ValidationSchema,
200
+ ValidationError,
201
+ normalizeValidationError,
202
+ InferSchemaType,
203
+ } from './schema-interface';
204
+ export { joi, yup, fn as customValidator, classValidator } from './adapters';
205
+
206
+ // Note: z is re-exported from main index.ts with dynamic import
@@ -0,0 +1,100 @@
1
+ // Universal Validation Schema Interface for Moro Framework
2
+ // Allows Zod, Joi, Yup, and other validation libraries to work seamlessly
3
+
4
+ /**
5
+ * Standard validation error structure
6
+ */
7
+ export interface ValidationIssue {
8
+ path: (string | number)[];
9
+ message: string;
10
+ code: string;
11
+ }
12
+
13
+ /**
14
+ * Standard validation error class
15
+ * Compatible with ZodError structure
16
+ */
17
+ export class ValidationError extends Error {
18
+ public readonly issues: ValidationIssue[];
19
+
20
+ constructor(issues: ValidationIssue[]) {
21
+ const message = `Validation failed: ${issues.map(i => i.message).join(', ')}`;
22
+ super(message);
23
+ this.name = 'ValidationError';
24
+ this.issues = issues;
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Universal validation schema interface
30
+ * This is what Zod naturally implements! No breaking changes needed.
31
+ */
32
+ export interface ValidationSchema<T = any> {
33
+ /**
34
+ * Parse data asynchronously and return validated result
35
+ * Throws ValidationError on validation failure
36
+ */
37
+ parseAsync(data: unknown): Promise<T>;
38
+ }
39
+
40
+ /**
41
+ * Check if an object implements the ValidationSchema interface
42
+ */
43
+ export function isValidationSchema(obj: any): obj is ValidationSchema {
44
+ return obj && typeof obj.parseAsync === 'function';
45
+ }
46
+
47
+ /**
48
+ * Convert various error formats to our standard ValidationError
49
+ */
50
+ export function normalizeValidationError(error: any): ValidationError {
51
+ // Already our format
52
+ if (error instanceof ValidationError) {
53
+ return error;
54
+ }
55
+
56
+ // Zod error format
57
+ if (error && error.issues && Array.isArray(error.issues)) {
58
+ return new ValidationError(
59
+ error.issues.map((issue: any) => ({
60
+ path: issue.path || [],
61
+ message: issue.message || 'Validation failed',
62
+ code: issue.code || 'invalid',
63
+ }))
64
+ );
65
+ }
66
+
67
+ // Joi error format
68
+ if (error && error.details && Array.isArray(error.details)) {
69
+ return new ValidationError(
70
+ error.details.map((detail: any) => ({
71
+ path: detail.path || [],
72
+ message: detail.message || 'Validation failed',
73
+ code: detail.type || 'invalid',
74
+ }))
75
+ );
76
+ }
77
+
78
+ // Yup error format
79
+ if (error && error.errors && Array.isArray(error.errors)) {
80
+ return new ValidationError(
81
+ error.errors.map((msg: string, index: number) => ({
82
+ path: error.path ? [error.path] : [index],
83
+ message: msg,
84
+ code: error.type || 'invalid',
85
+ }))
86
+ );
87
+ }
88
+
89
+ // Generic error
90
+ return new ValidationError([
91
+ {
92
+ path: [],
93
+ message: error.message || String(error),
94
+ code: 'unknown',
95
+ },
96
+ ]);
97
+ }
98
+
99
+ // Type helper for inferring types from validation schemas
100
+ export type InferSchemaType<T> = T extends ValidationSchema<infer U> ? U : never;
package/src/index.ts CHANGED
@@ -105,15 +105,34 @@ export type {
105
105
  // Logger System
106
106
  export { createFrameworkLogger, logger } from './core/logger';
107
107
 
108
- // Validation System (Zod-based)
109
- export { validate, body, query, params, combineSchemas, z } from './core/validation';
108
+ // Universal Validation System
109
+ export { validate, body, query, params, combineSchemas } from './core/validation';
110
+
111
+ // Dynamic Zod export (optional dependency)
112
+ let z: any;
113
+ try {
114
+ z = require('zod').z;
115
+ } catch {
116
+ // Zod not available - that's fine!
117
+ z = undefined;
118
+ }
119
+ export { z };
110
120
  export type {
111
121
  ValidationConfig,
112
122
  ValidationResult,
113
- ValidationError,
123
+ ValidationErrorDetail,
114
124
  ValidatedRequest,
115
125
  } from './core/validation';
116
126
 
127
+ // Universal Validation Interfaces and Adapters
128
+ export type {
129
+ ValidationSchema,
130
+ ValidationError,
131
+ InferSchemaType,
132
+ } from './core/validation/schema-interface';
133
+ export { normalizeValidationError } from './core/validation/schema-interface';
134
+ export { joi, yup, fn as customValidator, classValidator } from './core/validation/adapters';
135
+
117
136
  // Module System
118
137
  export {
119
138
  defineModule,
@@ -123,6 +142,20 @@ export {
123
142
  } from './core/modules';
124
143
  export type { ModuleDefinition, ModuleRoute, ModuleSocket, ModuleConfig } from './types/module';
125
144
 
145
+ // WebSocket Adapter System
146
+ export type {
147
+ WebSocketAdapter,
148
+ WebSocketAdapterOptions,
149
+ WebSocketNamespace,
150
+ WebSocketConnection,
151
+ WebSocketEmitter,
152
+ WebSocketMiddleware,
153
+ WebSocketEventHandler,
154
+ } from './core/networking/websocket-adapter';
155
+
156
+ // Built-in WebSocket Adapters
157
+ export { SocketIOAdapter, WSAdapter } from './core/networking/adapters';
158
+
126
159
  // Intelligent Routing System
127
160
  export { createRoute, defineRoute, EXECUTION_PHASES } from './core/routing';
128
161
  export { IntelligentRoutingManager, RouteRegistry } from './core/routing/app-integration';
package/src/moro.ts CHANGED
@@ -387,10 +387,19 @@ export class Moro extends EventEmitter {
387
387
 
388
388
  // WebSocket helper with events
389
389
  websocket(namespace: string, handlers: Record<string, Function>) {
390
+ const adapter = this.coreFramework.getWebSocketAdapter();
391
+ if (!adapter) {
392
+ throw new Error(
393
+ 'WebSocket features require a WebSocket adapter. Install socket.io or configure an adapter:\n' +
394
+ 'npm install socket.io\n' +
395
+ 'or\n' +
396
+ 'new Moro({ websocket: { adapter: new SocketIOAdapter() } })'
397
+ );
398
+ }
399
+
390
400
  this.emit('websocket:registering', { namespace, handlers });
391
401
 
392
- const io = this.coreFramework.getIOServer();
393
- const ns = io.of(namespace);
402
+ const ns = adapter.createNamespace(namespace);
394
403
 
395
404
  Object.entries(handlers).forEach(([event, handler]) => {
396
405
  ns.on('connection', socket => {
@@ -761,25 +770,26 @@ export class Moro extends EventEmitter {
761
770
  // Enhance request with events property for direct routes
762
771
  req.events = this.eventBus;
763
772
 
764
- // Validation middleware (Zod-only)
773
+ // Universal validation middleware (works with any ValidationSchema)
765
774
  if (route.validation) {
766
775
  try {
767
- const validated = route.validation.parse(req.body);
776
+ const validated = await route.validation.parseAsync(req.body);
768
777
  req.body = validated;
769
778
  } catch (error: any) {
770
- if (error.issues) {
771
- res.status(400).json({
772
- success: false,
773
- error: 'Validation failed',
774
- details: error.issues.map((issue: any) => ({
775
- field: issue.path.length > 0 ? issue.path.join('.') : 'body',
776
- message: issue.message,
777
- code: issue.code,
778
- })),
779
- });
780
- return;
781
- }
782
- throw error;
779
+ // Handle universal validation errors
780
+ const { normalizeValidationError } = require('./core/validation/schema-interface');
781
+ const normalizedError = normalizeValidationError(error);
782
+ res.status(400).json({
783
+ success: false,
784
+ error: 'Validation failed',
785
+ details: normalizedError.issues.map((issue: any) => ({
786
+ field: issue.path.length > 0 ? issue.path.join('.') : 'body',
787
+ message: issue.message,
788
+ code: issue.code,
789
+ })),
790
+ requestId: req.requestId,
791
+ });
792
+ return;
783
793
  }
784
794
  }
785
795