@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.
Files changed (221) hide show
  1. package/dist/advanced/playground/playground.js.map +1 -1
  2. package/dist/advanced/static/generateDirectoryListing.d.ts +1 -1
  3. package/dist/advanced/static/generateDirectoryListing.d.ts.map +1 -1
  4. package/dist/advanced/static/generateDirectoryListing.js +12 -6
  5. package/dist/advanced/static/generateDirectoryListing.js.map +1 -1
  6. package/dist/advanced/static/index.d.ts +2 -0
  7. package/dist/advanced/static/index.d.ts.map +1 -1
  8. package/dist/advanced/static/index.js +4 -1
  9. package/dist/advanced/static/index.js.map +1 -1
  10. package/dist/advanced/static/serveStatic.d.ts.map +1 -1
  11. package/dist/advanced/static/serveStatic.js +7 -1
  12. package/dist/advanced/static/serveStatic.js.map +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -1
  16. package/dist/index.js.map +1 -1
  17. package/package.json +1 -1
  18. package/BENCHMARK_REPORT.md +0 -343
  19. package/documentation/01-getting-started.md +0 -240
  20. package/documentation/02-context.md +0 -335
  21. package/documentation/03-routing.md +0 -397
  22. package/documentation/04-middleware.md +0 -483
  23. package/documentation/05-validation.md +0 -514
  24. package/documentation/06-error-handling.md +0 -465
  25. package/documentation/07-performance.md +0 -364
  26. package/documentation/08-adapters.md +0 -470
  27. package/documentation/09-api-reference.md +0 -548
  28. package/documentation/10-examples.md +0 -582
  29. package/documentation/11-deployment.md +0 -477
  30. package/documentation/12-sentry.md +0 -620
  31. package/documentation/13-sentry-data-storage.md +0 -996
  32. package/documentation/14-sentry-data-reference.md +0 -457
  33. package/documentation/15-sentry-summary.md +0 -409
  34. package/documentation/16-alerts-system.md +0 -745
  35. package/documentation/17-alert-adapters.md +0 -696
  36. package/documentation/18-alerts-implementation-summary.md +0 -385
  37. package/documentation/19-class-based-routing.md +0 -840
  38. package/documentation/20-websocket-realtime.md +0 -813
  39. package/documentation/21-cache-system.md +0 -510
  40. package/documentation/22-job-queue.md +0 -772
  41. package/documentation/23-sentry-plugin.md +0 -551
  42. package/documentation/24-testing-utilities.md +0 -1287
  43. package/documentation/25-api-versioning.md +0 -533
  44. package/documentation/26-context-store.md +0 -607
  45. package/documentation/27-dependency-injection.md +0 -329
  46. package/documentation/28-lifecycle-hooks.md +0 -521
  47. package/documentation/29-package-structure.md +0 -196
  48. package/documentation/30-plugin-system.md +0 -414
  49. package/documentation/31-jwt-authentication.md +0 -597
  50. package/documentation/32-cli.md +0 -268
  51. package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
  52. package/documentation/ALERTS-INDEX.md +0 -330
  53. package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
  54. package/documentation/README.md +0 -178
  55. package/documentation/index.html +0 -34
  56. package/modern_framework_paper.md +0 -1870
  57. package/public/css/style.css +0 -87
  58. package/public/index.html +0 -34
  59. package/public/js/app.js +0 -27
  60. package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
  61. package/src/advanced/cache/MultiTierCache.ts +0 -194
  62. package/src/advanced/cache/RedisCacheStore.ts +0 -341
  63. package/src/advanced/cache/index.ts +0 -5
  64. package/src/advanced/cache/types.ts +0 -40
  65. package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
  66. package/src/advanced/graphql/index.ts +0 -22
  67. package/src/advanced/graphql/server.ts +0 -252
  68. package/src/advanced/graphql/types.ts +0 -42
  69. package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
  70. package/src/advanced/jobs/JobQueue.ts +0 -556
  71. package/src/advanced/jobs/RedisQueueStore.ts +0 -367
  72. package/src/advanced/jobs/index.ts +0 -5
  73. package/src/advanced/jobs/types.ts +0 -70
  74. package/src/advanced/observability/APMManager.ts +0 -163
  75. package/src/advanced/observability/AlertManager.ts +0 -109
  76. package/src/advanced/observability/MetricRegistry.ts +0 -151
  77. package/src/advanced/observability/ObservabilityCenter.ts +0 -304
  78. package/src/advanced/observability/StructuredLogger.ts +0 -154
  79. package/src/advanced/observability/TracingManager.ts +0 -117
  80. package/src/advanced/observability/adapters.ts +0 -304
  81. package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
  82. package/src/advanced/observability/index.ts +0 -11
  83. package/src/advanced/observability/types.ts +0 -174
  84. package/src/advanced/playground/extractPathParams.ts +0 -6
  85. package/src/advanced/playground/generateFieldExample.ts +0 -31
  86. package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1956
  87. package/src/advanced/playground/generateSummary.ts +0 -19
  88. package/src/advanced/playground/getTagFromPath.ts +0 -9
  89. package/src/advanced/playground/index.ts +0 -8
  90. package/src/advanced/playground/playground.ts +0 -250
  91. package/src/advanced/playground/types.ts +0 -49
  92. package/src/advanced/playground/zodToExample.ts +0 -16
  93. package/src/advanced/playground/zodToParams.ts +0 -15
  94. package/src/advanced/postman/buildAuth.ts +0 -31
  95. package/src/advanced/postman/buildBody.ts +0 -15
  96. package/src/advanced/postman/buildQueryParams.ts +0 -27
  97. package/src/advanced/postman/buildRequestItem.ts +0 -36
  98. package/src/advanced/postman/buildResponses.ts +0 -11
  99. package/src/advanced/postman/buildUrl.ts +0 -33
  100. package/src/advanced/postman/capitalize.ts +0 -4
  101. package/src/advanced/postman/generateCollection.ts +0 -59
  102. package/src/advanced/postman/generateEnvironment.ts +0 -34
  103. package/src/advanced/postman/generateExampleFromZod.ts +0 -21
  104. package/src/advanced/postman/generateFieldExample.ts +0 -45
  105. package/src/advanced/postman/generateName.ts +0 -20
  106. package/src/advanced/postman/generateUUID.ts +0 -11
  107. package/src/advanced/postman/getTagFromPath.ts +0 -10
  108. package/src/advanced/postman/index.ts +0 -28
  109. package/src/advanced/postman/postman.ts +0 -156
  110. package/src/advanced/postman/slugify.ts +0 -7
  111. package/src/advanced/postman/types.ts +0 -140
  112. package/src/advanced/realtime/index.ts +0 -18
  113. package/src/advanced/realtime/websocket.ts +0 -231
  114. package/src/advanced/sentry/index.ts +0 -1236
  115. package/src/advanced/sentry/types.ts +0 -355
  116. package/src/advanced/static/generateDirectoryListing.ts +0 -47
  117. package/src/advanced/static/generateETag.ts +0 -7
  118. package/src/advanced/static/getMimeType.ts +0 -9
  119. package/src/advanced/static/index.ts +0 -32
  120. package/src/advanced/static/isSafePath.ts +0 -13
  121. package/src/advanced/static/publicDir.ts +0 -21
  122. package/src/advanced/static/serveStatic.ts +0 -225
  123. package/src/advanced/static/spa.ts +0 -24
  124. package/src/advanced/static/types.ts +0 -159
  125. package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
  126. package/src/advanced/swagger/buildOperation.ts +0 -61
  127. package/src/advanced/swagger/buildParameters.ts +0 -61
  128. package/src/advanced/swagger/buildRequestBody.ts +0 -21
  129. package/src/advanced/swagger/buildResponses.ts +0 -54
  130. package/src/advanced/swagger/capitalize.ts +0 -5
  131. package/src/advanced/swagger/convertPath.ts +0 -9
  132. package/src/advanced/swagger/createSwagger.ts +0 -12
  133. package/src/advanced/swagger/generateOperationId.ts +0 -21
  134. package/src/advanced/swagger/generateSpec.ts +0 -105
  135. package/src/advanced/swagger/generateSummary.ts +0 -24
  136. package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
  137. package/src/advanced/swagger/generateThemeCss.ts +0 -53
  138. package/src/advanced/swagger/index.ts +0 -25
  139. package/src/advanced/swagger/swagger.ts +0 -237
  140. package/src/advanced/swagger/types.ts +0 -206
  141. package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
  142. package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
  143. package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
  144. package/src/advanced/testing/factory.ts +0 -509
  145. package/src/advanced/testing/harness.ts +0 -612
  146. package/src/advanced/testing/index.ts +0 -430
  147. package/src/advanced/testing/load-test.ts +0 -618
  148. package/src/advanced/testing/mock-server.ts +0 -498
  149. package/src/advanced/testing/mock.ts +0 -670
  150. package/src/cli/bin.ts +0 -9
  151. package/src/cli/cli.ts +0 -158
  152. package/src/cli/commands/add.ts +0 -178
  153. package/src/cli/commands/build.ts +0 -73
  154. package/src/cli/commands/create.ts +0 -166
  155. package/src/cli/commands/dev.ts +0 -85
  156. package/src/cli/commands/generate.ts +0 -99
  157. package/src/cli/commands/help.ts +0 -95
  158. package/src/cli/commands/init.ts +0 -91
  159. package/src/cli/commands/version.ts +0 -38
  160. package/src/cli/index.ts +0 -6
  161. package/src/cli/templates/generators.ts +0 -359
  162. package/src/cli/templates/index.ts +0 -680
  163. package/src/cli/utils/exec.ts +0 -52
  164. package/src/cli/utils/file-system.ts +0 -78
  165. package/src/cli/utils/logger.ts +0 -111
  166. package/src/core/adapter.ts +0 -88
  167. package/src/core/application.ts +0 -1453
  168. package/src/core/context-pool.ts +0 -79
  169. package/src/core/context.ts +0 -856
  170. package/src/core/index.ts +0 -94
  171. package/src/core/middleware.ts +0 -272
  172. package/src/core/performance/buffer-pool.ts +0 -108
  173. package/src/core/performance/middleware-optimizer.ts +0 -162
  174. package/src/core/plugin/PluginManager.ts +0 -435
  175. package/src/core/plugin/builder.ts +0 -358
  176. package/src/core/plugin/index.ts +0 -50
  177. package/src/core/plugin/types.ts +0 -214
  178. package/src/core/router/file-router.ts +0 -623
  179. package/src/core/router/index.ts +0 -260
  180. package/src/core/router/radix-tree.ts +0 -242
  181. package/src/core/serializer.ts +0 -397
  182. package/src/core/store/index.ts +0 -30
  183. package/src/core/store/registry.ts +0 -178
  184. package/src/core/store/request-store.ts +0 -240
  185. package/src/core/store/types.ts +0 -233
  186. package/src/core/types.ts +0 -616
  187. package/src/database/adapter.ts +0 -35
  188. package/src/database/adapters/index.ts +0 -1
  189. package/src/database/adapters/mysql.ts +0 -669
  190. package/src/database/database.ts +0 -70
  191. package/src/database/dialect.ts +0 -388
  192. package/src/database/index.ts +0 -12
  193. package/src/database/migrations.ts +0 -86
  194. package/src/database/optimizer.ts +0 -125
  195. package/src/database/query-builder.ts +0 -404
  196. package/src/database/realtime.ts +0 -53
  197. package/src/database/schema.ts +0 -71
  198. package/src/database/transactions.ts +0 -56
  199. package/src/database/types.ts +0 -87
  200. package/src/deployment/cluster.ts +0 -471
  201. package/src/deployment/config.ts +0 -454
  202. package/src/deployment/docker.ts +0 -599
  203. package/src/deployment/graceful-shutdown.ts +0 -373
  204. package/src/deployment/index.ts +0 -56
  205. package/src/index.ts +0 -281
  206. package/src/security/adapter.ts +0 -318
  207. package/src/security/auth/JWTPlugin.ts +0 -234
  208. package/src/security/auth/JWTProvider.ts +0 -316
  209. package/src/security/auth/adapter.ts +0 -12
  210. package/src/security/auth/jwt.ts +0 -234
  211. package/src/security/auth/middleware.ts +0 -188
  212. package/src/security/csrf.ts +0 -220
  213. package/src/security/headers.ts +0 -108
  214. package/src/security/index.ts +0 -60
  215. package/src/security/rate-limit/adapter.ts +0 -7
  216. package/src/security/rate-limit/memory.ts +0 -108
  217. package/src/security/rate-limit/middleware.ts +0 -181
  218. package/src/security/sanitization.ts +0 -75
  219. package/src/security/types.ts +0 -240
  220. package/src/security/utils.ts +0 -52
  221. package/tsconfig.json +0 -39
