@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
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { Application } from '../../core/application';
|
|
2
|
-
import { RouteConfig, HTTPMethod, Context, Plugin } from '../../core/types';
|
|
3
|
-
import { generateCollection } from './generateCollection';
|
|
4
|
-
import { generateEnvironment } from './generateEnvironment';
|
|
5
|
-
import { slugify } from './slugify';
|
|
6
|
-
import { PostmanConfig, StoredRoute } from './types';
|
|
7
|
-
|
|
8
|
-
// ============================================
|
|
9
|
-
// POSTMAN FEATURE (PLUGIN)
|
|
10
|
-
// ============================================
|
|
11
|
-
/**
|
|
12
|
-
* Create Postman feature plugin for Nexus
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
export function postman(config: PostmanConfig = {}): Plugin {
|
|
16
|
-
const resolvedConfig: PostmanConfig = {
|
|
17
|
-
path: '/postman',
|
|
18
|
-
name: 'API Collection',
|
|
19
|
-
description: 'Auto-generated Postman collection',
|
|
20
|
-
environmentName: 'API Environment',
|
|
21
|
-
includeExamples: true,
|
|
22
|
-
...config
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const routes: StoredRoute[] = [];
|
|
26
|
-
let detectedBaseUrl = '';
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
name: 'postman',
|
|
30
|
-
version: '1.0.0',
|
|
31
|
-
|
|
32
|
-
install(app: Application) {
|
|
33
|
-
// Hook into route registration
|
|
34
|
-
const originalRoute = app.route.bind(app);
|
|
35
|
-
const originalGet = app.get.bind(app);
|
|
36
|
-
const originalPost = app.post.bind(app);
|
|
37
|
-
const originalPut = app.put.bind(app);
|
|
38
|
-
const originalDelete = app.delete.bind(app);
|
|
39
|
-
const originalPatch = app.patch.bind(app);
|
|
40
|
-
|
|
41
|
-
app.route = function (routeConfig: RouteConfig) {
|
|
42
|
-
routes.push({
|
|
43
|
-
method: routeConfig.method,
|
|
44
|
-
path: routeConfig.path,
|
|
45
|
-
schema: routeConfig.schema,
|
|
46
|
-
meta: routeConfig.meta
|
|
47
|
-
});
|
|
48
|
-
return originalRoute(routeConfig);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const wrapMethod = (method: HTTPMethod, original: Function) => {
|
|
52
|
-
return function (pathOrRoute: string | any, handlerOrConfig?: any) {
|
|
53
|
-
// Class-based routing
|
|
54
|
-
if (typeof pathOrRoute === 'object' && 'pathName' in pathOrRoute) {
|
|
55
|
-
const route = pathOrRoute;
|
|
56
|
-
routes.push({
|
|
57
|
-
method,
|
|
58
|
-
path: route.pathName,
|
|
59
|
-
schema: route.schema?.(),
|
|
60
|
-
meta: route.meta?.()
|
|
61
|
-
});
|
|
62
|
-
return original(pathOrRoute);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const path = pathOrRoute;
|
|
66
|
-
if (typeof handlerOrConfig !== 'function' && handlerOrConfig) {
|
|
67
|
-
routes.push({
|
|
68
|
-
method,
|
|
69
|
-
path,
|
|
70
|
-
schema: handlerOrConfig.schema,
|
|
71
|
-
meta: handlerOrConfig.meta
|
|
72
|
-
});
|
|
73
|
-
} else {
|
|
74
|
-
routes.push({ method, path });
|
|
75
|
-
}
|
|
76
|
-
return original(path, handlerOrConfig);
|
|
77
|
-
};
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
app.get = wrapMethod('GET', originalGet);
|
|
81
|
-
app.post = wrapMethod('POST', originalPost);
|
|
82
|
-
app.put = wrapMethod('PUT', originalPut);
|
|
83
|
-
app.delete = wrapMethod('DELETE', originalDelete);
|
|
84
|
-
app.patch = wrapMethod('PATCH', originalPatch);
|
|
85
|
-
|
|
86
|
-
const basePath = resolvedConfig.path!;
|
|
87
|
-
|
|
88
|
-
// GET /postman → Download collection
|
|
89
|
-
originalGet(basePath, async (ctx: Context) => {
|
|
90
|
-
// Auto-detect base URL
|
|
91
|
-
if (!detectedBaseUrl && ctx.raw?.req) {
|
|
92
|
-
const req = ctx.raw.req;
|
|
93
|
-
const protocol = req.headers['x-forwarded-proto'] || 'http';
|
|
94
|
-
const host = req.headers.host || 'localhost:3000';
|
|
95
|
-
detectedBaseUrl = `${protocol}://${host}`;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const baseUrl = resolvedConfig.baseUrl || detectedBaseUrl || 'http://localhost:3000';
|
|
99
|
-
const collection = generateCollection(routes, resolvedConfig, baseUrl);
|
|
100
|
-
const filename = `${slugify(resolvedConfig.name!)}_collection.json`;
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
statusCode: 200,
|
|
104
|
-
headers: {
|
|
105
|
-
'Content-Type': 'application/json',
|
|
106
|
-
'Content-Disposition': `attachment; filename="${filename}"`
|
|
107
|
-
},
|
|
108
|
-
body: JSON.stringify(collection, null, 2)
|
|
109
|
-
};
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
// GET /postman/environment → Download environment
|
|
113
|
-
originalGet(basePath + '/environment', async (ctx: Context) => {
|
|
114
|
-
if (!detectedBaseUrl && ctx.raw?.req) {
|
|
115
|
-
const req = ctx.raw.req;
|
|
116
|
-
const protocol = req.headers['x-forwarded-proto'] || 'http';
|
|
117
|
-
const host = req.headers.host || 'localhost:3000';
|
|
118
|
-
detectedBaseUrl = `${protocol}://${host}`;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const baseUrl = resolvedConfig.baseUrl || detectedBaseUrl || 'http://localhost:3000';
|
|
122
|
-
const environment = generateEnvironment(resolvedConfig, baseUrl);
|
|
123
|
-
const filename = `${slugify(resolvedConfig.environmentName!)}_environment.json`;
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
statusCode: 200,
|
|
127
|
-
headers: {
|
|
128
|
-
'Content-Type': 'application/json',
|
|
129
|
-
'Content-Disposition': `attachment; filename="${filename}"`
|
|
130
|
-
},
|
|
131
|
-
body: JSON.stringify(environment, null, 2)
|
|
132
|
-
};
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// GET /postman/preview → Preview collection (no download)
|
|
136
|
-
originalGet(basePath + '/preview', async (ctx: Context) => {
|
|
137
|
-
if (!detectedBaseUrl && ctx.raw?.req) {
|
|
138
|
-
const req = ctx.raw.req;
|
|
139
|
-
const protocol = req.headers['x-forwarded-proto'] || 'http';
|
|
140
|
-
const host = req.headers.host || 'localhost:3000';
|
|
141
|
-
detectedBaseUrl = `${protocol}://${host}`;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const baseUrl = resolvedConfig.baseUrl || detectedBaseUrl || 'http://localhost:3000';
|
|
145
|
-
const collection = generateCollection(routes, resolvedConfig, baseUrl);
|
|
146
|
-
|
|
147
|
-
return ctx.json(collection);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
if (process.env.DEBUG === 'true' || process.env.NODE_ENV === 'development') {
|
|
151
|
-
console.log(`📦 Postman Collection: ${basePath}`);
|
|
152
|
-
console.log(`🌍 Postman Environment: ${basePath}/environment`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { HTTPMethod, SchemaConfig, RouteMeta } from '../../core/types';
|
|
2
|
-
|
|
3
|
-
// ============================================
|
|
4
|
-
// TYPES & INTERFACES
|
|
5
|
-
// ============================================
|
|
6
|
-
/**
|
|
7
|
-
* Postman configuration options
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export interface PostmanConfig {
|
|
11
|
-
/** Path to serve Postman endpoints (default: /postman) */
|
|
12
|
-
path?: string;
|
|
13
|
-
/** Collection name */
|
|
14
|
-
name?: string;
|
|
15
|
-
/** Collection description */
|
|
16
|
-
description?: string;
|
|
17
|
-
/** Base URL for requests (auto-detected if not provided) */
|
|
18
|
-
baseUrl?: string;
|
|
19
|
-
/** Environment name */
|
|
20
|
-
environmentName?: string;
|
|
21
|
-
/** Additional environment variables */
|
|
22
|
-
variables?: Record<string, string>;
|
|
23
|
-
/** Auth type for collection */
|
|
24
|
-
auth?: PostmanAuth;
|
|
25
|
-
/** Include example responses */
|
|
26
|
-
includeExamples?: boolean;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Postman auth configuration
|
|
32
|
-
*/
|
|
33
|
-
export interface PostmanAuth {
|
|
34
|
-
type: 'bearer' | 'apikey' | 'basic' | 'oauth2';
|
|
35
|
-
bearer?: { token: string };
|
|
36
|
-
apikey?: { key: string; value: string; in: 'header' | 'query' };
|
|
37
|
-
basic?: { username: string; password: string };
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Postman Collection v2.1 format
|
|
42
|
-
*/
|
|
43
|
-
export interface PostmanCollection {
|
|
44
|
-
info: {
|
|
45
|
-
_postman_id: string;
|
|
46
|
-
name: string;
|
|
47
|
-
description?: string;
|
|
48
|
-
schema: string;
|
|
49
|
-
};
|
|
50
|
-
item: PostmanItem[];
|
|
51
|
-
auth?: any;
|
|
52
|
-
variable?: PostmanVariable[];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface PostmanItem {
|
|
56
|
-
name: string;
|
|
57
|
-
item?: PostmanItem[];
|
|
58
|
-
request?: PostmanRequest;
|
|
59
|
-
response?: PostmanResponse[];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface PostmanRequest {
|
|
63
|
-
method: string;
|
|
64
|
-
header: PostmanHeader[];
|
|
65
|
-
url: PostmanUrl;
|
|
66
|
-
body?: PostmanBody;
|
|
67
|
-
description?: string;
|
|
68
|
-
auth?: any;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface PostmanHeader {
|
|
72
|
-
key: string;
|
|
73
|
-
value: string;
|
|
74
|
-
type: string;
|
|
75
|
-
disabled?: boolean;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface PostmanUrl {
|
|
79
|
-
raw: string;
|
|
80
|
-
host: string[];
|
|
81
|
-
path: string[];
|
|
82
|
-
query?: PostmanQuery[];
|
|
83
|
-
variable?: PostmanVariable[];
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface PostmanQuery {
|
|
87
|
-
key: string;
|
|
88
|
-
value: string;
|
|
89
|
-
disabled?: boolean;
|
|
90
|
-
description?: string;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export interface PostmanVariable {
|
|
94
|
-
key: string;
|
|
95
|
-
value: string;
|
|
96
|
-
type?: string;
|
|
97
|
-
description?: string;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export interface PostmanBody {
|
|
101
|
-
mode: 'raw' | 'formdata' | 'urlencoded';
|
|
102
|
-
raw?: string;
|
|
103
|
-
options?: {
|
|
104
|
-
raw: { language: string };
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface PostmanResponse {
|
|
109
|
-
name: string;
|
|
110
|
-
status: string;
|
|
111
|
-
code: number;
|
|
112
|
-
body?: string;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Postman Environment format
|
|
117
|
-
*/
|
|
118
|
-
export interface PostmanEnvironment {
|
|
119
|
-
id: string;
|
|
120
|
-
name: string;
|
|
121
|
-
values: PostmanEnvVariable[];
|
|
122
|
-
_postman_variable_scope: string;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export interface PostmanEnvVariable {
|
|
126
|
-
key: string;
|
|
127
|
-
value: string;
|
|
128
|
-
type: string;
|
|
129
|
-
enabled: boolean;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Internal route storage
|
|
134
|
-
*/
|
|
135
|
-
export interface StoredRoute {
|
|
136
|
-
method: HTTPMethod;
|
|
137
|
-
path: string;
|
|
138
|
-
schema?: SchemaConfig;
|
|
139
|
-
meta?: RouteMeta;
|
|
140
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Nexus Realtime Module
|
|
3
|
-
*
|
|
4
|
-
* Optional WebSocket/Realtime integration for Nexus framework.
|
|
5
|
-
* Requires `ws` as peer dependency.
|
|
6
|
-
*
|
|
7
|
-
* Install: npm install ws
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* import { WebSocketGateway } from '@engjts/server/realtime';
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
export {
|
|
14
|
-
WebSocketGateway,
|
|
15
|
-
type WebSocketContext,
|
|
16
|
-
type WebSocketRoute,
|
|
17
|
-
type WebSocketRouteConfig
|
|
18
|
-
} from './websocket';
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import { IncomingMessage, Server as HTTPServer } from 'http';
|
|
2
|
-
import { parse as parseUrl } from 'url';
|
|
3
|
-
import { EventEmitter } from 'events';
|
|
4
|
-
|
|
5
|
-
let WebSocket: any;
|
|
6
|
-
let WebSocketServer: any;
|
|
7
|
-
let RawData: any;
|
|
8
|
-
|
|
9
|
-
try {
|
|
10
|
-
const wsModule = require('ws');
|
|
11
|
-
WebSocket = wsModule.default || wsModule;
|
|
12
|
-
WebSocketServer = wsModule.WebSocketServer;
|
|
13
|
-
RawData = wsModule.RawData;
|
|
14
|
-
} catch (error) {
|
|
15
|
-
// ws module not installed
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface WebSocketContext {
|
|
19
|
-
path: string;
|
|
20
|
-
query: Record<string, string | string[]>;
|
|
21
|
-
headers: IncomingMessage['headers'];
|
|
22
|
-
user?: any;
|
|
23
|
-
metadata?: Record<string, any>;
|
|
24
|
-
raw: {
|
|
25
|
-
req: IncomingMessage;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface WebSocketRouteConfig {
|
|
30
|
-
auth?: (ctx: WebSocketContext) => Promise<any>;
|
|
31
|
-
beforeConnect?: (socket: WebSocket, ctx: WebSocketContext) => Promise<void>;
|
|
32
|
-
onConnect?: (socket: WebSocket, ctx: WebSocketContext) => Promise<void>;
|
|
33
|
-
onMessage?: (socket: WebSocket, message: any, ctx: WebSocketContext) => Promise<void>;
|
|
34
|
-
onClose?: (socket: WebSocket, ctx: WebSocketContext, code: number, reason?: Buffer) => Promise<void>;
|
|
35
|
-
onError?: (socket: WebSocket, error: Error, ctx: WebSocketContext) => Promise<void>;
|
|
36
|
-
rooms?: boolean;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface WebSocketRoute extends WebSocketRouteConfig {
|
|
40
|
-
path: string;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface ConnectionState {
|
|
44
|
-
ctx: WebSocketContext;
|
|
45
|
-
route: WebSocketRoute;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* WebSocket gateway with room management and authentication hooks
|
|
50
|
-
*/
|
|
51
|
-
export class WebSocketGateway extends EventEmitter {
|
|
52
|
-
private routes: Map<string, WebSocketRoute> = new Map();
|
|
53
|
-
private wss?: any;
|
|
54
|
-
private connections: WeakMap<any, ConnectionState> = new WeakMap();
|
|
55
|
-
private rooms: Map<string, Set<any>> = new Map();
|
|
56
|
-
private socketRooms: WeakMap<any, Set<string>> = new WeakMap();
|
|
57
|
-
|
|
58
|
-
register(path: string, config: WebSocketRouteConfig) {
|
|
59
|
-
if (!path.startsWith('/')) {
|
|
60
|
-
throw new Error('WebSocket route path must start with "/"');
|
|
61
|
-
}
|
|
62
|
-
this.routes.set(path, { ...config, path });
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
attach(server: HTTPServer) {
|
|
66
|
-
if (this.wss) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (!WebSocketServer) {
|
|
71
|
-
throw new Error(
|
|
72
|
-
'WebSocket support requires the "ws" package to be installed.\n' +
|
|
73
|
-
'Install it with: npm install ws\n' +
|
|
74
|
-
'Or if using the CLI: nexus create my-app --skip-install && npm install'
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
this.wss = new WebSocketServer({ noServer: true });
|
|
79
|
-
|
|
80
|
-
server.on('upgrade', async (req, socket, head) => {
|
|
81
|
-
try {
|
|
82
|
-
const pathname = parseUrl(req.url || '').pathname || '/';
|
|
83
|
-
const route = this.routes.get(pathname);
|
|
84
|
-
|
|
85
|
-
if (!route) {
|
|
86
|
-
socket.destroy();
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const ctx = this.createContext(req, pathname);
|
|
91
|
-
if (route.auth) {
|
|
92
|
-
ctx.user = await route.auth(ctx);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
this.wss!.handleUpgrade(req, socket, head, (ws: WebSocket) => {
|
|
96
|
-
this.bindConnection(ws, route, ctx);
|
|
97
|
-
});
|
|
98
|
-
} catch (error) {
|
|
99
|
-
socket.destroy();
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
broadcast(room: string, payload: any) {
|
|
105
|
-
const sockets = this.rooms.get(room);
|
|
106
|
-
if (!sockets) return;
|
|
107
|
-
|
|
108
|
-
for (const socket of sockets) {
|
|
109
|
-
if (socket.readyState === WebSocket.OPEN) {
|
|
110
|
-
socket.send(JSON.stringify(payload));
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
createRoom(name: string) {
|
|
116
|
-
if (!this.rooms.has(name)) {
|
|
117
|
-
this.rooms.set(name, new Set());
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
joinRoom(room: string, socket: WebSocket) {
|
|
122
|
-
this.createRoom(room);
|
|
123
|
-
const sockets = this.rooms.get(room)!;
|
|
124
|
-
sockets.add(socket);
|
|
125
|
-
|
|
126
|
-
const joinedRooms = this.socketRooms.get(socket) ?? new Set<string>();
|
|
127
|
-
joinedRooms.add(room);
|
|
128
|
-
this.socketRooms.set(socket, joinedRooms);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
leaveRoom(room: string, socket: WebSocket) {
|
|
132
|
-
const sockets = this.rooms.get(room);
|
|
133
|
-
if (!sockets) return;
|
|
134
|
-
sockets.delete(socket);
|
|
135
|
-
|
|
136
|
-
const joinedRooms = this.socketRooms.get(socket);
|
|
137
|
-
joinedRooms?.delete(room);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
private bindConnection(socket: any, route: WebSocketRoute, ctx: WebSocketContext) {
|
|
141
|
-
this.connections.set(socket, { ctx, route });
|
|
142
|
-
this.emit('connection', socket, ctx);
|
|
143
|
-
|
|
144
|
-
socket.on('message', async (data: any) => {
|
|
145
|
-
try {
|
|
146
|
-
const payload = this.parseMessage(data);
|
|
147
|
-
await route.onMessage?.(socket, payload, ctx);
|
|
148
|
-
this.emit('message', socket, payload, ctx);
|
|
149
|
-
} catch (error) {
|
|
150
|
-
await route.onError?.(socket, error as Error, ctx);
|
|
151
|
-
this.emit('error', error, socket, ctx);
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
socket.on('close', async (code: number, buffer: Buffer) => {
|
|
156
|
-
await route.onClose?.(socket, ctx, code, buffer);
|
|
157
|
-
this.cleanupSocket(socket);
|
|
158
|
-
this.emit('close', socket, ctx);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
socket.on('error', async (error: Error) => {
|
|
162
|
-
await route.onError?.(socket, error, ctx);
|
|
163
|
-
this.emit('error', error, socket, ctx);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
void (async () => {
|
|
167
|
-
if (route.beforeConnect) {
|
|
168
|
-
await route.beforeConnect(socket, ctx);
|
|
169
|
-
}
|
|
170
|
-
await route.onConnect?.(socket, ctx);
|
|
171
|
-
})();
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
private createContext(req: IncomingMessage, path: string): WebSocketContext {
|
|
175
|
-
const parsed = parseUrl(req.url || '', true);
|
|
176
|
-
return {
|
|
177
|
-
path,
|
|
178
|
-
query: parsed.query as Record<string, string | string[]>,
|
|
179
|
-
headers: req.headers,
|
|
180
|
-
raw: { req }
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
private parseMessage(data: any): any {
|
|
185
|
-
if (Buffer.isBuffer(data) || data instanceof ArrayBuffer) {
|
|
186
|
-
const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
187
|
-
const stringPayload = buffer.toString('utf-8');
|
|
188
|
-
try {
|
|
189
|
-
return JSON.parse(stringPayload);
|
|
190
|
-
} catch {
|
|
191
|
-
return stringPayload;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (Array.isArray(data)) {
|
|
196
|
-
return data.map((item): any => this.parseMessage(item));
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Handle string case
|
|
200
|
-
try {
|
|
201
|
-
return JSON.parse(data as string);
|
|
202
|
-
} catch {
|
|
203
|
-
return data as string;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
private cleanupSocket(socket: any) {
|
|
208
|
-
const rooms = this.socketRooms.get(socket);
|
|
209
|
-
if (rooms) {
|
|
210
|
-
for (const room of rooms) {
|
|
211
|
-
this.rooms.get(room)?.delete(socket);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
this.socketRooms.delete(socket);
|
|
215
|
-
this.connections.delete(socket);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Helper object to expose room operations in a structured way
|
|
220
|
-
*/
|
|
221
|
-
get roomManager() {
|
|
222
|
-
return {
|
|
223
|
-
create: (name: string) => this.createRoom(name),
|
|
224
|
-
join: (name: string, socket: WebSocket) => this.joinRoom(name, socket),
|
|
225
|
-
leave: (name: string, socket: WebSocket) => this.leaveRoom(name, socket),
|
|
226
|
-
broadcast: (name: string, payload: any) => this.broadcast(name, payload),
|
|
227
|
-
list: () => Array.from(this.rooms.keys())
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|