@engjts/nexus 0.1.8 → 0.1.10
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/playground.js.map +1 -1
- package/dist/advanced/static/generateDirectoryListing.d.ts +1 -1
- package/dist/advanced/static/generateDirectoryListing.d.ts.map +1 -1
- package/dist/advanced/static/generateDirectoryListing.js +12 -6
- package/dist/advanced/static/generateDirectoryListing.js.map +1 -1
- package/dist/advanced/static/index.d.ts +2 -0
- package/dist/advanced/static/index.d.ts.map +1 -1
- package/dist/advanced/static/index.js +4 -1
- package/dist/advanced/static/index.js.map +1 -1
- package/dist/advanced/static/serveStatic.d.ts.map +1 -1
- package/dist/advanced/static/serveStatic.js +7 -1
- package/dist/advanced/static/serveStatic.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- 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
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { SwaggerGenerator } from './SwaggerGenerator';
|
|
2
|
-
import { SwaggerConfig } from './types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Create swagger instance (legacy)
|
|
6
|
-
* @deprecated Use swagger() plugin instead
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export function createSwagger(config: SwaggerConfig = {}): SwaggerGenerator {
|
|
11
|
-
return new SwaggerGenerator(config);
|
|
12
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { capitalize } from './capitalize';
|
|
2
|
-
import { HTTPMethod } from '../../core/types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Generate operation ID from method and path
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export function generateOperationId(method: HTTPMethod, path: string): string {
|
|
10
|
-
const parts = path
|
|
11
|
-
.split('/')
|
|
12
|
-
.filter(Boolean)
|
|
13
|
-
.map(part => {
|
|
14
|
-
if (part.startsWith(':')) {
|
|
15
|
-
return 'By' + capitalize(part.slice(1));
|
|
16
|
-
}
|
|
17
|
-
return capitalize(part);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
return method.toLowerCase() + parts.join('');
|
|
21
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { buildOperation } from './buildOperation';
|
|
2
|
-
import { convertPath } from './convertPath';
|
|
3
|
-
import { StoredRoute, OpenAPISchema, SwaggerConfig, OpenAPISpec, OpenAPIOperation } from './types';
|
|
4
|
-
|
|
5
|
-
// ============================================
|
|
6
|
-
// SPEC GENERATION
|
|
7
|
-
// ============================================
|
|
8
|
-
/**
|
|
9
|
-
* Generate OpenAPI specification from routes
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export function generateSpec(
|
|
14
|
-
routes: StoredRoute[],
|
|
15
|
-
schemas: Map<string, OpenAPISchema>,
|
|
16
|
-
config: SwaggerConfig,
|
|
17
|
-
serverUrl: string
|
|
18
|
-
): OpenAPISpec {
|
|
19
|
-
const paths: Record<string, Record<string, OpenAPIOperation>> = {};
|
|
20
|
-
const tags = new Map<string, { name: string; description?: string; }>();
|
|
21
|
-
|
|
22
|
-
// Add predefined tags
|
|
23
|
-
if (config.tags) {
|
|
24
|
-
config.tags.forEach(tag => tags.set(tag.name, tag));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
for (const route of routes) {
|
|
28
|
-
// Skip swagger's own endpoints
|
|
29
|
-
if (route.path === config.path || route.path === config.specPath) {
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Skip untagged routes if configured
|
|
34
|
-
if (config.hideUntagged && (!route.meta?.tags || route.meta.tags.length === 0)) {
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const openApiPath = convertPath(route.path);
|
|
39
|
-
|
|
40
|
-
if (!paths[openApiPath]) {
|
|
41
|
-
paths[openApiPath] = {};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const operation = buildOperation(route, config);
|
|
45
|
-
paths[openApiPath][route.method.toLowerCase()] = operation;
|
|
46
|
-
|
|
47
|
-
// Collect tags
|
|
48
|
-
if (route.meta?.tags) {
|
|
49
|
-
route.meta.tags.forEach(tag => {
|
|
50
|
-
if (!tags.has(tag)) {
|
|
51
|
-
tags.set(tag, { name: tag });
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Sort tags if configured
|
|
58
|
-
let tagList = Array.from(tags.values());
|
|
59
|
-
if (config.sortTags) {
|
|
60
|
-
tagList = tagList.sort((a, b) => a.name.localeCompare(b.name));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const spec: OpenAPISpec = {
|
|
64
|
-
openapi: '3.0.3',
|
|
65
|
-
info: {
|
|
66
|
-
title: config.info?.title || 'API Documentation',
|
|
67
|
-
version: config.info?.version || '1.0.0',
|
|
68
|
-
...config.info
|
|
69
|
-
},
|
|
70
|
-
paths,
|
|
71
|
-
tags: tagList
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
// Add servers
|
|
75
|
-
if (config.servers && config.servers.length > 0) {
|
|
76
|
-
spec.servers = config.servers;
|
|
77
|
-
} else if (serverUrl) {
|
|
78
|
-
spec.servers = [{ url: serverUrl, description: 'Current server' }];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Add components
|
|
82
|
-
if (schemas.size > 0 || config.securitySchemes) {
|
|
83
|
-
spec.components = {};
|
|
84
|
-
|
|
85
|
-
if (schemas.size > 0) {
|
|
86
|
-
spec.components.schemas = Object.fromEntries(schemas);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (config.securitySchemes) {
|
|
90
|
-
spec.components.securitySchemes = config.securitySchemes;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Add global security
|
|
95
|
-
if (config.security) {
|
|
96
|
-
spec.security = config.security;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Add external docs
|
|
100
|
-
if (config.externalDocs) {
|
|
101
|
-
spec.externalDocs = config.externalDocs;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return spec;
|
|
105
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { HTTPMethod } from '../../core/types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Auto-generate summary from method and path
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export function generateSummary(method: HTTPMethod, path: string): string {
|
|
9
|
-
const parts = path.split('/').filter(Boolean);
|
|
10
|
-
const resource = parts.find(p => !p.startsWith(':')) || 'resource';
|
|
11
|
-
const hasId = parts.some(p => p.startsWith(':'));
|
|
12
|
-
|
|
13
|
-
const actions: Record<HTTPMethod, string> = {
|
|
14
|
-
'GET': hasId ? `Get ${resource} by ID` : `List all ${resource}`,
|
|
15
|
-
'POST': `Create ${resource}`,
|
|
16
|
-
'PUT': `Update ${resource}`,
|
|
17
|
-
'PATCH': `Partial update ${resource}`,
|
|
18
|
-
'DELETE': `Delete ${resource}`,
|
|
19
|
-
'HEAD': `Check ${resource}`,
|
|
20
|
-
'OPTIONS': `Options for ${resource}`
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
return actions[method] || `${method} ${path}`;
|
|
24
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { generateThemeCss } from './generateThemeCss';
|
|
2
|
-
import { SwaggerConfig } from './types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Generate Swagger UI HTML
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export function generateSwaggerUI(config: SwaggerConfig): string {
|
|
10
|
-
const specUrl = config.specPath || '/openapi.json';
|
|
11
|
-
const title = config.info?.title || 'API Documentation';
|
|
12
|
-
const themeCss = generateThemeCss(config.theme);
|
|
13
|
-
const customCss = config.customCss || '';
|
|
14
|
-
const favicon = config.favicon || 'https://unpkg.com/swagger-ui-dist@5/favicon-32x32.png';
|
|
15
|
-
|
|
16
|
-
return `<!DOCTYPE html>
|
|
17
|
-
<html lang="en">
|
|
18
|
-
<head>
|
|
19
|
-
<meta charset="UTF-8">
|
|
20
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
21
|
-
<title>${title}</title>
|
|
22
|
-
<link rel="icon" type="image/png" href="${favicon}">
|
|
23
|
-
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
24
|
-
<style>
|
|
25
|
-
html { box-sizing: border-box; overflow-y: scroll; }
|
|
26
|
-
*, *:before, *:after { box-sizing: inherit; }
|
|
27
|
-
body { margin: 0; background: #fafafa; }
|
|
28
|
-
.swagger-ui .topbar { padding: 10px 0; }
|
|
29
|
-
.swagger-ui .info { margin: 30px 0; }
|
|
30
|
-
.swagger-ui .info hgroup.main { margin: 0 0 20px 0; }
|
|
31
|
-
.swagger-ui .info .title { font-size: 36px; }
|
|
32
|
-
${themeCss}
|
|
33
|
-
${customCss}
|
|
34
|
-
</style>
|
|
35
|
-
</head>
|
|
36
|
-
<body>
|
|
37
|
-
<div id="swagger-ui"></div>
|
|
38
|
-
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
39
|
-
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-standalone-preset.js"></script>
|
|
40
|
-
<script>
|
|
41
|
-
window.onload = function() {
|
|
42
|
-
window.ui = SwaggerUIBundle({
|
|
43
|
-
url: "${specUrl}",
|
|
44
|
-
dom_id: '#swagger-ui',
|
|
45
|
-
deepLinking: true,
|
|
46
|
-
docExpansion: '${config.docExpansion || 'list'}',
|
|
47
|
-
filter: ${config.filter !== false},
|
|
48
|
-
tryItOutEnabled: ${config.tryItOutEnabled !== false},
|
|
49
|
-
persistAuthorization: ${config.persistAuthorization !== false},
|
|
50
|
-
presets: [
|
|
51
|
-
SwaggerUIBundle.presets.apis,
|
|
52
|
-
SwaggerUIStandalonePreset
|
|
53
|
-
],
|
|
54
|
-
plugins: [
|
|
55
|
-
SwaggerUIBundle.plugins.DownloadUrl
|
|
56
|
-
],
|
|
57
|
-
layout: "StandaloneLayout",
|
|
58
|
-
validatorUrl: null,
|
|
59
|
-
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch', 'head', 'options'],
|
|
60
|
-
defaultModelsExpandDepth: 2,
|
|
61
|
-
defaultModelExpandDepth: 2,
|
|
62
|
-
displayRequestDuration: true,
|
|
63
|
-
showExtensions: true,
|
|
64
|
-
showCommonExtensions: true
|
|
65
|
-
});
|
|
66
|
-
};
|
|
67
|
-
</script>
|
|
68
|
-
</body>
|
|
69
|
-
</html>`;
|
|
70
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { SwaggerTheme } from './types';
|
|
2
|
-
|
|
3
|
-
// ============================================
|
|
4
|
-
// SWAGGER UI GENERATION
|
|
5
|
-
// ============================================
|
|
6
|
-
/**
|
|
7
|
-
* Generate theme CSS
|
|
8
|
-
*/
|
|
9
|
-
export function generateThemeCss(theme?: 'light' | 'dark' | SwaggerTheme): string {
|
|
10
|
-
if (!theme) return '';
|
|
11
|
-
|
|
12
|
-
if (theme === 'dark') {
|
|
13
|
-
return `
|
|
14
|
-
body { background-color: #1a1a2e !important; }
|
|
15
|
-
.swagger-ui { background-color: #1a1a2e; }
|
|
16
|
-
.swagger-ui .topbar { background-color: #16213e; }
|
|
17
|
-
.swagger-ui .info .title { color: #e94560; }
|
|
18
|
-
.swagger-ui .scheme-container { background: #16213e; }
|
|
19
|
-
.swagger-ui .opblock-tag { color: #fff; border-bottom-color: #333; }
|
|
20
|
-
.swagger-ui .opblock { background: rgba(255,255,255,0.05); border-color: #333; }
|
|
21
|
-
.swagger-ui .opblock-summary { border-color: #333; }
|
|
22
|
-
.swagger-ui .opblock .opblock-summary-description { color: #aaa; }
|
|
23
|
-
.swagger-ui .opblock-body { background: #16213e; }
|
|
24
|
-
.swagger-ui .parameter__name, .swagger-ui .parameter__type { color: #fff; }
|
|
25
|
-
.swagger-ui table thead tr th { color: #fff; border-color: #333; }
|
|
26
|
-
.swagger-ui table tbody tr td { color: #ddd; border-color: #333; }
|
|
27
|
-
.swagger-ui .response-col_status { color: #e94560; }
|
|
28
|
-
.swagger-ui section.models { border-color: #333; }
|
|
29
|
-
.swagger-ui section.models h4 { color: #fff; }
|
|
30
|
-
.swagger-ui .model-box { background: #16213e; }
|
|
31
|
-
.swagger-ui .model { color: #ddd; }
|
|
32
|
-
.swagger-ui input[type=text], .swagger-ui textarea {
|
|
33
|
-
background: #0f3460; color: #fff; border-color: #333;
|
|
34
|
-
}
|
|
35
|
-
.swagger-ui select { background: #0f3460; color: #fff; }
|
|
36
|
-
.swagger-ui .btn { border-color: #e94560; }
|
|
37
|
-
.swagger-ui .btn.execute { background: #e94560; }
|
|
38
|
-
`;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (typeof theme === 'object') {
|
|
42
|
-
return `
|
|
43
|
-
${theme.backgroundColor ? `body { background-color: ${theme.backgroundColor} !important; }` : ''}
|
|
44
|
-
${theme.primaryColor ? `.swagger-ui .info .title { color: ${theme.primaryColor}; }` : ''}
|
|
45
|
-
${theme.primaryColor ? `.swagger-ui .btn.execute { background: ${theme.primaryColor}; border-color: ${theme.primaryColor}; }` : ''}
|
|
46
|
-
${theme.headerColor ? `.swagger-ui .topbar { background-color: ${theme.headerColor}; }` : ''}
|
|
47
|
-
${theme.textColor ? `.swagger-ui { color: ${theme.textColor}; }` : ''}
|
|
48
|
-
${theme.fontFamily ? `.swagger-ui { font-family: ${theme.fontFamily}; }` : ''}
|
|
49
|
-
`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return '';
|
|
53
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Swagger/OpenAPI Integration for Nexus Framework
|
|
3
|
-
* Smart auto-detection of routes with zero configuration
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* ```typescript
|
|
7
|
-
* import { createApp, swagger } from 'nexus';
|
|
8
|
-
*
|
|
9
|
-
* const app = createApp();
|
|
10
|
-
*
|
|
11
|
-
* // Zero config - just works!
|
|
12
|
-
* app.plugin(swagger());
|
|
13
|
-
*
|
|
14
|
-
* // With config
|
|
15
|
-
* app.plugin(swagger({
|
|
16
|
-
* path: '/docs',
|
|
17
|
-
* info: { title: 'My API', version: '1.0.0' }
|
|
18
|
-
* }));
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { swagger } from './swagger';
|
|
23
|
-
|
|
24
|
-
// Default export
|
|
25
|
-
export default swagger;
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import { generateSwaggerUI } from './generateSwaggerUI';
|
|
2
|
-
import { generateSpec } from './generateSpec';
|
|
3
|
-
import { Application } from '../../core/application';
|
|
4
|
-
import { RouteConfig, HTTPMethod, Context, SchemaConfig, RouteMeta } from '../../core/types';
|
|
5
|
-
import { Plugin } from '../static/spa';
|
|
6
|
-
import { SwaggerConfig, StoredRoute, OpenAPISchema, SwaggerApplication } from './types';
|
|
7
|
-
|
|
8
|
-
// ============================================
|
|
9
|
-
// SWAGGER FEATURE (PLUGIN)
|
|
10
|
-
// ============================================
|
|
11
|
-
/**
|
|
12
|
-
* Create Swagger feature plugin for Nexus
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```typescript
|
|
16
|
-
* // Minimal setup - auto-detects everything
|
|
17
|
-
* app.plugin(swagger());
|
|
18
|
-
*
|
|
19
|
-
* // With custom info
|
|
20
|
-
* app.plugin(swagger({
|
|
21
|
-
* info: {
|
|
22
|
-
* title: 'My Awesome API',
|
|
23
|
-
* version: '2.0.0',
|
|
24
|
-
* description: 'API documentation'
|
|
25
|
-
* }
|
|
26
|
-
* }));
|
|
27
|
-
*
|
|
28
|
-
* // Full configuration
|
|
29
|
-
* app.plugin(swagger({
|
|
30
|
-
* path: '/api-docs',
|
|
31
|
-
* specPath: '/swagger.json',
|
|
32
|
-
* theme: 'dark',
|
|
33
|
-
* securitySchemes: {
|
|
34
|
-
* bearerAuth: {
|
|
35
|
-
* type: 'http',
|
|
36
|
-
* scheme: 'bearer',
|
|
37
|
-
* bearerFormat: 'JWT'
|
|
38
|
-
* }
|
|
39
|
-
* }
|
|
40
|
-
* }));
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
export function swagger(config: SwaggerConfig = {}): Plugin {
|
|
46
|
-
const resolvedConfig: SwaggerConfig = {
|
|
47
|
-
path: '/docs',
|
|
48
|
-
specPath: '/openapi.json',
|
|
49
|
-
docExpansion: 'list',
|
|
50
|
-
filter: true,
|
|
51
|
-
tryItOutEnabled: true,
|
|
52
|
-
persistAuthorization: true,
|
|
53
|
-
...config,
|
|
54
|
-
info: {
|
|
55
|
-
title: 'API Documentation',
|
|
56
|
-
version: '1.0.0',
|
|
57
|
-
...config.info
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// Storage for routes - will be populated when app registers routes
|
|
62
|
-
const routes: StoredRoute[] = [];
|
|
63
|
-
const schemas: Map<string, OpenAPISchema> = new Map();
|
|
64
|
-
let serverUrl = '';
|
|
65
|
-
let appInstance: Application | null = null;
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
name: 'swagger',
|
|
69
|
-
version: '1.0.0',
|
|
70
|
-
|
|
71
|
-
install(app: Application) {
|
|
72
|
-
appInstance = app;
|
|
73
|
-
// Cast to extended interface for swagger-specific properties
|
|
74
|
-
const swaggerApp = app as SwaggerApplication;
|
|
75
|
-
// Hook into route registration to capture routes with metadata
|
|
76
|
-
const originalRoute = app.route.bind(app);
|
|
77
|
-
const originalGet = app.get.bind(app);
|
|
78
|
-
const originalPost = app.post.bind(app);
|
|
79
|
-
const originalPut = app.put.bind(app);
|
|
80
|
-
const originalDelete = app.delete.bind(app);
|
|
81
|
-
const originalPatch = app.patch.bind(app);
|
|
82
|
-
|
|
83
|
-
// Override route method to capture metadata
|
|
84
|
-
app.route = function (routeConfig: RouteConfig) {
|
|
85
|
-
routes.push({
|
|
86
|
-
method: routeConfig.method,
|
|
87
|
-
path: routeConfig.path,
|
|
88
|
-
schema: routeConfig.schema,
|
|
89
|
-
meta: routeConfig.meta
|
|
90
|
-
});
|
|
91
|
-
return originalRoute(routeConfig);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
// Override HTTP method shortcuts
|
|
95
|
-
const wrapMethod = (method: HTTPMethod, original: Function) => {
|
|
96
|
-
return function (pathOrRoute: string | any, handlerOrConfig?: any) {
|
|
97
|
-
// Class-based routing
|
|
98
|
-
if (typeof pathOrRoute === 'object' && 'pathName' in pathOrRoute) {
|
|
99
|
-
const route = pathOrRoute;
|
|
100
|
-
routes.push({
|
|
101
|
-
method,
|
|
102
|
-
path: route.pathName,
|
|
103
|
-
schema: route.schema?.(),
|
|
104
|
-
meta: route.meta?.()
|
|
105
|
-
});
|
|
106
|
-
return original(pathOrRoute);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const path = pathOrRoute;
|
|
110
|
-
if (typeof handlerOrConfig !== 'function' && handlerOrConfig) {
|
|
111
|
-
routes.push({
|
|
112
|
-
method,
|
|
113
|
-
path,
|
|
114
|
-
schema: handlerOrConfig.schema,
|
|
115
|
-
meta: handlerOrConfig.meta
|
|
116
|
-
});
|
|
117
|
-
} else {
|
|
118
|
-
routes.push({ method, path });
|
|
119
|
-
}
|
|
120
|
-
return original(path, handlerOrConfig);
|
|
121
|
-
};
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
app.get = wrapMethod('GET', originalGet);
|
|
125
|
-
app.post = wrapMethod('POST', originalPost);
|
|
126
|
-
app.put = wrapMethod('PUT', originalPut);
|
|
127
|
-
app.delete = wrapMethod('DELETE', originalDelete);
|
|
128
|
-
app.patch = wrapMethod('PATCH', originalPatch);
|
|
129
|
-
|
|
130
|
-
// Add swagger endpoints
|
|
131
|
-
const docsPath = resolvedConfig.path!;
|
|
132
|
-
const specPath = resolvedConfig.specPath!;
|
|
133
|
-
|
|
134
|
-
// Serve OpenAPI JSON spec
|
|
135
|
-
originalGet(specPath, async (ctx: Context) => {
|
|
136
|
-
// Auto-detect server URL from request
|
|
137
|
-
if (!serverUrl && 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
|
-
serverUrl = `${protocol}://${host}`;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Combine intercepted routes with routes from router (for file-based routing)
|
|
145
|
-
const allRoutes = getAllRoutes(routes, appInstance, docsPath, specPath);
|
|
146
|
-
const spec = generateSpec(allRoutes, schemas, resolvedConfig, serverUrl);
|
|
147
|
-
return ctx.json(spec);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
// Serve Swagger UI
|
|
151
|
-
originalGet(docsPath, async (_ctx: Context) => {
|
|
152
|
-
const html = generateSwaggerUI(resolvedConfig);
|
|
153
|
-
return {
|
|
154
|
-
statusCode: 200,
|
|
155
|
-
headers: { 'Content-Type': 'text/html; charset=utf-8' },
|
|
156
|
-
body: html
|
|
157
|
-
};
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// Also serve at /docs/ (with trailing slash)
|
|
161
|
-
originalGet(docsPath + '/', async (_ctx: Context) => {
|
|
162
|
-
const html = generateSwaggerUI(resolvedConfig);
|
|
163
|
-
return {
|
|
164
|
-
statusCode: 200,
|
|
165
|
-
headers: { 'Content-Type': 'text/html; charset=utf-8' },
|
|
166
|
-
body: html
|
|
167
|
-
};
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// Add schema registration method to app
|
|
171
|
-
swaggerApp.swaggerSchema = (name: string, schema: OpenAPISchema) => {
|
|
172
|
-
schemas.set(name, schema);
|
|
173
|
-
return swaggerApp;
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
// Log swagger is enabled (check via environment or resolvedConfig)
|
|
177
|
-
if (process.env.DEBUG === 'true' || process.env.NODE_ENV === 'development') {
|
|
178
|
-
console.log(`📚 Swagger UI: ${docsPath}`);
|
|
179
|
-
console.log(`📄 OpenAPI Spec: ${specPath}`);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Get all routes by combining intercepted routes with routes from the router
|
|
187
|
-
* This ensures file-based routes are also included in Swagger docs
|
|
188
|
-
*/
|
|
189
|
-
function getAllRoutes(
|
|
190
|
-
interceptedRoutes: StoredRoute[],
|
|
191
|
-
app: Application | null,
|
|
192
|
-
docsPath: string,
|
|
193
|
-
specPath: string
|
|
194
|
-
): StoredRoute[] {
|
|
195
|
-
// Create a Set of already tracked route keys (method + path)
|
|
196
|
-
const trackedKeys = new Set(
|
|
197
|
-
interceptedRoutes.map(r => `${r.method}:${r.path}`)
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
// Start with intercepted routes (filtered to exclude swagger routes)
|
|
201
|
-
const allRoutes: StoredRoute[] = interceptedRoutes.filter(
|
|
202
|
-
r => !r.path.startsWith(docsPath) && r.path !== specPath
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
// Get routes from router (includes file-based routes)
|
|
206
|
-
if (app) {
|
|
207
|
-
const routerRoutes = app.getRoutes() as Array<{
|
|
208
|
-
method: string;
|
|
209
|
-
path: string;
|
|
210
|
-
schema?: SchemaConfig;
|
|
211
|
-
meta?: RouteMeta;
|
|
212
|
-
}>;
|
|
213
|
-
|
|
214
|
-
for (const route of routerRoutes) {
|
|
215
|
-
const key = `${route.method}:${route.path}`;
|
|
216
|
-
|
|
217
|
-
// Skip if already tracked or is swagger route
|
|
218
|
-
if (
|
|
219
|
-
trackedKeys.has(key) ||
|
|
220
|
-
route.path.startsWith(docsPath) ||
|
|
221
|
-
route.path === specPath
|
|
222
|
-
) {
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
allRoutes.push({
|
|
227
|
-
method: route.method as HTTPMethod,
|
|
228
|
-
path: route.path,
|
|
229
|
-
schema: route.schema,
|
|
230
|
-
meta: route.meta
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// Sort routes by path for consistent ordering
|
|
236
|
-
return allRoutes.sort((a, b) => a.path.localeCompare(b.path));
|
|
237
|
-
}
|