@engjts/nexus 0.1.7 → 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/dist/advanced/playground/generatePlaygroundHTML.d.ts.map +1 -1
- package/dist/advanced/playground/generatePlaygroundHTML.js +107 -0
- package/dist/advanced/playground/generatePlaygroundHTML.js.map +1 -1
- package/dist/advanced/playground/playground.d.ts +19 -0
- package/dist/advanced/playground/playground.d.ts.map +1 -1
- package/dist/advanced/playground/playground.js +70 -0
- package/dist/advanced/playground/playground.js.map +1 -1
- package/dist/advanced/playground/types.d.ts +20 -0
- package/dist/advanced/playground/types.d.ts.map +1 -1
- package/dist/core/application.d.ts +14 -0
- package/dist/core/application.d.ts.map +1 -1
- package/dist/core/application.js +173 -71
- package/dist/core/application.js.map +1 -1
- package/dist/core/context-pool.d.ts +2 -13
- package/dist/core/context-pool.d.ts.map +1 -1
- package/dist/core/context-pool.js +7 -45
- package/dist/core/context-pool.js.map +1 -1
- package/dist/core/context.d.ts +108 -5
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +449 -53
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +9 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/middleware.d.ts +6 -0
- package/dist/core/middleware.d.ts.map +1 -1
- package/dist/core/middleware.js +83 -84
- package/dist/core/middleware.js.map +1 -1
- package/dist/core/performance/fast-json.d.ts +149 -0
- package/dist/core/performance/fast-json.d.ts.map +1 -0
- package/dist/core/performance/fast-json.js +473 -0
- package/dist/core/performance/fast-json.js.map +1 -0
- package/dist/core/router/file-router.d.ts +20 -7
- package/dist/core/router/file-router.d.ts.map +1 -1
- package/dist/core/router/file-router.js +41 -13
- package/dist/core/router/file-router.js.map +1 -1
- package/dist/core/router/index.d.ts +6 -0
- package/dist/core/router/index.d.ts.map +1 -1
- package/dist/core/router/index.js +33 -6
- package/dist/core/router/index.js.map +1 -1
- package/dist/core/router/radix-tree.d.ts +4 -1
- package/dist/core/router/radix-tree.d.ts.map +1 -1
- package/dist/core/router/radix-tree.js +7 -3
- package/dist/core/router/radix-tree.js.map +1 -1
- package/dist/core/serializer.d.ts +251 -0
- package/dist/core/serializer.d.ts.map +1 -0
- package/dist/core/serializer.js +290 -0
- package/dist/core/serializer.js.map +1 -0
- package/dist/core/types.d.ts +39 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- 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 -1849
- 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 -170
- package/src/advanced/playground/types.ts +0 -20
- 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 -1335
- package/src/core/context-pool.ts +0 -127
- package/src/core/context.ts +0 -412
- package/src/core/index.ts +0 -80
- package/src/core/middleware.ts +0 -262
- 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 -594
- package/src/core/router/index.ts +0 -227
- package/src/core/router/radix-tree.ts +0 -226
- 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 -574
- 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 -264
- 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/context-pool.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Context pooling for performance optimization
|
|
3
|
-
* Reuses context objects to reduce garbage collection pressure
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { IncomingMessage, ServerResponse } from 'http';
|
|
7
|
-
import { ContextImpl, parseBody } from './context';
|
|
8
|
-
import { Context } from './types';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Context pool implementation
|
|
12
|
-
* Maintains a pool of reusable context objects
|
|
13
|
-
*/
|
|
14
|
-
export class ContextPool {
|
|
15
|
-
private pool: ContextImpl[] = [];
|
|
16
|
-
private maxSize: number;
|
|
17
|
-
private created: number = 0;
|
|
18
|
-
private reused: number = 0;
|
|
19
|
-
|
|
20
|
-
constructor(maxSize: number = 100) {
|
|
21
|
-
this.maxSize = maxSize;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Acquire a context from the pool or create a new one
|
|
26
|
-
*/
|
|
27
|
-
async acquire(req: IncomingMessage, res: ServerResponse): Promise<Context> {
|
|
28
|
-
let ctx: ContextImpl;
|
|
29
|
-
|
|
30
|
-
// Try to reuse from pool
|
|
31
|
-
if (this.pool.length > 0) {
|
|
32
|
-
ctx = this.pool.pop()!;
|
|
33
|
-
this.reused++;
|
|
34
|
-
await this.reset(ctx, req, res);
|
|
35
|
-
} else {
|
|
36
|
-
// Create new context
|
|
37
|
-
ctx = new ContextImpl(req, res);
|
|
38
|
-
this.created++;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Parse body if applicable
|
|
42
|
-
if (this.hasBody(req)) {
|
|
43
|
-
const body = await parseBody(req);
|
|
44
|
-
ctx.setBody(body);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return ctx;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Release a context back to the pool
|
|
52
|
-
*/
|
|
53
|
-
release(ctx: Context): void {
|
|
54
|
-
if (this.pool.length < this.maxSize) {
|
|
55
|
-
// Clear sensitive data before pooling
|
|
56
|
-
this.clearContext(ctx as ContextImpl);
|
|
57
|
-
this.pool.push(ctx as ContextImpl);
|
|
58
|
-
}
|
|
59
|
-
// If pool is full, let GC handle it
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Reset context for reuse
|
|
64
|
-
*/
|
|
65
|
-
private async reset(
|
|
66
|
-
ctx: ContextImpl,
|
|
67
|
-
req: IncomingMessage,
|
|
68
|
-
res: ServerResponse
|
|
69
|
-
): Promise<void> {
|
|
70
|
-
// Recreate the context with new request/response
|
|
71
|
-
const newCtx = new ContextImpl(req, res);
|
|
72
|
-
|
|
73
|
-
// Copy properties
|
|
74
|
-
Object.assign(ctx, newCtx);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Clear sensitive data from context
|
|
79
|
-
*/
|
|
80
|
-
private clearContext(ctx: ContextImpl): void {
|
|
81
|
-
ctx.params = {};
|
|
82
|
-
ctx.query = {};
|
|
83
|
-
ctx.body = null;
|
|
84
|
-
|
|
85
|
-
// Clear custom properties added by middleware
|
|
86
|
-
const knownProps = new Set([
|
|
87
|
-
'method', 'path', 'url', 'params', 'query', 'body',
|
|
88
|
-
'headers', 'cookies', 'raw', 'response',
|
|
89
|
-
'json', 'html', 'text', 'redirect', 'stream',
|
|
90
|
-
'setParams', 'setBody', 'getSetCookieHeaders'
|
|
91
|
-
]);
|
|
92
|
-
|
|
93
|
-
for (const key in ctx) {
|
|
94
|
-
if (!knownProps.has(key)) {
|
|
95
|
-
delete (ctx as any)[key];
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Check if request has a body
|
|
102
|
-
*/
|
|
103
|
-
private hasBody(req: IncomingMessage): boolean {
|
|
104
|
-
const method = req.method?.toUpperCase();
|
|
105
|
-
return method === 'POST' || method === 'PUT' || method === 'PATCH';
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Get pool statistics
|
|
110
|
-
*/
|
|
111
|
-
getStats() {
|
|
112
|
-
return {
|
|
113
|
-
poolSize: this.pool.length,
|
|
114
|
-
maxSize: this.maxSize,
|
|
115
|
-
created: this.created,
|
|
116
|
-
reused: this.reused,
|
|
117
|
-
hitRate: this.created > 0 ? this.reused / (this.created + this.reused) : 0
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Clear the entire pool
|
|
123
|
-
*/
|
|
124
|
-
clear(): void {
|
|
125
|
-
this.pool = [];
|
|
126
|
-
}
|
|
127
|
-
}
|
package/src/core/context.ts
DELETED
|
@@ -1,412 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Context implementation
|
|
3
|
-
* Provides a unified request/response context with immutable properties
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { IncomingMessage, ServerResponse } from 'http';
|
|
7
|
-
import { parse as parseUrl } from 'url';
|
|
8
|
-
import { parse as parseQueryString } from 'querystring';
|
|
9
|
-
import {
|
|
10
|
-
Context,
|
|
11
|
-
Headers,
|
|
12
|
-
Cookies,
|
|
13
|
-
CookieOptions,
|
|
14
|
-
ResponseBuilder,
|
|
15
|
-
Response,
|
|
16
|
-
HTTPMethod
|
|
17
|
-
} from './types';
|
|
18
|
-
import { ContextStore, StoreConstructor, StoreRegistry, RequestStore, RequestStoreConstructor, RequestStoreRegistry } from './store';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Cookie manager implementation
|
|
22
|
-
*/
|
|
23
|
-
class CookieManager implements Cookies {
|
|
24
|
-
private cookies: Map<string, string>;
|
|
25
|
-
private setCookies: Array<{ name: string; value: string; options?: CookieOptions }> = [];
|
|
26
|
-
|
|
27
|
-
constructor(cookieHeader?: string) {
|
|
28
|
-
this.cookies = new Map();
|
|
29
|
-
if (cookieHeader) {
|
|
30
|
-
const pairs = cookieHeader.split(';');
|
|
31
|
-
for (const pair of pairs) {
|
|
32
|
-
const [name, value] = pair.trim().split('=');
|
|
33
|
-
if (name && value) {
|
|
34
|
-
this.cookies.set(name, decodeURIComponent(value));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
get(name: string): string | undefined {
|
|
41
|
-
return this.cookies.get(name);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
set(name: string, value: string, options?: CookieOptions): void {
|
|
45
|
-
this.cookies.set(name, value);
|
|
46
|
-
this.setCookies.push({ name, value, options });
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
delete(name: string): void {
|
|
50
|
-
this.cookies.delete(name);
|
|
51
|
-
this.setCookies.push({
|
|
52
|
-
name,
|
|
53
|
-
value: '',
|
|
54
|
-
options: { expires: new Date(0) }
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
getSetCookieHeaders(): string[] {
|
|
59
|
-
return this.setCookies.map(({ name, value, options }) => {
|
|
60
|
-
let cookie = `${name}=${encodeURIComponent(value)}`;
|
|
61
|
-
|
|
62
|
-
if (options) {
|
|
63
|
-
if (options.maxAge) cookie += `; Max-Age=${options.maxAge}`;
|
|
64
|
-
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
65
|
-
if (options.path) cookie += `; Path=${options.path}`;
|
|
66
|
-
if (options.domain) cookie += `; Domain=${options.domain}`;
|
|
67
|
-
if (options.secure) cookie += '; Secure';
|
|
68
|
-
if (options.httpOnly) cookie += '; HttpOnly';
|
|
69
|
-
if (options.sameSite) cookie += `; SameSite=${options.sameSite}`;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return cookie;
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Response builder implementation
|
|
79
|
-
*/
|
|
80
|
-
class ResponseBuilderImpl implements ResponseBuilder {
|
|
81
|
-
private _status: number = 200;
|
|
82
|
-
private _headers: Headers = {};
|
|
83
|
-
|
|
84
|
-
status(code: number): ResponseBuilder {
|
|
85
|
-
this._status = code;
|
|
86
|
-
return this;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
header(name: string, value: string): ResponseBuilder {
|
|
90
|
-
this._headers[name] = value;
|
|
91
|
-
return this;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
json<T>(data: T): Response {
|
|
95
|
-
return {
|
|
96
|
-
statusCode: this._status,
|
|
97
|
-
headers: {
|
|
98
|
-
...this._headers,
|
|
99
|
-
'Content-Type': 'application/json'
|
|
100
|
-
},
|
|
101
|
-
body: JSON.stringify(data)
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
html(content: string): Response {
|
|
106
|
-
return {
|
|
107
|
-
statusCode: this._status,
|
|
108
|
-
headers: {
|
|
109
|
-
...this._headers,
|
|
110
|
-
'Content-Type': 'text/html; charset=utf-8'
|
|
111
|
-
},
|
|
112
|
-
body: content
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
text(content: string): Response {
|
|
117
|
-
return {
|
|
118
|
-
statusCode: this._status,
|
|
119
|
-
headers: {
|
|
120
|
-
...this._headers,
|
|
121
|
-
'Content-Type': 'text/plain; charset=utf-8'
|
|
122
|
-
},
|
|
123
|
-
body: content
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
redirect(url: string, status: number = 302): Response {
|
|
128
|
-
return {
|
|
129
|
-
statusCode: status,
|
|
130
|
-
headers: {
|
|
131
|
-
...this._headers,
|
|
132
|
-
'Location': url
|
|
133
|
-
},
|
|
134
|
-
body: ''
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
stream(readable: NodeJS.ReadableStream): Response {
|
|
139
|
-
return {
|
|
140
|
-
statusCode: this._status,
|
|
141
|
-
headers: this._headers,
|
|
142
|
-
body: null,
|
|
143
|
-
stream: readable
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Context implementation
|
|
150
|
-
*/
|
|
151
|
-
export class ContextImpl implements Context {
|
|
152
|
-
method: HTTPMethod;
|
|
153
|
-
path: string;
|
|
154
|
-
url: URL;
|
|
155
|
-
params: Record<string, string> = {};
|
|
156
|
-
query: Record<string, any> = {};
|
|
157
|
-
body: any = null;
|
|
158
|
-
headers: Headers;
|
|
159
|
-
cookies: Cookies;
|
|
160
|
-
raw: { req: IncomingMessage; res: ServerResponse };
|
|
161
|
-
response: ResponseBuilder;
|
|
162
|
-
|
|
163
|
-
// Store registry reference (set by Application)
|
|
164
|
-
private _storeRegistry?: StoreRegistry;
|
|
165
|
-
|
|
166
|
-
// Request-scoped store registry (created per request)
|
|
167
|
-
private _requestStoreRegistry: RequestStoreRegistry;
|
|
168
|
-
|
|
169
|
-
// Request-scoped simple key-value storage
|
|
170
|
-
private _data: Map<string, any> = new Map();
|
|
171
|
-
|
|
172
|
-
// Debug mode
|
|
173
|
-
private _debug: boolean = false;
|
|
174
|
-
|
|
175
|
-
constructor(req: IncomingMessage, res: ServerResponse) {
|
|
176
|
-
this.raw = { req, res };
|
|
177
|
-
|
|
178
|
-
// Parse method
|
|
179
|
-
this.method = (req.method?.toUpperCase() || 'GET') as HTTPMethod;
|
|
180
|
-
|
|
181
|
-
// Parse URL and query
|
|
182
|
-
const parsedUrl = parseUrl(req.url || '/', true);
|
|
183
|
-
this.path = parsedUrl.pathname || '/';
|
|
184
|
-
this.url = new URL(this.path, `http://${req.headers.host || 'localhost'}`);
|
|
185
|
-
this.query = parsedUrl.query as Record<string, any>;
|
|
186
|
-
|
|
187
|
-
// Parse headers
|
|
188
|
-
this.headers = req.headers as Headers;
|
|
189
|
-
|
|
190
|
-
// Parse cookies
|
|
191
|
-
this.cookies = new CookieManager(req.headers.cookie);
|
|
192
|
-
|
|
193
|
-
// Create response builder
|
|
194
|
-
this.response = new ResponseBuilderImpl();
|
|
195
|
-
|
|
196
|
-
// Create request-scoped store registry
|
|
197
|
-
this._requestStoreRegistry = new RequestStoreRegistry(this._debug);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Convenience methods
|
|
201
|
-
json<T>(data: T, status?: number): Response {
|
|
202
|
-
if (status !== undefined) {
|
|
203
|
-
return this.response.status(status).json(data);
|
|
204
|
-
}
|
|
205
|
-
return this.response.json(data);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
html(content: string, status?: number): Response {
|
|
209
|
-
if (status !== undefined) {
|
|
210
|
-
return this.response.status(status).html(content);
|
|
211
|
-
}
|
|
212
|
-
return this.response.html(content);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
text(content: string, status?: number): Response {
|
|
216
|
-
if (status !== undefined) {
|
|
217
|
-
return this.response.status(status).text(content);
|
|
218
|
-
}
|
|
219
|
-
return this.response.text(content);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
redirect(url: string, status?: number): Response {
|
|
223
|
-
return this.response.redirect(url, status);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
stream(readable: NodeJS.ReadableStream): Response {
|
|
227
|
-
return this.response.stream(readable);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Access a registered global store by its class
|
|
232
|
-
* Store persist across all requests (singleton)
|
|
233
|
-
*
|
|
234
|
-
* @param StoreClass - Store constructor class
|
|
235
|
-
* @returns Store instance
|
|
236
|
-
*
|
|
237
|
-
* @example
|
|
238
|
-
* ```typescript
|
|
239
|
-
* app.get('/users', async (ctx) => {
|
|
240
|
-
* const userStore = ctx.store(UserStore);
|
|
241
|
-
* return { users: userStore.state.users };
|
|
242
|
-
* });
|
|
243
|
-
* ```
|
|
244
|
-
*/
|
|
245
|
-
store<T extends ContextStore<any>>(StoreClass: StoreConstructor<T>): T {
|
|
246
|
-
if (!this._storeRegistry) {
|
|
247
|
-
throw new Error(
|
|
248
|
-
'[Context] Store registry not initialized. ' +
|
|
249
|
-
'Make sure to call app.stores([...]) before accessing stores.'
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
return this._storeRegistry.get(StoreClass);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Access a request-scoped store by its class
|
|
257
|
-
* Store only exists for this request, disposed after response
|
|
258
|
-
*
|
|
259
|
-
* @param StoreClass - RequestStore constructor class
|
|
260
|
-
* @returns Store instance (created on first access)
|
|
261
|
-
*
|
|
262
|
-
* @example
|
|
263
|
-
* ```typescript
|
|
264
|
-
* class CheckoutStore extends RequestStore<CheckoutState> {
|
|
265
|
-
* protected initial() { return { items: [], total: 0 }; }
|
|
266
|
-
*
|
|
267
|
-
* addItem(item: Item) {
|
|
268
|
-
* this.update({
|
|
269
|
-
* items: [...this.state.items, item],
|
|
270
|
-
* total: this.state.total + item.price
|
|
271
|
-
* });
|
|
272
|
-
* }
|
|
273
|
-
* }
|
|
274
|
-
*
|
|
275
|
-
* app.post('/checkout', async (ctx) => {
|
|
276
|
-
* const checkout = ctx.requestStore(CheckoutStore);
|
|
277
|
-
* checkout.addItem(ctx.body.item);
|
|
278
|
-
* return { total: checkout.state.total };
|
|
279
|
-
* });
|
|
280
|
-
* // checkout store is automatically disposed after response
|
|
281
|
-
* ```
|
|
282
|
-
*/
|
|
283
|
-
requestStore<T extends RequestStore<any>>(StoreClass: RequestStoreConstructor<T>): T {
|
|
284
|
-
return this._requestStoreRegistry.get(StoreClass);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Set a value in request-scoped storage
|
|
289
|
-
* Data is automatically cleared after the request completes
|
|
290
|
-
*
|
|
291
|
-
* @param key - Storage key
|
|
292
|
-
* @param value - Value to store
|
|
293
|
-
*
|
|
294
|
-
* @example
|
|
295
|
-
* ```typescript
|
|
296
|
-
* // In middleware or onBefore
|
|
297
|
-
* ctx.set('user', { id: '123', name: 'John' });
|
|
298
|
-
* ctx.set('startTime', Date.now());
|
|
299
|
-
*
|
|
300
|
-
* // In handler
|
|
301
|
-
* const user = ctx.get('user');
|
|
302
|
-
* ```
|
|
303
|
-
*/
|
|
304
|
-
set<T = any>(key: string, value: T): void {
|
|
305
|
-
this._data.set(key, value);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Get a value from request-scoped storage
|
|
310
|
-
*
|
|
311
|
-
* @param key - Storage key
|
|
312
|
-
* @returns The stored value or undefined
|
|
313
|
-
*
|
|
314
|
-
* @example
|
|
315
|
-
* ```typescript
|
|
316
|
-
* const user = ctx.get<User>('user');
|
|
317
|
-
* const startTime = ctx.get<number>('startTime');
|
|
318
|
-
* ```
|
|
319
|
-
*/
|
|
320
|
-
get<T = any>(key: string): T | undefined {
|
|
321
|
-
return this._data.get(key) as T | undefined;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Set store registry (called by Application)
|
|
326
|
-
* @internal
|
|
327
|
-
*/
|
|
328
|
-
setStoreRegistry(registry: StoreRegistry): void {
|
|
329
|
-
this._storeRegistry = registry;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Set debug mode (called by Application)
|
|
334
|
-
* @internal
|
|
335
|
-
*/
|
|
336
|
-
setDebugMode(debug: boolean): void {
|
|
337
|
-
this._debug = debug;
|
|
338
|
-
// Re-create request store registry with debug mode
|
|
339
|
-
this._requestStoreRegistry = new RequestStoreRegistry(debug);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Dispose request-scoped stores and data (called after response)
|
|
344
|
-
* @internal
|
|
345
|
-
*/
|
|
346
|
-
disposeRequestStores(): void {
|
|
347
|
-
this._requestStoreRegistry.dispose();
|
|
348
|
-
this._data.clear();
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Get request store registry for advanced usage
|
|
353
|
-
* @internal
|
|
354
|
-
*/
|
|
355
|
-
getRequestStoreRegistry(): RequestStoreRegistry {
|
|
356
|
-
return this._requestStoreRegistry;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Set route parameters (called by router)
|
|
361
|
-
*/
|
|
362
|
-
setParams(params: Record<string, string>): void {
|
|
363
|
-
this.params = params;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* Set request body (called after parsing)
|
|
368
|
-
*/
|
|
369
|
-
setBody(body: any): void {
|
|
370
|
-
this.body = body;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Get all Set-Cookie headers
|
|
375
|
-
*/
|
|
376
|
-
getSetCookieHeaders(): string[] {
|
|
377
|
-
return (this.cookies as CookieManager).getSetCookieHeaders();
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Parse request body based on Content-Type
|
|
383
|
-
*/
|
|
384
|
-
export async function parseBody(req: IncomingMessage): Promise<any> {
|
|
385
|
-
return new Promise((resolve, reject) => {
|
|
386
|
-
const contentType = req.headers['content-type'] || '';
|
|
387
|
-
const chunks: Buffer[] = [];
|
|
388
|
-
|
|
389
|
-
req.on('data', (chunk: Buffer) => chunks.push(chunk));
|
|
390
|
-
|
|
391
|
-
req.on('end', () => {
|
|
392
|
-
try {
|
|
393
|
-
const buffer = Buffer.concat(chunks);
|
|
394
|
-
const body = buffer.toString('utf-8');
|
|
395
|
-
|
|
396
|
-
if (contentType.includes('application/json')) {
|
|
397
|
-
resolve(body ? JSON.parse(body) : {});
|
|
398
|
-
} else if (contentType.includes('application/x-www-form-urlencoded')) {
|
|
399
|
-
resolve(parseQueryString(body));
|
|
400
|
-
} else if (contentType.includes('text/')) {
|
|
401
|
-
resolve(body);
|
|
402
|
-
} else {
|
|
403
|
-
resolve(buffer);
|
|
404
|
-
}
|
|
405
|
-
} catch (error) {
|
|
406
|
-
reject(error);
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
req.on('error', reject);
|
|
411
|
-
});
|
|
412
|
-
}
|
package/src/core/index.ts
DELETED
|
@@ -1,80 +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
|
-
// Re-export Zod for convenience
|
|
80
|
-
export { z } from 'zod';
|