@engjts/nexus 0.1.8 → 0.1.9
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/package.json +1 -1
- package/BENCHMARK_REPORT.md +0 -343
- package/documentation/01-getting-started.md +0 -240
- package/documentation/02-context.md +0 -335
- package/documentation/03-routing.md +0 -397
- package/documentation/04-middleware.md +0 -483
- package/documentation/05-validation.md +0 -514
- package/documentation/06-error-handling.md +0 -465
- package/documentation/07-performance.md +0 -364
- package/documentation/08-adapters.md +0 -470
- package/documentation/09-api-reference.md +0 -548
- package/documentation/10-examples.md +0 -582
- package/documentation/11-deployment.md +0 -477
- package/documentation/12-sentry.md +0 -620
- package/documentation/13-sentry-data-storage.md +0 -996
- package/documentation/14-sentry-data-reference.md +0 -457
- package/documentation/15-sentry-summary.md +0 -409
- package/documentation/16-alerts-system.md +0 -745
- package/documentation/17-alert-adapters.md +0 -696
- package/documentation/18-alerts-implementation-summary.md +0 -385
- package/documentation/19-class-based-routing.md +0 -840
- package/documentation/20-websocket-realtime.md +0 -813
- package/documentation/21-cache-system.md +0 -510
- package/documentation/22-job-queue.md +0 -772
- package/documentation/23-sentry-plugin.md +0 -551
- package/documentation/24-testing-utilities.md +0 -1287
- package/documentation/25-api-versioning.md +0 -533
- package/documentation/26-context-store.md +0 -607
- package/documentation/27-dependency-injection.md +0 -329
- package/documentation/28-lifecycle-hooks.md +0 -521
- package/documentation/29-package-structure.md +0 -196
- package/documentation/30-plugin-system.md +0 -414
- package/documentation/31-jwt-authentication.md +0 -597
- package/documentation/32-cli.md +0 -268
- package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
- package/documentation/ALERTS-INDEX.md +0 -330
- package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
- package/documentation/README.md +0 -178
- package/documentation/index.html +0 -34
- package/modern_framework_paper.md +0 -1870
- package/public/css/style.css +0 -87
- package/public/index.html +0 -34
- package/public/js/app.js +0 -27
- package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
- package/src/advanced/cache/MultiTierCache.ts +0 -194
- package/src/advanced/cache/RedisCacheStore.ts +0 -341
- package/src/advanced/cache/index.ts +0 -5
- package/src/advanced/cache/types.ts +0 -40
- package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
- package/src/advanced/graphql/index.ts +0 -22
- package/src/advanced/graphql/server.ts +0 -252
- package/src/advanced/graphql/types.ts +0 -42
- package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
- package/src/advanced/jobs/JobQueue.ts +0 -556
- package/src/advanced/jobs/RedisQueueStore.ts +0 -367
- package/src/advanced/jobs/index.ts +0 -5
- package/src/advanced/jobs/types.ts +0 -70
- package/src/advanced/observability/APMManager.ts +0 -163
- package/src/advanced/observability/AlertManager.ts +0 -109
- package/src/advanced/observability/MetricRegistry.ts +0 -151
- package/src/advanced/observability/ObservabilityCenter.ts +0 -304
- package/src/advanced/observability/StructuredLogger.ts +0 -154
- package/src/advanced/observability/TracingManager.ts +0 -117
- package/src/advanced/observability/adapters.ts +0 -304
- package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
- package/src/advanced/observability/index.ts +0 -11
- package/src/advanced/observability/types.ts +0 -174
- package/src/advanced/playground/extractPathParams.ts +0 -6
- package/src/advanced/playground/generateFieldExample.ts +0 -31
- package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1956
- package/src/advanced/playground/generateSummary.ts +0 -19
- package/src/advanced/playground/getTagFromPath.ts +0 -9
- package/src/advanced/playground/index.ts +0 -8
- package/src/advanced/playground/playground.ts +0 -250
- package/src/advanced/playground/types.ts +0 -49
- package/src/advanced/playground/zodToExample.ts +0 -16
- package/src/advanced/playground/zodToParams.ts +0 -15
- package/src/advanced/postman/buildAuth.ts +0 -31
- package/src/advanced/postman/buildBody.ts +0 -15
- package/src/advanced/postman/buildQueryParams.ts +0 -27
- package/src/advanced/postman/buildRequestItem.ts +0 -36
- package/src/advanced/postman/buildResponses.ts +0 -11
- package/src/advanced/postman/buildUrl.ts +0 -33
- package/src/advanced/postman/capitalize.ts +0 -4
- package/src/advanced/postman/generateCollection.ts +0 -59
- package/src/advanced/postman/generateEnvironment.ts +0 -34
- package/src/advanced/postman/generateExampleFromZod.ts +0 -21
- package/src/advanced/postman/generateFieldExample.ts +0 -45
- package/src/advanced/postman/generateName.ts +0 -20
- package/src/advanced/postman/generateUUID.ts +0 -11
- package/src/advanced/postman/getTagFromPath.ts +0 -10
- package/src/advanced/postman/index.ts +0 -28
- package/src/advanced/postman/postman.ts +0 -156
- package/src/advanced/postman/slugify.ts +0 -7
- package/src/advanced/postman/types.ts +0 -140
- package/src/advanced/realtime/index.ts +0 -18
- package/src/advanced/realtime/websocket.ts +0 -231
- package/src/advanced/sentry/index.ts +0 -1236
- package/src/advanced/sentry/types.ts +0 -355
- package/src/advanced/static/generateDirectoryListing.ts +0 -47
- package/src/advanced/static/generateETag.ts +0 -7
- package/src/advanced/static/getMimeType.ts +0 -9
- package/src/advanced/static/index.ts +0 -32
- package/src/advanced/static/isSafePath.ts +0 -13
- package/src/advanced/static/publicDir.ts +0 -21
- package/src/advanced/static/serveStatic.ts +0 -225
- package/src/advanced/static/spa.ts +0 -24
- package/src/advanced/static/types.ts +0 -159
- package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
- package/src/advanced/swagger/buildOperation.ts +0 -61
- package/src/advanced/swagger/buildParameters.ts +0 -61
- package/src/advanced/swagger/buildRequestBody.ts +0 -21
- package/src/advanced/swagger/buildResponses.ts +0 -54
- package/src/advanced/swagger/capitalize.ts +0 -5
- package/src/advanced/swagger/convertPath.ts +0 -9
- package/src/advanced/swagger/createSwagger.ts +0 -12
- package/src/advanced/swagger/generateOperationId.ts +0 -21
- package/src/advanced/swagger/generateSpec.ts +0 -105
- package/src/advanced/swagger/generateSummary.ts +0 -24
- package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
- package/src/advanced/swagger/generateThemeCss.ts +0 -53
- package/src/advanced/swagger/index.ts +0 -25
- package/src/advanced/swagger/swagger.ts +0 -237
- package/src/advanced/swagger/types.ts +0 -206
- package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
- package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
- package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
- package/src/advanced/testing/factory.ts +0 -509
- package/src/advanced/testing/harness.ts +0 -612
- package/src/advanced/testing/index.ts +0 -430
- package/src/advanced/testing/load-test.ts +0 -618
- package/src/advanced/testing/mock-server.ts +0 -498
- package/src/advanced/testing/mock.ts +0 -670
- package/src/cli/bin.ts +0 -9
- package/src/cli/cli.ts +0 -158
- package/src/cli/commands/add.ts +0 -178
- package/src/cli/commands/build.ts +0 -73
- package/src/cli/commands/create.ts +0 -166
- package/src/cli/commands/dev.ts +0 -85
- package/src/cli/commands/generate.ts +0 -99
- package/src/cli/commands/help.ts +0 -95
- package/src/cli/commands/init.ts +0 -91
- package/src/cli/commands/version.ts +0 -38
- package/src/cli/index.ts +0 -6
- package/src/cli/templates/generators.ts +0 -359
- package/src/cli/templates/index.ts +0 -680
- package/src/cli/utils/exec.ts +0 -52
- package/src/cli/utils/file-system.ts +0 -78
- package/src/cli/utils/logger.ts +0 -111
- package/src/core/adapter.ts +0 -88
- package/src/core/application.ts +0 -1453
- package/src/core/context-pool.ts +0 -79
- package/src/core/context.ts +0 -856
- package/src/core/index.ts +0 -94
- package/src/core/middleware.ts +0 -272
- package/src/core/performance/buffer-pool.ts +0 -108
- package/src/core/performance/middleware-optimizer.ts +0 -162
- package/src/core/plugin/PluginManager.ts +0 -435
- package/src/core/plugin/builder.ts +0 -358
- package/src/core/plugin/index.ts +0 -50
- package/src/core/plugin/types.ts +0 -214
- package/src/core/router/file-router.ts +0 -623
- package/src/core/router/index.ts +0 -260
- package/src/core/router/radix-tree.ts +0 -242
- package/src/core/serializer.ts +0 -397
- package/src/core/store/index.ts +0 -30
- package/src/core/store/registry.ts +0 -178
- package/src/core/store/request-store.ts +0 -240
- package/src/core/store/types.ts +0 -233
- package/src/core/types.ts +0 -616
- package/src/database/adapter.ts +0 -35
- package/src/database/adapters/index.ts +0 -1
- package/src/database/adapters/mysql.ts +0 -669
- package/src/database/database.ts +0 -70
- package/src/database/dialect.ts +0 -388
- package/src/database/index.ts +0 -12
- package/src/database/migrations.ts +0 -86
- package/src/database/optimizer.ts +0 -125
- package/src/database/query-builder.ts +0 -404
- package/src/database/realtime.ts +0 -53
- package/src/database/schema.ts +0 -71
- package/src/database/transactions.ts +0 -56
- package/src/database/types.ts +0 -87
- package/src/deployment/cluster.ts +0 -471
- package/src/deployment/config.ts +0 -454
- package/src/deployment/docker.ts +0 -599
- package/src/deployment/graceful-shutdown.ts +0 -373
- package/src/deployment/index.ts +0 -56
- package/src/index.ts +0 -281
- package/src/security/adapter.ts +0 -318
- package/src/security/auth/JWTPlugin.ts +0 -234
- package/src/security/auth/JWTProvider.ts +0 -316
- package/src/security/auth/adapter.ts +0 -12
- package/src/security/auth/jwt.ts +0 -234
- package/src/security/auth/middleware.ts +0 -188
- package/src/security/csrf.ts +0 -220
- package/src/security/headers.ts +0 -108
- package/src/security/index.ts +0 -60
- package/src/security/rate-limit/adapter.ts +0 -7
- package/src/security/rate-limit/memory.ts +0 -108
- package/src/security/rate-limit/middleware.ts +0 -181
- package/src/security/sanitization.ts +0 -75
- package/src/security/types.ts +0 -240
- package/src/security/utils.ts +0 -52
- package/tsconfig.json +0 -39
package/src/core/index.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Nexus Core Module
|
|
3
|
-
*
|
|
4
|
-
* The minimal core of Nexus framework - Application, Router, Context, Middleware
|
|
5
|
-
* Use this import path when you want only the core without optional features:
|
|
6
|
-
*
|
|
7
|
-
* import { Application, Router, createApp } from '@engjts/server/core';
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
// Application
|
|
11
|
-
export { Application, Application as Nexus, createApp } from './application';
|
|
12
|
-
|
|
13
|
-
// Core types
|
|
14
|
-
export * from './types';
|
|
15
|
-
|
|
16
|
-
// Router
|
|
17
|
-
export { Router } from './router';
|
|
18
|
-
export { FileRouter, createFileRouter, useFileRoutes } from './router/file-router';
|
|
19
|
-
export type { FileRouterOptions, FileRouteClass, RouteModule } from './router/file-router';
|
|
20
|
-
|
|
21
|
-
// Middleware
|
|
22
|
-
export {
|
|
23
|
-
MiddlewareExecutor,
|
|
24
|
-
logger,
|
|
25
|
-
cors,
|
|
26
|
-
errorHandler
|
|
27
|
-
} from './middleware';
|
|
28
|
-
|
|
29
|
-
// Context
|
|
30
|
-
export { ContextImpl, parseBody } from './context';
|
|
31
|
-
export { ContextPool } from './context-pool';
|
|
32
|
-
|
|
33
|
-
// State Management
|
|
34
|
-
export {
|
|
35
|
-
ContextStore,
|
|
36
|
-
RequestStore,
|
|
37
|
-
StoreRegistry,
|
|
38
|
-
RequestStoreRegistry,
|
|
39
|
-
createStoreRegistry,
|
|
40
|
-
type StoreListener,
|
|
41
|
-
type DisposeCallback,
|
|
42
|
-
type StoreConstructor,
|
|
43
|
-
type StateOf,
|
|
44
|
-
type StoreOptions,
|
|
45
|
-
type RequestStoreConstructor,
|
|
46
|
-
type RequestStateOf
|
|
47
|
-
} from './store';
|
|
48
|
-
|
|
49
|
-
// Plugin System
|
|
50
|
-
export {
|
|
51
|
-
PluginManager,
|
|
52
|
-
PluginBuilder,
|
|
53
|
-
definePlugin,
|
|
54
|
-
createPlugin,
|
|
55
|
-
type NexusPlugin,
|
|
56
|
-
type SimplePlugin,
|
|
57
|
-
type PluginFactory,
|
|
58
|
-
type PluginMeta,
|
|
59
|
-
type PluginContext,
|
|
60
|
-
type PluginLogger,
|
|
61
|
-
type PluginPhase,
|
|
62
|
-
type PluginPriority,
|
|
63
|
-
type PluginRouteExtension,
|
|
64
|
-
type RegisteredPlugin
|
|
65
|
-
} from './plugin';
|
|
66
|
-
|
|
67
|
-
// Adapters
|
|
68
|
-
export {
|
|
69
|
-
AdapterRegistry,
|
|
70
|
-
type LoggerAdapter,
|
|
71
|
-
type CacheAdapter,
|
|
72
|
-
type SessionAdapter
|
|
73
|
-
} from './adapter';
|
|
74
|
-
|
|
75
|
-
// Performance
|
|
76
|
-
export { BufferPool, StreamUtils } from './performance/buffer-pool';
|
|
77
|
-
export { MiddlewareOptimizer, PerformanceMonitor } from './performance/middleware-optimizer';
|
|
78
|
-
|
|
79
|
-
// Fast JSON Serializer
|
|
80
|
-
export {
|
|
81
|
-
createSerializer,
|
|
82
|
-
createArraySerializer,
|
|
83
|
-
serialize,
|
|
84
|
-
serializerRegistry,
|
|
85
|
-
SerializerRegistry,
|
|
86
|
-
CommonSchemas,
|
|
87
|
-
type JSONSchema,
|
|
88
|
-
type ResponseSchemaConfig,
|
|
89
|
-
type SerializerFunction,
|
|
90
|
-
type SerializerOptions
|
|
91
|
-
} from './serializer';
|
|
92
|
-
|
|
93
|
-
// Re-export Zod for convenience
|
|
94
|
-
export { z } from 'zod';
|
package/src/core/middleware.ts
DELETED
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type-safe middleware system
|
|
3
|
-
* Provides composable middleware with automatic error handling
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { Context, Middleware, Handler, Response, Next, LifecycleHooks } from './types';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Middleware executor
|
|
10
|
-
* Executes a chain of middleware and the final handler
|
|
11
|
-
*/
|
|
12
|
-
export class MiddlewareExecutor {
|
|
13
|
-
/**
|
|
14
|
-
* Execute middleware chain with a final handler
|
|
15
|
-
* Optimized: skip recursion when no middleware
|
|
16
|
-
*/
|
|
17
|
-
async execute(
|
|
18
|
-
ctx: Context,
|
|
19
|
-
middlewares: Middleware[],
|
|
20
|
-
handler: Handler,
|
|
21
|
-
deps: any = {}
|
|
22
|
-
): Promise<Response> {
|
|
23
|
-
const len = middlewares.length;
|
|
24
|
-
|
|
25
|
-
// Fast path: no middleware - call handler directly
|
|
26
|
-
if (len === 0) {
|
|
27
|
-
return this.executeHandler(ctx, handler, deps);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Single middleware - no recursion needed
|
|
31
|
-
if (len === 1) {
|
|
32
|
-
return middlewares[0](ctx, async (c) => this.executeHandler(c, handler, deps), deps);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Multiple middleware - use optimized loop
|
|
36
|
-
let index = 0;
|
|
37
|
-
|
|
38
|
-
const next: Next = async (currentCtx: Context): Promise<Response> => {
|
|
39
|
-
if (index < len) {
|
|
40
|
-
const middleware = middlewares[index++];
|
|
41
|
-
return middleware(currentCtx, next, deps);
|
|
42
|
-
}
|
|
43
|
-
return this.executeHandler(currentCtx, handler, deps);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
return next(ctx);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Execute handler and normalize response - inlined for performance
|
|
51
|
-
*/
|
|
52
|
-
private async executeHandler(ctx: Context, handler: Handler, deps: any): Promise<Response> {
|
|
53
|
-
const result = await handler(ctx, deps);
|
|
54
|
-
|
|
55
|
-
// If handler returns an Error, throw it
|
|
56
|
-
if (result instanceof Error) {
|
|
57
|
-
(result as any)._isIntentional = true;
|
|
58
|
-
throw result;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Fast path: already a Response
|
|
62
|
-
if (result && typeof result === 'object' && 'statusCode' in result && 'body' in result) {
|
|
63
|
-
return result as Response;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Wrap in JSON response
|
|
67
|
-
return ctx.json(result);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Execute middleware chain with lifecycle hooks
|
|
72
|
-
* This method integrates hooks at the appropriate points in the request lifecycle
|
|
73
|
-
* Optimized to check hooks existence only once
|
|
74
|
-
*/
|
|
75
|
-
async executeWithHooks(
|
|
76
|
-
ctx: Context,
|
|
77
|
-
middlewares: Middleware[],
|
|
78
|
-
handler: Handler,
|
|
79
|
-
hooks: LifecycleHooks,
|
|
80
|
-
deps: any = {}
|
|
81
|
-
): Promise<Response> {
|
|
82
|
-
// Check if we have any hooks at all (optimization)
|
|
83
|
-
const hasHooks = hooks.beforeValidation || hooks.afterValidation ||
|
|
84
|
-
hooks.beforeHandler || hooks.afterHandler;
|
|
85
|
-
|
|
86
|
-
// Fast path: no hooks and no middleware
|
|
87
|
-
if (!hasHooks && middlewares.length === 0) {
|
|
88
|
-
return this.executeHandler(ctx, handler, deps);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Fast path: no hooks but has middleware
|
|
92
|
-
if (!hasHooks) {
|
|
93
|
-
return this.execute(ctx, middlewares, handler, deps);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
let index = 0;
|
|
97
|
-
const len = middlewares.length;
|
|
98
|
-
|
|
99
|
-
const next: Next = async (currentCtx: Context): Promise<Response> => {
|
|
100
|
-
if (index < len) {
|
|
101
|
-
const middleware = middlewares[index++];
|
|
102
|
-
return middleware(currentCtx, next, deps);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// All middleware executed, now run handler with hooks
|
|
106
|
-
|
|
107
|
-
// === HOOK: beforeValidation ===
|
|
108
|
-
if (hooks.beforeValidation) {
|
|
109
|
-
const hookResult = await hooks.beforeValidation(currentCtx);
|
|
110
|
-
if (hookResult && typeof hookResult === 'object' && 'statusCode' in hookResult) {
|
|
111
|
-
return hookResult as Response;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// === HOOK: afterValidation ===
|
|
116
|
-
if (hooks.afterValidation) {
|
|
117
|
-
const hookResult = await hooks.afterValidation(currentCtx);
|
|
118
|
-
if (hookResult && typeof hookResult === 'object' && 'statusCode' in hookResult) {
|
|
119
|
-
return hookResult as Response;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// === HOOK: beforeHandler ===
|
|
124
|
-
if (hooks.beforeHandler) {
|
|
125
|
-
const hookResult = await hooks.beforeHandler(currentCtx);
|
|
126
|
-
if (hookResult && typeof hookResult === 'object' && 'statusCode' in hookResult) {
|
|
127
|
-
return hookResult as Response;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Execute the handler with dependencies
|
|
132
|
-
let result = await handler(currentCtx, deps);
|
|
133
|
-
|
|
134
|
-
// If handler returns an Error, throw it
|
|
135
|
-
if (result instanceof Error) {
|
|
136
|
-
(result as any)._isIntentional = true;
|
|
137
|
-
throw result;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// === HOOK: afterHandler ===
|
|
141
|
-
if (hooks.afterHandler) {
|
|
142
|
-
const transformedResult = await hooks.afterHandler(currentCtx, result);
|
|
143
|
-
if (transformedResult !== undefined) {
|
|
144
|
-
result = transformedResult;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// If result is a Response, return it
|
|
149
|
-
if (result && typeof result === 'object' && 'statusCode' in result && 'body' in result) {
|
|
150
|
-
return result as Response;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Otherwise, wrap in JSON response
|
|
154
|
-
return currentCtx.json(result);
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
return next(ctx);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Compose multiple middleware into a single middleware function
|
|
162
|
-
*/
|
|
163
|
-
compose(middlewares: Middleware[]): Middleware {
|
|
164
|
-
return async (ctx: Context, next: Next, deps: any): Promise<Response> => {
|
|
165
|
-
let index = 0;
|
|
166
|
-
|
|
167
|
-
const dispatch = async (i: number, currentCtx: Context): Promise<Response> => {
|
|
168
|
-
if (i >= middlewares.length) {
|
|
169
|
-
return next(currentCtx);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const middleware = middlewares[i];
|
|
173
|
-
index = i + 1;
|
|
174
|
-
|
|
175
|
-
return middleware(currentCtx, (nextCtx) => dispatch(index, nextCtx), deps);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
return dispatch(0, ctx);
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Check if value is a Response object
|
|
184
|
-
*/
|
|
185
|
-
private isResponse(value: any): value is Response {
|
|
186
|
-
return (
|
|
187
|
-
value &&
|
|
188
|
-
typeof value === 'object' &&
|
|
189
|
-
'statusCode' in value &&
|
|
190
|
-
'headers' in value &&
|
|
191
|
-
'body' in value
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Built-in middleware utilities
|
|
198
|
-
*/
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Logger middleware
|
|
202
|
-
*/
|
|
203
|
-
export function logger(): Middleware {
|
|
204
|
-
return async (ctx, next, _deps) => {
|
|
205
|
-
const start = Date.now();
|
|
206
|
-
console.log(`--> ${ctx.method} ${ctx.path}`);
|
|
207
|
-
|
|
208
|
-
try {
|
|
209
|
-
const response = await next(ctx);
|
|
210
|
-
const duration = Date.now() - start;
|
|
211
|
-
console.log(`<-- ${ctx.method} ${ctx.path} ${response.statusCode} ${duration}ms`);
|
|
212
|
-
return response;
|
|
213
|
-
} catch (error) {
|
|
214
|
-
const duration = Date.now() - start;
|
|
215
|
-
console.error(`<-- ${ctx.method} ${ctx.path} ERROR ${duration}ms`);
|
|
216
|
-
throw error;
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* CORS middleware
|
|
223
|
-
*/
|
|
224
|
-
export function cors(options: {
|
|
225
|
-
origin?: string | string[];
|
|
226
|
-
methods?: string[];
|
|
227
|
-
credentials?: boolean;
|
|
228
|
-
maxAge?: number;
|
|
229
|
-
} = {}): Middleware {
|
|
230
|
-
const {
|
|
231
|
-
origin = '*',
|
|
232
|
-
methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
|
|
233
|
-
credentials = false,
|
|
234
|
-
maxAge = 86400
|
|
235
|
-
} = options;
|
|
236
|
-
|
|
237
|
-
return async (ctx, next, _deps) => {
|
|
238
|
-
const response = await next(ctx);
|
|
239
|
-
|
|
240
|
-
// Set CORS headers
|
|
241
|
-
response.headers['Access-Control-Allow-Origin'] = Array.isArray(origin) ? origin.join(',') : origin;
|
|
242
|
-
response.headers['Access-Control-Allow-Methods'] = methods.join(',');
|
|
243
|
-
response.headers['Access-Control-Max-Age'] = maxAge.toString();
|
|
244
|
-
|
|
245
|
-
if (credentials) {
|
|
246
|
-
response.headers['Access-Control-Allow-Credentials'] = 'true';
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Handle preflight
|
|
250
|
-
if (ctx.method === 'OPTIONS') {
|
|
251
|
-
response.statusCode = 204;
|
|
252
|
-
response.body = '';
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return response;
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Error handling middleware wrapper
|
|
261
|
-
*/
|
|
262
|
-
export function errorHandler(
|
|
263
|
-
handler: (error: Error, ctx: Context) => Response | Promise<Response>
|
|
264
|
-
): Middleware {
|
|
265
|
-
return async (ctx, next, _deps) => {
|
|
266
|
-
try {
|
|
267
|
-
return await next(ctx);
|
|
268
|
-
} catch (error) {
|
|
269
|
-
return handler(error as Error, ctx);
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Performance optimizations - Buffer pooling
|
|
3
|
-
* Zero-copy buffer handling for request/response bodies
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Buffer pool for reusing buffers
|
|
8
|
-
*/
|
|
9
|
-
export class BufferPool {
|
|
10
|
-
private pool: Buffer[] = [];
|
|
11
|
-
private bufferSize: number;
|
|
12
|
-
private maxPoolSize: number;
|
|
13
|
-
|
|
14
|
-
constructor(bufferSize: number = 8192, maxPoolSize: number = 50) {
|
|
15
|
-
this.bufferSize = bufferSize;
|
|
16
|
-
this.maxPoolSize = maxPoolSize;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Acquire a buffer from the pool
|
|
21
|
-
*/
|
|
22
|
-
acquire(): Buffer {
|
|
23
|
-
if (this.pool.length > 0) {
|
|
24
|
-
return this.pool.pop()!;
|
|
25
|
-
}
|
|
26
|
-
return Buffer.allocUnsafe(this.bufferSize);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Release a buffer back to the pool
|
|
31
|
-
*/
|
|
32
|
-
release(buffer: Buffer): void {
|
|
33
|
-
if (this.pool.length < this.maxPoolSize && buffer.length === this.bufferSize) {
|
|
34
|
-
// Clear the buffer before returning to pool
|
|
35
|
-
buffer.fill(0);
|
|
36
|
-
this.pool.push(buffer);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Clear the pool
|
|
42
|
-
*/
|
|
43
|
-
clear(): void {
|
|
44
|
-
this.pool = [];
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Get pool statistics
|
|
49
|
-
*/
|
|
50
|
-
getStats() {
|
|
51
|
-
return {
|
|
52
|
-
poolSize: this.pool.length,
|
|
53
|
-
maxPoolSize: this.maxPoolSize,
|
|
54
|
-
bufferSize: this.bufferSize
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Stream utilities for efficient data handling
|
|
61
|
-
*/
|
|
62
|
-
export class StreamUtils {
|
|
63
|
-
/**
|
|
64
|
-
* Read stream into buffer without copying
|
|
65
|
-
*/
|
|
66
|
-
static async readStream(stream: NodeJS.ReadableStream, maxSize?: number): Promise<Buffer> {
|
|
67
|
-
return new Promise((resolve, reject) => {
|
|
68
|
-
const chunks: Buffer[] = [];
|
|
69
|
-
let totalSize = 0;
|
|
70
|
-
|
|
71
|
-
stream.on('data', (chunk: Buffer) => {
|
|
72
|
-
totalSize += chunk.length;
|
|
73
|
-
|
|
74
|
-
if (maxSize && totalSize > maxSize) {
|
|
75
|
-
if (typeof (stream as any).destroy === 'function') {
|
|
76
|
-
(stream as any).destroy();
|
|
77
|
-
}
|
|
78
|
-
reject(new Error(`Stream size exceeds maximum of ${maxSize} bytes`));
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
chunks.push(chunk);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
stream.on('end', () => {
|
|
86
|
-
resolve(Buffer.concat(chunks));
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
stream.on('error', reject);
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Pipe stream with error handling
|
|
95
|
-
*/
|
|
96
|
-
static pipeWithErrorHandling(
|
|
97
|
-
source: NodeJS.ReadableStream,
|
|
98
|
-
destination: NodeJS.WritableStream
|
|
99
|
-
): Promise<void> {
|
|
100
|
-
return new Promise((resolve, reject) => {
|
|
101
|
-
source.pipe(destination);
|
|
102
|
-
|
|
103
|
-
source.on('error', reject);
|
|
104
|
-
destination.on('error', reject);
|
|
105
|
-
destination.on('finish', resolve);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Middleware Optimizer
|
|
3
|
-
* Provides utilities for composing and optimizing middleware chains
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { Handler, Middleware } from '../types';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Optimization statistics
|
|
10
|
-
*/
|
|
11
|
-
interface OptimizationStats {
|
|
12
|
-
cachedHandlers: number;
|
|
13
|
-
cachedMiddlewares: number;
|
|
14
|
-
composedChains: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Middleware Optimizer
|
|
19
|
-
* Caches and composes middleware chains for better performance
|
|
20
|
-
*/
|
|
21
|
-
export class MiddlewareOptimizer {
|
|
22
|
-
private handlerCache: WeakMap<Handler, Handler> = new WeakMap();
|
|
23
|
-
private middlewareCache: WeakMap<Middleware, Middleware> = new WeakMap();
|
|
24
|
-
private stats: OptimizationStats = {
|
|
25
|
-
cachedHandlers: 0,
|
|
26
|
-
cachedMiddlewares: 0,
|
|
27
|
-
composedChains: 0
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Cache a handler to avoid repeated wrapping
|
|
32
|
-
*/
|
|
33
|
-
cacheHandler(handler: Handler): Handler {
|
|
34
|
-
const cached = this.handlerCache.get(handler);
|
|
35
|
-
if (cached) return cached;
|
|
36
|
-
|
|
37
|
-
// Store reference for caching
|
|
38
|
-
this.handlerCache.set(handler, handler);
|
|
39
|
-
this.stats.cachedHandlers++;
|
|
40
|
-
|
|
41
|
-
return handler;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Cache middleware functions
|
|
46
|
-
*/
|
|
47
|
-
cacheMiddleware(middlewares: Middleware[]): Middleware[] {
|
|
48
|
-
return middlewares.map(mw => {
|
|
49
|
-
const cached = this.middlewareCache.get(mw);
|
|
50
|
-
if (cached) return cached;
|
|
51
|
-
|
|
52
|
-
this.middlewareCache.set(mw, mw);
|
|
53
|
-
this.stats.cachedMiddlewares++;
|
|
54
|
-
|
|
55
|
-
return mw;
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Compose middleware chain into single function
|
|
61
|
-
* Reduces function call overhead for frequently used routes
|
|
62
|
-
*/
|
|
63
|
-
compose(middlewares: Middleware[]): Middleware {
|
|
64
|
-
if (middlewares.length === 0) {
|
|
65
|
-
return async (ctx, next, _deps) => next(ctx);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (middlewares.length === 1) {
|
|
69
|
-
return middlewares[0];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
this.stats.composedChains++;
|
|
73
|
-
|
|
74
|
-
// Create composed middleware that reduces call stack depth
|
|
75
|
-
return async (ctx, next, deps) => {
|
|
76
|
-
let index = 0;
|
|
77
|
-
|
|
78
|
-
const dispatch = async (currentCtx: any): Promise<any> => {
|
|
79
|
-
if (index >= middlewares.length) {
|
|
80
|
-
return next(currentCtx);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const mw = middlewares[index++];
|
|
84
|
-
return mw(currentCtx, dispatch, deps);
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
return dispatch(ctx);
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Get optimization statistics
|
|
93
|
-
*/
|
|
94
|
-
getStats(): OptimizationStats {
|
|
95
|
-
return { ...this.stats };
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Clear caches
|
|
100
|
-
*/
|
|
101
|
-
clearCache(): void {
|
|
102
|
-
this.handlerCache = new WeakMap();
|
|
103
|
-
this.middlewareCache = new WeakMap();
|
|
104
|
-
this.stats.cachedHandlers = 0;
|
|
105
|
-
this.stats.cachedMiddlewares = 0;
|
|
106
|
-
this.stats.composedChains = 0;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Performance monitoring utilities
|
|
112
|
-
*/
|
|
113
|
-
export class PerformanceMonitor {
|
|
114
|
-
private metrics: Map<string, { count: number; totalTime: number; avgTime: number }> = new Map();
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Measure execution time of a function
|
|
118
|
-
*/
|
|
119
|
-
async measure<T>(name: string, fn: () => Promise<T>): Promise<T> {
|
|
120
|
-
const start = performance.now();
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
return await fn();
|
|
124
|
-
} finally {
|
|
125
|
-
const duration = performance.now() - start;
|
|
126
|
-
this.recordMetric(name, duration);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Record a metric
|
|
132
|
-
*/
|
|
133
|
-
private recordMetric(name: string, duration: number): void {
|
|
134
|
-
const existing = this.metrics.get(name);
|
|
135
|
-
|
|
136
|
-
if (existing) {
|
|
137
|
-
existing.count++;
|
|
138
|
-
existing.totalTime += duration;
|
|
139
|
-
existing.avgTime = existing.totalTime / existing.count;
|
|
140
|
-
} else {
|
|
141
|
-
this.metrics.set(name, {
|
|
142
|
-
count: 1,
|
|
143
|
-
totalTime: duration,
|
|
144
|
-
avgTime: duration
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Get all metrics
|
|
151
|
-
*/
|
|
152
|
-
getMetrics() {
|
|
153
|
-
return Object.fromEntries(this.metrics);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Clear metrics
|
|
158
|
-
*/
|
|
159
|
-
clearMetrics(): void {
|
|
160
|
-
this.metrics.clear();
|
|
161
|
-
}
|
|
162
|
-
}
|