@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.
Files changed (259) hide show
  1. package/dist/advanced/playground/generatePlaygroundHTML.d.ts.map +1 -1
  2. package/dist/advanced/playground/generatePlaygroundHTML.js +107 -0
  3. package/dist/advanced/playground/generatePlaygroundHTML.js.map +1 -1
  4. package/dist/advanced/playground/playground.d.ts +19 -0
  5. package/dist/advanced/playground/playground.d.ts.map +1 -1
  6. package/dist/advanced/playground/playground.js +70 -0
  7. package/dist/advanced/playground/playground.js.map +1 -1
  8. package/dist/advanced/playground/types.d.ts +20 -0
  9. package/dist/advanced/playground/types.d.ts.map +1 -1
  10. package/dist/core/application.d.ts +14 -0
  11. package/dist/core/application.d.ts.map +1 -1
  12. package/dist/core/application.js +173 -71
  13. package/dist/core/application.js.map +1 -1
  14. package/dist/core/context-pool.d.ts +2 -13
  15. package/dist/core/context-pool.d.ts.map +1 -1
  16. package/dist/core/context-pool.js +7 -45
  17. package/dist/core/context-pool.js.map +1 -1
  18. package/dist/core/context.d.ts +108 -5
  19. package/dist/core/context.d.ts.map +1 -1
  20. package/dist/core/context.js +449 -53
  21. package/dist/core/context.js.map +1 -1
  22. package/dist/core/index.d.ts +1 -0
  23. package/dist/core/index.d.ts.map +1 -1
  24. package/dist/core/index.js +9 -1
  25. package/dist/core/index.js.map +1 -1
  26. package/dist/core/middleware.d.ts +6 -0
  27. package/dist/core/middleware.d.ts.map +1 -1
  28. package/dist/core/middleware.js +83 -84
  29. package/dist/core/middleware.js.map +1 -1
  30. package/dist/core/performance/fast-json.d.ts +149 -0
  31. package/dist/core/performance/fast-json.d.ts.map +1 -0
  32. package/dist/core/performance/fast-json.js +473 -0
  33. package/dist/core/performance/fast-json.js.map +1 -0
  34. package/dist/core/router/file-router.d.ts +20 -7
  35. package/dist/core/router/file-router.d.ts.map +1 -1
  36. package/dist/core/router/file-router.js +41 -13
  37. package/dist/core/router/file-router.js.map +1 -1
  38. package/dist/core/router/index.d.ts +6 -0
  39. package/dist/core/router/index.d.ts.map +1 -1
  40. package/dist/core/router/index.js +33 -6
  41. package/dist/core/router/index.js.map +1 -1
  42. package/dist/core/router/radix-tree.d.ts +4 -1
  43. package/dist/core/router/radix-tree.d.ts.map +1 -1
  44. package/dist/core/router/radix-tree.js +7 -3
  45. package/dist/core/router/radix-tree.js.map +1 -1
  46. package/dist/core/serializer.d.ts +251 -0
  47. package/dist/core/serializer.d.ts.map +1 -0
  48. package/dist/core/serializer.js +290 -0
  49. package/dist/core/serializer.js.map +1 -0
  50. package/dist/core/types.d.ts +39 -1
  51. package/dist/core/types.d.ts.map +1 -1
  52. package/dist/core/types.js.map +1 -1
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +12 -2
  56. package/dist/index.js.map +1 -1
  57. package/package.json +3 -1
  58. package/documentation/01-getting-started.md +0 -240
  59. package/documentation/02-context.md +0 -335
  60. package/documentation/03-routing.md +0 -397
  61. package/documentation/04-middleware.md +0 -483
  62. package/documentation/05-validation.md +0 -514
  63. package/documentation/06-error-handling.md +0 -465
  64. package/documentation/07-performance.md +0 -364
  65. package/documentation/08-adapters.md +0 -470
  66. package/documentation/09-api-reference.md +0 -548
  67. package/documentation/10-examples.md +0 -582
  68. package/documentation/11-deployment.md +0 -477
  69. package/documentation/12-sentry.md +0 -620
  70. package/documentation/13-sentry-data-storage.md +0 -996
  71. package/documentation/14-sentry-data-reference.md +0 -457
  72. package/documentation/15-sentry-summary.md +0 -409
  73. package/documentation/16-alerts-system.md +0 -745
  74. package/documentation/17-alert-adapters.md +0 -696
  75. package/documentation/18-alerts-implementation-summary.md +0 -385
  76. package/documentation/19-class-based-routing.md +0 -840
  77. package/documentation/20-websocket-realtime.md +0 -813
  78. package/documentation/21-cache-system.md +0 -510
  79. package/documentation/22-job-queue.md +0 -772
  80. package/documentation/23-sentry-plugin.md +0 -551
  81. package/documentation/24-testing-utilities.md +0 -1287
  82. package/documentation/25-api-versioning.md +0 -533
  83. package/documentation/26-context-store.md +0 -607
  84. package/documentation/27-dependency-injection.md +0 -329
  85. package/documentation/28-lifecycle-hooks.md +0 -521
  86. package/documentation/29-package-structure.md +0 -196
  87. package/documentation/30-plugin-system.md +0 -414
  88. package/documentation/31-jwt-authentication.md +0 -597
  89. package/documentation/32-cli.md +0 -268
  90. package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
  91. package/documentation/ALERTS-INDEX.md +0 -330
  92. package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
  93. package/documentation/README.md +0 -178
  94. package/documentation/index.html +0 -34
  95. package/modern_framework_paper.md +0 -1870
  96. package/public/css/style.css +0 -87
  97. package/public/index.html +0 -34
  98. package/public/js/app.js +0 -27
  99. package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
  100. package/src/advanced/cache/MultiTierCache.ts +0 -194
  101. package/src/advanced/cache/RedisCacheStore.ts +0 -341
  102. package/src/advanced/cache/index.ts +0 -5
  103. package/src/advanced/cache/types.ts +0 -40
  104. package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
  105. package/src/advanced/graphql/index.ts +0 -22
  106. package/src/advanced/graphql/server.ts +0 -252
  107. package/src/advanced/graphql/types.ts +0 -42
  108. package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
  109. package/src/advanced/jobs/JobQueue.ts +0 -556
  110. package/src/advanced/jobs/RedisQueueStore.ts +0 -367
  111. package/src/advanced/jobs/index.ts +0 -5
  112. package/src/advanced/jobs/types.ts +0 -70
  113. package/src/advanced/observability/APMManager.ts +0 -163
  114. package/src/advanced/observability/AlertManager.ts +0 -109
  115. package/src/advanced/observability/MetricRegistry.ts +0 -151
  116. package/src/advanced/observability/ObservabilityCenter.ts +0 -304
  117. package/src/advanced/observability/StructuredLogger.ts +0 -154
  118. package/src/advanced/observability/TracingManager.ts +0 -117
  119. package/src/advanced/observability/adapters.ts +0 -304
  120. package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
  121. package/src/advanced/observability/index.ts +0 -11
  122. package/src/advanced/observability/types.ts +0 -174
  123. package/src/advanced/playground/extractPathParams.ts +0 -6
  124. package/src/advanced/playground/generateFieldExample.ts +0 -31
  125. package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1849
  126. package/src/advanced/playground/generateSummary.ts +0 -19
  127. package/src/advanced/playground/getTagFromPath.ts +0 -9
  128. package/src/advanced/playground/index.ts +0 -8
  129. package/src/advanced/playground/playground.ts +0 -170
  130. package/src/advanced/playground/types.ts +0 -20
  131. package/src/advanced/playground/zodToExample.ts +0 -16
  132. package/src/advanced/playground/zodToParams.ts +0 -15
  133. package/src/advanced/postman/buildAuth.ts +0 -31
  134. package/src/advanced/postman/buildBody.ts +0 -15
  135. package/src/advanced/postman/buildQueryParams.ts +0 -27
  136. package/src/advanced/postman/buildRequestItem.ts +0 -36
  137. package/src/advanced/postman/buildResponses.ts +0 -11
  138. package/src/advanced/postman/buildUrl.ts +0 -33
  139. package/src/advanced/postman/capitalize.ts +0 -4
  140. package/src/advanced/postman/generateCollection.ts +0 -59
  141. package/src/advanced/postman/generateEnvironment.ts +0 -34
  142. package/src/advanced/postman/generateExampleFromZod.ts +0 -21
  143. package/src/advanced/postman/generateFieldExample.ts +0 -45
  144. package/src/advanced/postman/generateName.ts +0 -20
  145. package/src/advanced/postman/generateUUID.ts +0 -11
  146. package/src/advanced/postman/getTagFromPath.ts +0 -10
  147. package/src/advanced/postman/index.ts +0 -28
  148. package/src/advanced/postman/postman.ts +0 -156
  149. package/src/advanced/postman/slugify.ts +0 -7
  150. package/src/advanced/postman/types.ts +0 -140
  151. package/src/advanced/realtime/index.ts +0 -18
  152. package/src/advanced/realtime/websocket.ts +0 -231
  153. package/src/advanced/sentry/index.ts +0 -1236
  154. package/src/advanced/sentry/types.ts +0 -355
  155. package/src/advanced/static/generateDirectoryListing.ts +0 -47
  156. package/src/advanced/static/generateETag.ts +0 -7
  157. package/src/advanced/static/getMimeType.ts +0 -9
  158. package/src/advanced/static/index.ts +0 -32
  159. package/src/advanced/static/isSafePath.ts +0 -13
  160. package/src/advanced/static/publicDir.ts +0 -21
  161. package/src/advanced/static/serveStatic.ts +0 -225
  162. package/src/advanced/static/spa.ts +0 -24
  163. package/src/advanced/static/types.ts +0 -159
  164. package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
  165. package/src/advanced/swagger/buildOperation.ts +0 -61
  166. package/src/advanced/swagger/buildParameters.ts +0 -61
  167. package/src/advanced/swagger/buildRequestBody.ts +0 -21
  168. package/src/advanced/swagger/buildResponses.ts +0 -54
  169. package/src/advanced/swagger/capitalize.ts +0 -5
  170. package/src/advanced/swagger/convertPath.ts +0 -9
  171. package/src/advanced/swagger/createSwagger.ts +0 -12
  172. package/src/advanced/swagger/generateOperationId.ts +0 -21
  173. package/src/advanced/swagger/generateSpec.ts +0 -105
  174. package/src/advanced/swagger/generateSummary.ts +0 -24
  175. package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
  176. package/src/advanced/swagger/generateThemeCss.ts +0 -53
  177. package/src/advanced/swagger/index.ts +0 -25
  178. package/src/advanced/swagger/swagger.ts +0 -237
  179. package/src/advanced/swagger/types.ts +0 -206
  180. package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
  181. package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
  182. package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
  183. package/src/advanced/testing/factory.ts +0 -509
  184. package/src/advanced/testing/harness.ts +0 -612
  185. package/src/advanced/testing/index.ts +0 -430
  186. package/src/advanced/testing/load-test.ts +0 -618
  187. package/src/advanced/testing/mock-server.ts +0 -498
  188. package/src/advanced/testing/mock.ts +0 -670
  189. package/src/cli/bin.ts +0 -9
  190. package/src/cli/cli.ts +0 -158
  191. package/src/cli/commands/add.ts +0 -178
  192. package/src/cli/commands/build.ts +0 -73
  193. package/src/cli/commands/create.ts +0 -166
  194. package/src/cli/commands/dev.ts +0 -85
  195. package/src/cli/commands/generate.ts +0 -99
  196. package/src/cli/commands/help.ts +0 -95
  197. package/src/cli/commands/init.ts +0 -91
  198. package/src/cli/commands/version.ts +0 -38
  199. package/src/cli/index.ts +0 -6
  200. package/src/cli/templates/generators.ts +0 -359
  201. package/src/cli/templates/index.ts +0 -680
  202. package/src/cli/utils/exec.ts +0 -52
  203. package/src/cli/utils/file-system.ts +0 -78
  204. package/src/cli/utils/logger.ts +0 -111
  205. package/src/core/adapter.ts +0 -88
  206. package/src/core/application.ts +0 -1335
  207. package/src/core/context-pool.ts +0 -127
  208. package/src/core/context.ts +0 -412
  209. package/src/core/index.ts +0 -80
  210. package/src/core/middleware.ts +0 -262
  211. package/src/core/performance/buffer-pool.ts +0 -108
  212. package/src/core/performance/middleware-optimizer.ts +0 -162
  213. package/src/core/plugin/PluginManager.ts +0 -435
  214. package/src/core/plugin/builder.ts +0 -358
  215. package/src/core/plugin/index.ts +0 -50
  216. package/src/core/plugin/types.ts +0 -214
  217. package/src/core/router/file-router.ts +0 -594
  218. package/src/core/router/index.ts +0 -227
  219. package/src/core/router/radix-tree.ts +0 -226
  220. package/src/core/store/index.ts +0 -30
  221. package/src/core/store/registry.ts +0 -178
  222. package/src/core/store/request-store.ts +0 -240
  223. package/src/core/store/types.ts +0 -233
  224. package/src/core/types.ts +0 -574
  225. package/src/database/adapter.ts +0 -35
  226. package/src/database/adapters/index.ts +0 -1
  227. package/src/database/adapters/mysql.ts +0 -669
  228. package/src/database/database.ts +0 -70
  229. package/src/database/dialect.ts +0 -388
  230. package/src/database/index.ts +0 -12
  231. package/src/database/migrations.ts +0 -86
  232. package/src/database/optimizer.ts +0 -125
  233. package/src/database/query-builder.ts +0 -404
  234. package/src/database/realtime.ts +0 -53
  235. package/src/database/schema.ts +0 -71
  236. package/src/database/transactions.ts +0 -56
  237. package/src/database/types.ts +0 -87
  238. package/src/deployment/cluster.ts +0 -471
  239. package/src/deployment/config.ts +0 -454
  240. package/src/deployment/docker.ts +0 -599
  241. package/src/deployment/graceful-shutdown.ts +0 -373
  242. package/src/deployment/index.ts +0 -56
  243. package/src/index.ts +0 -264
  244. package/src/security/adapter.ts +0 -318
  245. package/src/security/auth/JWTPlugin.ts +0 -234
  246. package/src/security/auth/JWTProvider.ts +0 -316
  247. package/src/security/auth/adapter.ts +0 -12
  248. package/src/security/auth/jwt.ts +0 -234
  249. package/src/security/auth/middleware.ts +0 -188
  250. package/src/security/csrf.ts +0 -220
  251. package/src/security/headers.ts +0 -108
  252. package/src/security/index.ts +0 -60
  253. package/src/security/rate-limit/adapter.ts +0 -7
  254. package/src/security/rate-limit/memory.ts +0 -108
  255. package/src/security/rate-limit/middleware.ts +0 -181
  256. package/src/security/sanitization.ts +0 -75
  257. package/src/security/types.ts +0 -240
  258. package/src/security/utils.ts +0 -52
  259. 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
- }