@@ -1,225 +0,0 @@
1
- import { existsSync, statSync, createReadStream } from 'fs';
2
- import { resolve, join, extname } from 'path/posix';
3
- import { generateDirectoryListing } from './generateDirectoryListing';
4
- import { isSafePath } from './isSafePath';
5
- import { generateETag } from './generateETag';
6
- import { getMimeType } from './getMimeType';
7
- import { Plugin, Handler, Response } from '../../core/types';
8
- import { StaticConfig } from './types';
9
-
10
- /**
11
- * Create static file serving feature
12
- */
13
-
14
- export function serveStatic(config: StaticConfig = {}): Plugin {
15
- const {
16
- root = './public', prefix = '', index = 'index.html', directory = false, maxAge = 86400, immutable = false, etag = true, lastModified = true, extensions, dotfiles = 'ignore', fallback, headers = {}, precompressed = false
17
- } = config;
18
-
19
- const rootPath = resolve(process.cwd(), root);
20
- const normalizedPrefix = prefix.startsWith('/') ? prefix : prefix ? `/${prefix}` : '';
21
-
22
- return {
23
- name: 'static',
24
- version: '1.0.0',
25
-
26
- install(app: any) {
27
- // Create the static file handler
28
- const staticHandler: Handler = async (ctx) => {
29
- let requestPath = ctx.path;
30
-
31
- // Remove prefix if set
32
- if (normalizedPrefix && requestPath.startsWith(normalizedPrefix)) {
33
- requestPath = requestPath.slice(normalizedPrefix.length) || '/';
34
- } else if (normalizedPrefix) {
35
- // Path doesn't match prefix, skip
36
- return { statusCode: 404, headers: {}, body: 'Not Found' };
37
- }
38
-
39
- // Decode URL
40
- try {
41
- requestPath = decodeURIComponent(requestPath);
42
- } catch {
43
- return { statusCode: 400, headers: {}, body: 'Bad Request' };
44
- }
45
-
46
- // Remove leading slash for joining
47
- const cleanPath = requestPath.startsWith('/') ? requestPath.slice(1) : requestPath;
48
-
49
- // Security: Check for directory traversal
50
- if (!isSafePath(cleanPath, rootPath)) {
51
- return { statusCode: 403, headers: {}, body: 'Forbidden' };
52
- }
53
-
54
- const filePath = join(rootPath, cleanPath);
55
-
56
- // Handle dotfiles
57
- const basename = cleanPath.split('/').pop() || '';
58
- if (basename.startsWith('.')) {
59
- if (dotfiles === 'deny') {
60
- return { statusCode: 403, headers: {}, body: 'Forbidden' };
61
- }
62
- if (dotfiles === 'ignore') {
63
- return { statusCode: 404, headers: {}, body: 'Not Found' };
64
- }
65
- }
66
-
67
- // Check if file/directory exists
68
- if (!existsSync(filePath)) {
69
- // Try fallback for SPA
70
- if (fallback) {
71
- const fallbackPath = join(rootPath, fallback);
72
- if (existsSync(fallbackPath)) {
73
- return serveFile(fallbackPath, ctx);
74
- }
75
- }
76
- return { statusCode: 404, headers: {}, body: 'Not Found' };
77
- }
78
-
79
- const stats = statSync(filePath);
80
-
81
- // Handle directory
82
- if (stats.isDirectory()) {
83
- // Try index file(s)
84
- if (index !== false) {
85
- const indexFiles = Array.isArray(index) ? index : [index];
86
- for (const indexFile of indexFiles) {
87
- const indexPath = join(filePath, indexFile);
88
- if (existsSync(indexPath)) {
89
- return serveFile(indexPath, ctx);
90
- }
91
- }
92
- }
93
-
94
- // Directory listing
95
- if (directory) {
96
- const html = await generateDirectoryListing(filePath, requestPath);
97
- return {
98
- statusCode: 200,
99
- headers: { 'Content-Type': 'text/html; charset=utf-8' },
100
- body: html
101
- };
102
- }
103
-
104
- return { statusCode: 404, headers: {}, body: 'Not Found' };
105
- }
106
-
107
- // Check extension whitelist
108
- const ext = extname(filePath);
109
- if (extensions && !extensions.includes(ext)) {
110
- return { statusCode: 403, headers: {}, body: 'Forbidden' };
111
- }
112
-
113
- return serveFile(filePath, ctx);
114
- };
115
-
116
- // Helper to serve a file
117
- async function serveFile(filePath: string, ctx: any): Promise<Response> {
118
- const stats = statSync(filePath);
119
- const ext = extname(filePath);
120
- const mimeType = getMimeType(ext);
121
-
122
- const responseHeaders: Record<string, string> = {
123
- 'Content-Type': mimeType,
124
- 'Content-Length': stats.size.toString(),
125
- ...headers
126
- };
127
-
128
- // Cache headers
129
- let cacheControl = `public, max-age=${maxAge}`;
130
- if (immutable) {
131
- cacheControl += ', immutable';
132
- }
133
- responseHeaders['Cache-Control'] = cacheControl;
134
-
135
- // ETag
136
- if (etag) {
137
- const etagValue = generateETag(stats);
138
- responseHeaders['ETag'] = etagValue;
139
-
140
- // Check If-None-Match
141
- const ifNoneMatch = ctx.headers['if-none-match'];
142
- if (ifNoneMatch === etagValue) {
143
- return { statusCode: 304, headers: responseHeaders, body: '' };
144
- }
145
- }
146
-
147
- // Last-Modified
148
- if (lastModified) {
149
- const lastMod = stats.mtime.toUTCString();
150
- responseHeaders['Last-Modified'] = lastMod;
151
-
152
- // Check If-Modified-Since
153
- const ifModifiedSince = ctx.headers['if-modified-since'];
154
- if (ifModifiedSince) {
155
- const ifModDate = new Date(ifModifiedSince);
156
- if (stats.mtime <= ifModDate) {
157
- return { statusCode: 304, headers: responseHeaders, body: '' };
158
- }
159
- }
160
- }
161
-
162
- // Check for pre-compressed version
163
- if (precompressed) {
164
- const acceptEncoding = ctx.headers['accept-encoding'] || '';
165
- const compressions = Array.isArray(precompressed)
166
- ? precompressed
167
- : ['br', 'gzip'];
168
-
169
- for (const encoding of compressions) {
170
- if (acceptEncoding.includes(encoding)) {
171
- const ext = encoding === 'br' ? '.br' : '.gz';
172
- const compressedPath = filePath + ext;
173
- if (existsSync(compressedPath)) {
174
- const compressedStats = statSync(compressedPath);
175
- responseHeaders['Content-Encoding'] = encoding;
176
- responseHeaders['Content-Length'] = compressedStats.size.toString();
177
- responseHeaders['Vary'] = 'Accept-Encoding';
178
-
179
- return {
180
- statusCode: 200,
181
- headers: responseHeaders,
182
- body: '',
183
- stream: createReadStream(compressedPath)
184
- };
185
- }
186
- }
187
- }
188
- }
189
-
190
- // Stream the file
191
- return {
192
- statusCode: 200,
193
- headers: responseHeaders,
194
- body: '',
195
- stream: createReadStream(filePath)
196
- };
197
- }
198
-
199
- // Register static file handler
200
- if (normalizedPrefix) {
201
- // With prefix: only serve files under that prefix as routes
202
- app.get(`${normalizedPrefix}`, staticHandler);
203
- app.get(`${normalizedPrefix}/*`, staticHandler);
204
- } else {
205
- // Without prefix: register as fallback handler
206
- // This is called when no routes match, before 404
207
- if (typeof app.setFallbackHandler === 'function') {
208
- app.setFallbackHandler(staticHandler);
209
- } else {
210
- // Fallback: register as low-priority wildcard routes
211
- // NOTE: This should be registered LAST after all API routes
212
- app.get('/', staticHandler);
213
- app.get('/*', staticHandler);
214
- }
215
- }
216
-
217
- if (app.config?.debug) {
218
- console.log(`📁 Static files: ${rootPath}`);
219
- if (normalizedPrefix) {
220
- console.log(` Prefix: ${normalizedPrefix}`);
221
- }
222
- }
223
- }
224
- };
225
- }
@@ -1,24 +0,0 @@
1
- import { Plugin } from '../../core/types';
2
- import { serveStatic } from './serveStatic';
3
-
4
- /**
5
- * Create SPA (Single Page Application) static serving
6
- * Falls back to index.html for client-side routing
7
- *
8
- * @example
9
- * ```typescript
10
- * app.plugin(spa()); // SPA from ./public
11
- * app.plugin(spa('./dist')); // SPA from ./dist
12
- * ```
13
- */
14
-
15
- export function spa(root = './public'): Plugin {
16
- return serveStatic({
17
- root,
18
- fallback: 'index.html',
19
- maxAge: 0, // No cache for HTML
20
- etag: true
21
- });
22
- }
23
-
24
- export type { Plugin };
@@ -1,159 +0,0 @@
1
- /**
2
- * MIME types mapping
3
- */
4
-
5
- export const MIME_TYPES: Record<string, string> = {
6
- // Text
7
- '.html': 'text/html; charset=utf-8',
8
- '.htm': 'text/html; charset=utf-8',
9
- '.css': 'text/css; charset=utf-8',
10
- '.js': 'text/javascript; charset=utf-8',
11
- '.mjs': 'text/javascript; charset=utf-8',
12
- '.json': 'application/json; charset=utf-8',
13
- '.xml': 'application/xml; charset=utf-8',
14
- '.txt': 'text/plain; charset=utf-8',
15
- '.md': 'text/markdown; charset=utf-8',
16
- '.csv': 'text/csv; charset=utf-8',
17
-
18
- // Images
19
- '.png': 'image/png',
20
- '.jpg': 'image/jpeg',
21
- '.jpeg': 'image/jpeg',
22
- '.gif': 'image/gif',
23
- '.webp': 'image/webp',
24
- '.svg': 'image/svg+xml',
25
- '.ico': 'image/x-icon',
26
- '.bmp': 'image/bmp',
27
- '.avif': 'image/avif',
28
-
29
- // Fonts
30
- '.woff': 'font/woff',
31
- '.woff2': 'font/woff2',
32
- '.ttf': 'font/ttf',
33
- '.otf': 'font/otf',
34
- '.eot': 'application/vnd.ms-fontobject',
35
-
36
- // Audio
37
- '.mp3': 'audio/mpeg',
38
- '.wav': 'audio/wav',
39
- '.ogg': 'audio/ogg',
40
- '.m4a': 'audio/mp4',
41
- '.flac': 'audio/flac',
42
-
43
- // Video
44
- '.mp4': 'video/mp4',
45
- '.webm': 'video/webm',
46
- '.avi': 'video/x-msvideo',
47
- '.mov': 'video/quicktime',
48
- '.mkv': 'video/x-matroska',
49
-
50
- // Documents
51
- '.pdf': 'application/pdf',
52
- '.doc': 'application/msword',
53
- '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
54
- '.xls': 'application/vnd.ms-excel',
55
- '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
56
- '.ppt': 'application/vnd.ms-powerpoint',
57
- '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
58
-
59
- // Archives
60
- '.zip': 'application/zip',
61
- '.rar': 'application/vnd.rar',
62
- '.7z': 'application/x-7z-compressed',
63
- '.tar': 'application/x-tar',
64
- '.gz': 'application/gzip',
65
-
66
- // Data
67
- '.wasm': 'application/wasm',
68
- '.map': 'application/json',
69
-
70
- // Default
71
- '': 'application/octet-stream'
72
- };
73
-
74
-
75
- /**
76
- * Static file serving configuration
77
- */
78
- export interface StaticConfig {
79
- /**
80
- * Root directory to serve files from
81
- * @default './public'
82
- */
83
- root?: string;
84
-
85
- /**
86
- * URL prefix for static files
87
- * @default '' (serve from root)
88
- * @example '/static' → /static/image.png serves ./public/image.png
89
- */
90
- prefix?: string;
91
-
92
- /**
93
- * Default file to serve for directory requests
94
- * @default 'index.html'
95
- */
96
- index?: string | string[] | false;
97
-
98
- /**
99
- * Enable directory listing
100
- * @default false
101
- */
102
- directory?: boolean;
103
-
104
- /**
105
- * Maximum age for Cache-Control header (in seconds)
106
- * @default 86400 (1 day)
107
- */
108
- maxAge?: number;
109
-
110
- /**
111
- * Enable immutable caching (for versioned assets)
112
- * @default false
113
- */
114
- immutable?: boolean;
115
-
116
- /**
117
- * Enable ETag generation
118
- * @default true
119
- */
120
- etag?: boolean;
121
-
122
- /**
123
- * Enable Last-Modified header
124
- * @default true
125
- */
126
- lastModified?: boolean;
127
-
128
- /**
129
- * Allowed file extensions (whitelist)
130
- * @default undefined (allow all)
131
- * @example ['.html', '.css', '.js', '.png']
132
- */
133
- extensions?: string[];
134
-
135
- /**
136
- * Hidden files (dotfiles) handling
137
- * @default 'ignore'
138
- */
139
- dotfiles?: 'allow' | 'deny' | 'ignore';
140
-
141
- /**
142
- * Fallback file for SPA routing
143
- * @default undefined
144
- * @example 'index.html' for SPA
145
- */
146
- fallback?: string;
147
-
148
- /**
149
- * Custom headers to add to responses
150
- */
151
- headers?: Record<string, string>;
152
-
153
- /**
154
- * Enable gzip/brotli pre-compressed files
155
- * Looks for .gz or .br versions of files
156
- * @default false
157
- */
158
- precompressed?: boolean | ('gzip' | 'br')[];
159
- }
@@ -1,66 +0,0 @@
1
- import { RouteConfig } from '../../core/types';
2
- import { generateSpec } from './generateSpec';
3
- import { generateSwaggerUI } from './generateSwaggerUI';
4
- import { SwaggerConfig, StoredRoute, OpenAPISchema, OpenAPISpec } from './types';
5
-
6
- // ============================================
7
- // LEGACY EXPORTS (backward compatibility)
8
- // ============================================
9
- /**
10
- * SwaggerGenerator class for advanced/manual usage
11
- * @deprecated Use swagger() plugin instead
12
- */
13
-
14
-
15
- export class SwaggerGenerator {
16
- private config: SwaggerConfig;
17
- private routes: StoredRoute[] = [];
18
- private schemas: Map<string, OpenAPISchema> = new Map();
19
-
20
- constructor(config: SwaggerConfig = {}) {
21
- this.config = {
22
- path: '/docs',
23
- specPath: '/openapi.json',
24
- ...config,
25
- info: {
26
- title: 'API Documentation',
27
- version: '1.0.0',
28
- ...config.info
29
- }
30
- };
31
- }
32
-
33
- registerRoutes(routes: RouteConfig[]): void {
34
- this.routes.push(...routes.map(r => ({
35
- method: r.method,
36
- path: r.path,
37
- schema: r.schema,
38
- meta: r.meta
39
- })));
40
- }
41
-
42
- registerRoute(route: RouteConfig): void {
43
- this.routes.push({
44
- method: route.method,
45
- path: route.path,
46
- schema: route.schema,
47
- meta: route.meta
48
- });
49
- }
50
-
51
- registerSchema(name: string, schema: OpenAPISchema): void {
52
- this.schemas.set(name, schema);
53
- }
54
-
55
- generateSpec(): OpenAPISpec {
56
- return generateSpec(this.routes, this.schemas, this.config, '');
57
- }
58
-
59
- generateSwaggerUI(): string {
60
- return generateSwaggerUI(this.config);
61
- }
62
-
63
- getConfig(): SwaggerConfig {
64
- return this.config;
65
- }
66
- }
@@ -1,61 +0,0 @@
1
- import { buildRequestBody } from './buildRequestBody';
2
- import { buildParameters } from './buildParameters';
3
- import { buildResponses } from './buildResponses';
4
- import { capitalize } from './capitalize';
5
- import { generateOperationId } from './generateOperationId';
6
- import { generateSummary } from './generateSummary';
7
- import { StoredRoute, SwaggerConfig, OpenAPIOperation } from './types';
8
-
9
- /**
10
- * Build OpenAPI operation from route
11
- */
12
-
13
-
14
- export function buildOperation(route: StoredRoute, config: SwaggerConfig): OpenAPIOperation {
15
- const meta = route.meta || {};
16
-
17
- const operation: OpenAPIOperation = {
18
- responses: buildResponses(meta.responses, route.method)
19
- };
20
-
21
- // Auto-generate summary from path if not provided
22
- if (meta.summary) {
23
- operation.summary = meta.summary;
24
- } else {
25
- operation.summary = generateSummary(route.method, route.path);
26
- }
27
-
28
- if (meta.description) {
29
- operation.description = meta.description;
30
- }
31
-
32
- if (meta.tags && meta.tags.length > 0) {
33
- operation.tags = meta.tags;
34
- } else if (!config.hideUntagged) {
35
- // Auto-tag based on first path segment
36
- const firstSegment = route.path.split('/').filter(Boolean)[0];
37
- if (firstSegment && !firstSegment.startsWith(':')) {
38
- operation.tags = [capitalize(firstSegment)];
39
- }
40
- }
41
-
42
- if (meta.deprecated) {
43
- operation.deprecated = true;
44
- }
45
-
46
- // Generate operation ID
47
- operation.operationId = generateOperationId(route.method, route.path);
48
-
49
- // Build parameters from schema
50
- const parameters = buildParameters(route);
51
- if (parameters.length > 0) {
52
- operation.parameters = parameters;
53
- }
54
-
55
- // Build request body for POST/PUT/PATCH
56
- if (route.schema?.body && ['POST', 'PUT', 'PATCH'].includes(route.method)) {
57
- operation.requestBody = buildRequestBody(route.schema);
58
- }
59
-
60
- return operation;
61
- }
@@ -1,61 +0,0 @@
1
- import { zodToOpenAPI } from './zodToOpenAPI';
2
- import { zodSchemaToOpenAPI } from './zodSchemaToOpenAPI';
3
- import { capitalize } from './capitalize';
4
- import { StoredRoute, OpenAPIParameter, OpenAPISchema } from './types';
5
-
6
- /**
7
- * Build parameters from route schema
8
- */
9
-
10
-
11
- export function buildParameters(route: StoredRoute): OpenAPIParameter[] {
12
- const parameters: OpenAPIParameter[] = [];
13
-
14
- // Extract path parameters
15
- const pathParams = route.path.match(/:(\w+)/g);
16
- if (pathParams) {
17
- for (const param of pathParams) {
18
- const name = param.slice(1);
19
- const schemaFromZod = zodToOpenAPI(route.schema?.params, name);
20
- parameters.push({
21
- name,
22
- in: 'path',
23
- required: true,
24
- description: `${capitalize(name)} parameter`,
25
- schema: schemaFromZod || { type: 'string' }
26
- });
27
- }
28
- }
29
-
30
- // Add query parameters from schema
31
- if (route.schema?.query) {
32
- const querySchema = zodSchemaToOpenAPI(route.schema.query);
33
- if (querySchema.properties) {
34
- for (const [name, schema] of Object.entries(querySchema.properties)) {
35
- parameters.push({
36
- name,
37
- in: 'query',
38
- required: querySchema.required?.includes(name) || false,
39
- schema: schema as OpenAPISchema
40
- });
41
- }
42
- }
43
- }
44
-
45
- // Add header parameters from schema
46
- if (route.schema?.headers) {
47
- const headerSchema = zodSchemaToOpenAPI(route.schema.headers);
48
- if (headerSchema.properties) {
49
- for (const [name, schema] of Object.entries(headerSchema.properties)) {
50
- parameters.push({
51
- name,
52
- in: 'header',
53
- required: headerSchema.required?.includes(name) || false,
54
- schema: schema as OpenAPISchema
55
- });
56
- }
57
- }
58
- }
59
-
60
- return parameters;
61
- }
@@ -1,21 +0,0 @@
1
- import { zodSchemaToOpenAPI } from './zodSchemaToOpenAPI';
2
- import { SchemaConfig } from '../../core/types';
3
- import { OpenAPIRequestBody, OpenAPISchema } from './types';
4
-
5
- /**
6
- * Build request body from schema
7
- */
8
-
9
-
10
- export function buildRequestBody(schema: SchemaConfig): OpenAPIRequestBody {
11
- const bodySchema = schema.body ? zodSchemaToOpenAPI(schema.body) : { type: 'object' };
12
-
13
- return {
14
- required: true,
15
- content: {
16
- 'application/json': {
17
- schema: bodySchema as OpenAPISchema
18
- }
19
- }
20
- };
21
- }
@@ -1,54 +0,0 @@
1
- import { HTTPMethod } from '../../core/types';
2
- import { OpenAPIResponse } from './types';
3
-
4
- /**
5
- * Build response objects
6
- */
7
-
8
-
9
- export function buildResponses(
10
- responses?: Record<number, string>,
11
- method?: HTTPMethod
12
- ): Record<string, OpenAPIResponse> {
13
- const result: Record<string, OpenAPIResponse> = {};
14
-
15
- if (responses) {
16
- for (const [code, description] of Object.entries(responses)) {
17
- result[code] = {
18
- description,
19
- content: {
20
- 'application/json': {
21
- schema: { type: 'object' }
22
- }
23
- }
24
- };
25
- }
26
- }
27
-
28
- // Add default responses based on method
29
- if (!result['200'] && !result['201'] && !result['204']) {
30
- if (method === 'POST') {
31
- result['201'] = {
32
- description: 'Created successfully',
33
- content: { 'application/json': { schema: { type: 'object' } } }
34
- };
35
- } else if (method === 'DELETE') {
36
- result['204'] = { description: 'Deleted successfully' };
37
- } else {
38
- result['200'] = {
39
- description: 'Successful response',
40
- content: { 'application/json': { schema: { type: 'object' } } }
41
- };
42
- }
43
- }
44
-
45
- // Add common error responses
46
- if (!result['400']) {
47
- result['400'] = { description: 'Bad request' };
48
- }
49
- if (!result['500']) {
50
- result['500'] = { description: 'Internal server error' };
51
- }
52
-
53
- return result;
54
- }
@@ -1,5 +0,0 @@
1
-
2
-
3
- export function capitalize(str: string): string {
4
- return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
5
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * Convert Express-style path to OpenAPI path
3
- * :id -> {id}
4
- */
5
-
6
-
7
- export function convertPath(path: string): string {
8
- return path.replace(/:(\w+)/g, '{$1}');
9
- }