@engjts/nexus 0.1.6 → 0.1.8

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 (78) hide show
  1. package/BENCHMARK_REPORT.md +343 -0
  2. package/dist/advanced/playground/generatePlaygroundHTML.d.ts.map +1 -1
  3. package/dist/advanced/playground/generatePlaygroundHTML.js +107 -0
  4. package/dist/advanced/playground/generatePlaygroundHTML.js.map +1 -1
  5. package/dist/advanced/playground/playground.d.ts +19 -0
  6. package/dist/advanced/playground/playground.d.ts.map +1 -1
  7. package/dist/advanced/playground/playground.js +70 -0
  8. package/dist/advanced/playground/playground.js.map +1 -1
  9. package/dist/advanced/playground/types.d.ts +20 -0
  10. package/dist/advanced/playground/types.d.ts.map +1 -1
  11. package/dist/cli/templates/generators.d.ts.map +1 -1
  12. package/dist/cli/templates/generators.js +16 -13
  13. package/dist/cli/templates/generators.js.map +1 -1
  14. package/dist/cli/templates/index.js +25 -25
  15. package/dist/core/application.d.ts +14 -0
  16. package/dist/core/application.d.ts.map +1 -1
  17. package/dist/core/application.js +173 -71
  18. package/dist/core/application.js.map +1 -1
  19. package/dist/core/context-pool.d.ts +2 -13
  20. package/dist/core/context-pool.d.ts.map +1 -1
  21. package/dist/core/context-pool.js +7 -45
  22. package/dist/core/context-pool.js.map +1 -1
  23. package/dist/core/context.d.ts +108 -5
  24. package/dist/core/context.d.ts.map +1 -1
  25. package/dist/core/context.js +449 -53
  26. package/dist/core/context.js.map +1 -1
  27. package/dist/core/index.d.ts +1 -0
  28. package/dist/core/index.d.ts.map +1 -1
  29. package/dist/core/index.js +9 -1
  30. package/dist/core/index.js.map +1 -1
  31. package/dist/core/middleware.d.ts +6 -0
  32. package/dist/core/middleware.d.ts.map +1 -1
  33. package/dist/core/middleware.js +83 -84
  34. package/dist/core/middleware.js.map +1 -1
  35. package/dist/core/performance/fast-json.d.ts +149 -0
  36. package/dist/core/performance/fast-json.d.ts.map +1 -0
  37. package/dist/core/performance/fast-json.js +473 -0
  38. package/dist/core/performance/fast-json.js.map +1 -0
  39. package/dist/core/router/file-router.d.ts +20 -7
  40. package/dist/core/router/file-router.d.ts.map +1 -1
  41. package/dist/core/router/file-router.js +41 -13
  42. package/dist/core/router/file-router.js.map +1 -1
  43. package/dist/core/router/index.d.ts +6 -0
  44. package/dist/core/router/index.d.ts.map +1 -1
  45. package/dist/core/router/index.js +33 -6
  46. package/dist/core/router/index.js.map +1 -1
  47. package/dist/core/router/radix-tree.d.ts +4 -1
  48. package/dist/core/router/radix-tree.d.ts.map +1 -1
  49. package/dist/core/router/radix-tree.js +7 -3
  50. package/dist/core/router/radix-tree.js.map +1 -1
  51. package/dist/core/serializer.d.ts +251 -0
  52. package/dist/core/serializer.d.ts.map +1 -0
  53. package/dist/core/serializer.js +290 -0
  54. package/dist/core/serializer.js.map +1 -0
  55. package/dist/core/types.d.ts +39 -1
  56. package/dist/core/types.d.ts.map +1 -1
  57. package/dist/core/types.js.map +1 -1
  58. package/dist/index.d.ts +1 -0
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +12 -2
  61. package/dist/index.js.map +1 -1
  62. package/package.json +3 -1
  63. package/src/advanced/playground/generatePlaygroundHTML.ts +107 -0
  64. package/src/advanced/playground/playground.ts +225 -145
  65. package/src/advanced/playground/types.ts +29 -0
  66. package/src/cli/templates/generators.ts +16 -13
  67. package/src/cli/templates/index.ts +25 -25
  68. package/src/core/application.ts +202 -84
  69. package/src/core/context-pool.ts +8 -56
  70. package/src/core/context.ts +497 -53
  71. package/src/core/index.ts +14 -0
  72. package/src/core/middleware.ts +99 -89
  73. package/src/core/router/file-router.ts +41 -12
  74. package/src/core/router/index.ts +213 -180
  75. package/src/core/router/radix-tree.ts +20 -4
  76. package/src/core/serializer.ts +397 -0
  77. package/src/core/types.ts +43 -1
  78. package/src/index.ts +17 -0
@@ -0,0 +1,473 @@
1
+ "use strict";
2
+ /**
3
+ * Fast JSON Serialization
4
+ *
5
+ * Provides optimized JSON serialization for common response patterns.
6
+ * Inspired by fast-json-stringify but zero dependencies.
7
+ *
8
+ * Key optimizations:
9
+ * 1. Schema-based serialization with pre-compiled serializers
10
+ * 2. Avoids JSON.stringify overhead for simple objects
11
+ * 3. Caches stringified templates for known schemas
12
+ * 4. Fast path for primitives and simple objects
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.FastSerializers = void 0;
16
+ exports.createSerializer = createSerializer;
17
+ exports.fastStringify = fastStringify;
18
+ exports.createRouteSerializer = createRouteSerializer;
19
+ /**
20
+ * Pre-compiled serializer cache
21
+ */
22
+ const serializerCache = new Map();
23
+ /**
24
+ * Create a fast serializer from a JSON schema
25
+ * Pre-compiles the serialization logic for maximum performance
26
+ */
27
+ function createSerializer(schema) {
28
+ const schemaKey = JSON.stringify(schema);
29
+ // Check cache first
30
+ const cached = serializerCache.get(schemaKey);
31
+ if (cached) {
32
+ return cached;
33
+ }
34
+ // Compile new serializer
35
+ const serializer = compileSerializer(schema);
36
+ serializerCache.set(schemaKey, serializer);
37
+ return serializer;
38
+ }
39
+ /**
40
+ * Compile a serializer function from schema
41
+ */
42
+ function compileSerializer(schema) {
43
+ switch (schema.type) {
44
+ case 'string':
45
+ return serializeString;
46
+ case 'number':
47
+ return serializeNumber;
48
+ case 'boolean':
49
+ return serializeBoolean;
50
+ case 'null':
51
+ return () => 'null';
52
+ case 'array':
53
+ return compileSchemaArraySerializer(schema);
54
+ case 'object':
55
+ return compileObjectSerializer(schema);
56
+ default:
57
+ // Fallback to JSON.stringify
58
+ return JSON.stringify;
59
+ }
60
+ }
61
+ /**
62
+ * Fast string serialization with escape handling
63
+ */
64
+ function serializeString(value) {
65
+ // Fast path: no special characters
66
+ if (!needsEscape(value)) {
67
+ return `"${value}"`;
68
+ }
69
+ return JSON.stringify(value);
70
+ }
71
+ /**
72
+ * Check if string needs escaping
73
+ * Avoids full escape processing for simple strings (90%+ of cases)
74
+ */
75
+ function needsEscape(str) {
76
+ for (let i = 0; i < str.length; i++) {
77
+ const c = str.charCodeAt(i);
78
+ // Check for: " \ and control characters (< 32)
79
+ if (c === 34 || c === 92 || c < 32) {
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ }
85
+ /**
86
+ * Fast number serialization
87
+ */
88
+ function serializeNumber(value) {
89
+ // Fast path for integers
90
+ if (Number.isInteger(value)) {
91
+ return String(value);
92
+ }
93
+ // Handle special cases
94
+ if (!Number.isFinite(value)) {
95
+ return 'null';
96
+ }
97
+ return String(value);
98
+ }
99
+ /**
100
+ * Fast boolean serialization
101
+ */
102
+ function serializeBoolean(value) {
103
+ return value ? 'true' : 'false';
104
+ }
105
+ /**
106
+ * Compile array serializer for schema-based compilation
107
+ * This is used when a schema is provided
108
+ */
109
+ function compileSchemaArraySerializer(schema) {
110
+ if (!schema.items) {
111
+ // Unknown item type, use fast runtime detection
112
+ return fastStringifyArray;
113
+ }
114
+ const itemSerializer = compileSerializer(schema.items);
115
+ return (arr) => {
116
+ if (!arr || arr.length === 0) {
117
+ return '[]';
118
+ }
119
+ let result = '[';
120
+ for (let i = 0; i < arr.length; i++) {
121
+ if (i > 0)
122
+ result += ',';
123
+ result += itemSerializer(arr[i]);
124
+ }
125
+ result += ']';
126
+ return result;
127
+ };
128
+ }
129
+ /**
130
+ * Ultra-fast array serialization
131
+ * Detects array content type and uses optimized path
132
+ */
133
+ function fastStringifyArray(arr) {
134
+ if (arr.length === 0)
135
+ return '[]';
136
+ // Sample first item to detect type
137
+ const firstItem = arr[0];
138
+ const firstType = typeof firstItem;
139
+ // Fast path: array of primitives
140
+ if (firstType === 'string' || firstType === 'number' || firstType === 'boolean') {
141
+ let result = '[';
142
+ for (let i = 0; i < arr.length; i++) {
143
+ if (i > 0)
144
+ result += ',';
145
+ const item = arr[i];
146
+ const itemType = typeof item;
147
+ if (itemType === 'string') {
148
+ result += serializeString(item);
149
+ }
150
+ else if (itemType === 'number') {
151
+ result += serializeNumber(item);
152
+ }
153
+ else if (itemType === 'boolean') {
154
+ result += serializeBoolean(item);
155
+ }
156
+ else {
157
+ result += 'null';
158
+ }
159
+ }
160
+ result += ']';
161
+ return result;
162
+ }
163
+ // Fast path: array of simple objects (like user list)
164
+ if (firstType === 'object' && firstItem !== null && !Array.isArray(firstItem)) {
165
+ // Detect object shape from first item
166
+ const keys = Object.keys(firstItem);
167
+ const keyCount = keys.length;
168
+ // Only optimize small objects (< 20 properties)
169
+ if (keyCount > 0 && keyCount <= 20) {
170
+ // Check if all items have same shape
171
+ let sameShape = true;
172
+ for (let i = 1; i < Math.min(arr.length, 5); i++) {
173
+ const item = arr[i];
174
+ if (!item || typeof item !== 'object' || Object.keys(item).length !== keyCount) {
175
+ sameShape = false;
176
+ break;
177
+ }
178
+ }
179
+ if (sameShape) {
180
+ // Use optimized serialization for uniform objects
181
+ let result = '[';
182
+ for (let i = 0; i < arr.length; i++) {
183
+ if (i > 0)
184
+ result += ',';
185
+ result += fastStringifyObject(arr[i], keys);
186
+ }
187
+ result += ']';
188
+ return result;
189
+ }
190
+ }
191
+ }
192
+ // Fallback for complex/mixed arrays
193
+ return JSON.stringify(arr);
194
+ }
195
+ /**
196
+ * Fast object serialization with known keys
197
+ * Used for array of objects with uniform shape
198
+ */
199
+ function fastStringifyObject(obj, keys) {
200
+ if (obj === null || obj === undefined)
201
+ return 'null';
202
+ const objKeys = keys || Object.keys(obj);
203
+ let result = '{';
204
+ let first = true;
205
+ for (const key of objKeys) {
206
+ const value = obj[key];
207
+ if (value === undefined)
208
+ continue;
209
+ if (!first)
210
+ result += ',';
211
+ first = false;
212
+ // Pre-computed key (avoid multiple escapes)
213
+ result += `"${key}":`;
214
+ const valueType = typeof value;
215
+ if (valueType === 'string') {
216
+ result += serializeString(value);
217
+ }
218
+ else if (valueType === 'number') {
219
+ result += serializeNumber(value);
220
+ }
221
+ else if (valueType === 'boolean') {
222
+ result += serializeBoolean(value);
223
+ }
224
+ else if (value === null) {
225
+ result += 'null';
226
+ }
227
+ else if (Array.isArray(value)) {
228
+ // Nested arrays - use fast path if simple
229
+ result += fastStringifyArray(value);
230
+ }
231
+ else if (valueType === 'object') {
232
+ // Nested object - recurse with fast path
233
+ result += fastStringifyObject(value);
234
+ }
235
+ else {
236
+ result += JSON.stringify(value);
237
+ }
238
+ }
239
+ result += '}';
240
+ return result;
241
+ }
242
+ /**
243
+ * Compile object serializer - the key optimization!
244
+ * Pre-computes property order and serializers
245
+ */
246
+ function compileObjectSerializer(schema) {
247
+ const properties = schema.properties;
248
+ if (!properties || Object.keys(properties).length === 0) {
249
+ // No schema, use JSON.stringify
250
+ return JSON.stringify;
251
+ }
252
+ const keys = Object.keys(properties);
253
+ const propSerializers = [];
254
+ // Pre-compile each property's serializer
255
+ for (const key of keys) {
256
+ propSerializers.push({
257
+ key,
258
+ serializer: compileSerializer(properties[key]),
259
+ jsonKey: `"${key}":` // Pre-compute the key string
260
+ });
261
+ }
262
+ // Return optimized serializer
263
+ return (obj) => {
264
+ if (obj === null || obj === undefined) {
265
+ return 'null';
266
+ }
267
+ let result = '{';
268
+ let first = true;
269
+ for (const prop of propSerializers) {
270
+ const value = obj[prop.key];
271
+ if (value !== undefined) {
272
+ if (!first)
273
+ result += ',';
274
+ first = false;
275
+ result += prop.jsonKey;
276
+ result += prop.serializer(value);
277
+ }
278
+ }
279
+ // Handle additional properties if schema allows
280
+ if (schema.additionalProperties !== false) {
281
+ for (const key in obj) {
282
+ if (!properties[key] && obj[key] !== undefined) {
283
+ if (!first)
284
+ result += ',';
285
+ first = false;
286
+ result += `"${key}":`;
287
+ result += JSON.stringify(obj[key]);
288
+ }
289
+ }
290
+ }
291
+ result += '}';
292
+ return result;
293
+ };
294
+ }
295
+ /**
296
+ * Ultra-fast serializers for common response patterns
297
+ * These are hand-optimized for maximum performance
298
+ */
299
+ exports.FastSerializers = {
300
+ /**
301
+ * { "message": string }
302
+ * Common for simple JSON responses like "Hello, World!"
303
+ */
304
+ message: (data) => {
305
+ const msg = data.message;
306
+ if (!needsEscape(msg)) {
307
+ return `{"message":"${msg}"}`;
308
+ }
309
+ return `{"message":${JSON.stringify(msg)}}`;
310
+ },
311
+ /**
312
+ * { "echo": string }
313
+ * Common for echo endpoints
314
+ */
315
+ echo: (data) => {
316
+ const echo = data.echo;
317
+ if (!needsEscape(echo)) {
318
+ return `{"echo":"${echo}"}`;
319
+ }
320
+ return `{"echo":${JSON.stringify(echo)}}`;
321
+ },
322
+ /**
323
+ * { "success": boolean, "data": any }
324
+ * Common API response wrapper
325
+ */
326
+ successResponse: (data) => {
327
+ if (data.data === undefined) {
328
+ return data.success ? '{"success":true}' : '{"success":false}';
329
+ }
330
+ return `{"success":${data.success},"data":${JSON.stringify(data.data)}}`;
331
+ },
332
+ /**
333
+ * { "error": string }
334
+ * Common error response
335
+ */
336
+ error: (data) => {
337
+ const err = data.error;
338
+ if (!needsEscape(err)) {
339
+ return `{"error":"${err}"}`;
340
+ }
341
+ return `{"error":${JSON.stringify(err)}}`;
342
+ },
343
+ /**
344
+ * { "received": any, "processed": boolean }
345
+ * Common for POST echo endpoints
346
+ * OPTIMIZED: Use fast path for nested data
347
+ */
348
+ received: (data) => {
349
+ const receivedType = typeof data.received;
350
+ let receivedStr;
351
+ // Fast path for primitives and simple objects
352
+ if (receivedType === 'string') {
353
+ receivedStr = serializeString(data.received);
354
+ }
355
+ else if (receivedType === 'number') {
356
+ receivedStr = serializeNumber(data.received);
357
+ }
358
+ else if (receivedType === 'boolean') {
359
+ receivedStr = serializeBoolean(data.received);
360
+ }
361
+ else if (data.received === null) {
362
+ receivedStr = 'null';
363
+ }
364
+ else if (Array.isArray(data.received)) {
365
+ receivedStr = fastStringifyArray(data.received);
366
+ }
367
+ else if (receivedType === 'object') {
368
+ receivedStr = fastStringifyObject(data.received);
369
+ }
370
+ else {
371
+ receivedStr = JSON.stringify(data.received);
372
+ }
373
+ return `{"received":${receivedStr},"processed":${data.processed}}`;
374
+ }
375
+ };
376
+ /**
377
+ * Smart JSON stringify that uses fast paths when possible
378
+ * Falls back to JSON.stringify for complex objects
379
+ *
380
+ * OPTIMIZED: Now handles arrays efficiently!
381
+ */
382
+ function fastStringify(data) {
383
+ if (data === null)
384
+ return 'null';
385
+ if (data === undefined)
386
+ return 'undefined';
387
+ const type = typeof data;
388
+ // Fast paths for primitives
389
+ if (type === 'string')
390
+ return serializeString(data);
391
+ if (type === 'number')
392
+ return serializeNumber(data);
393
+ if (type === 'boolean')
394
+ return serializeBoolean(data);
395
+ // Check for known patterns (hot path optimization)
396
+ if (type === 'object') {
397
+ // Handle arrays with optimized path - BIG WIN for /users endpoint!
398
+ if (Array.isArray(data)) {
399
+ return fastStringifyArray(data);
400
+ }
401
+ // Single property objects - very common in APIs
402
+ const keys = Object.keys(data);
403
+ const keyCount = keys.length;
404
+ if (keyCount === 1) {
405
+ const key = keys[0];
406
+ const value = data[key];
407
+ // { "message": "..." } pattern
408
+ if (key === 'message' && typeof value === 'string') {
409
+ return exports.FastSerializers.message(data);
410
+ }
411
+ // { "echo": "..." } pattern
412
+ if (key === 'echo' && typeof value === 'string') {
413
+ return exports.FastSerializers.echo(data);
414
+ }
415
+ // { "error": "..." } pattern
416
+ if (key === 'error' && typeof value === 'string') {
417
+ return exports.FastSerializers.error(data);
418
+ }
419
+ }
420
+ // Two property patterns - common API responses
421
+ if (keyCount === 2) {
422
+ // { "success": boolean, "data": any }
423
+ if ('success' in data && 'data' in data) {
424
+ return exports.FastSerializers.successResponse(data);
425
+ }
426
+ // { "received": any, "processed": boolean } - POST echo pattern!
427
+ if ('received' in data && 'processed' in data) {
428
+ return exports.FastSerializers.received(data);
429
+ }
430
+ }
431
+ // Multi-property objects - use fast path
432
+ if (keyCount > 2 && keyCount <= 50) {
433
+ return fastStringifyObject(data);
434
+ }
435
+ }
436
+ // Fallback to native JSON.stringify for very complex objects
437
+ return JSON.stringify(data);
438
+ }
439
+ /**
440
+ * Create a route-specific serializer based on schema
441
+ * Use this in route registration to pre-compile serializers
442
+ *
443
+ * @example
444
+ * ```typescript
445
+ * const serialize = createRouteSerializer({
446
+ * type: 'object',
447
+ * properties: {
448
+ * id: { type: 'number' },
449
+ * name: { type: 'string' },
450
+ * email: { type: 'string' }
451
+ * }
452
+ * });
453
+ *
454
+ * app.get('/user/:id', async (ctx) => {
455
+ * const user = await getUser(ctx.params.id);
456
+ * return {
457
+ * statusCode: 200,
458
+ * headers: { 'Content-Type': 'application/json' },
459
+ * body: serialize(user) // 2-3x faster than JSON.stringify!
460
+ * };
461
+ * });
462
+ * ```
463
+ */
464
+ function createRouteSerializer(schema) {
465
+ return createSerializer(schema);
466
+ }
467
+ exports.default = {
468
+ createSerializer,
469
+ createRouteSerializer,
470
+ fastStringify,
471
+ FastSerializers: exports.FastSerializers
472
+ };
473
+ //# sourceMappingURL=fast-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fast-json.js","sourceRoot":"","sources":["../../../src/core/performance/fast-json.ts"],"names":[],"mappings":"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"}
@@ -4,20 +4,26 @@
4
4
  * Automatically scans a directory and registers routes based on file/folder structure.
5
5
  * Designed for class-based routing: 1 file = 1 class = 1 route.
6
6
  *
7
- * Smart filename conventions:
7
+ * Smart filename conventions (only if no body schema):
8
8
  * - `index.ts` → GET (default), maps to parent path
9
9
  * - `create.ts` → POST, maps to parent path (not /create)
10
10
  * - `update.ts` → PUT, maps to parent path (not /update)
11
11
  * - `delete.ts` → DELETE, maps to parent path (not /delete)
12
12
  * - `patch.ts` → PATCH, maps to parent path (not /patch)
13
- * - Other files → GET (or specify `method` in class)
13
+ * - Other files → GET (default)
14
+ *
15
+ * Smart body detection (HIGHEST PRIORITY after explicit method):
16
+ * - If schema() returns object with `body` property → POST
17
+ * - Works with inheritance (parent class schema is checked too)
18
+ * - Overrides smart filename detection!
19
+ * - Override by explicitly setting `method` property in class
14
20
  *
15
21
  * @example
16
22
  * ```
17
23
  * routes/
18
24
  * api/
19
25
  * auth/
20
- * register.ts → POST /api/auth/register (method = 'POST' in class)
26
+ * register.ts → POST /api/auth/register (auto-detected via ctx.body!)
21
27
  * login.ts → POST /api/auth/login
22
28
  * users/
23
29
  * index.ts → GET /api/users
@@ -31,11 +37,18 @@
31
37
  * Each file exports a class:
32
38
  * ```typescript
33
39
  * export default class RegisterRoute {
34
- * method = 'POST' // Optional if filename is create/update/delete
40
+ * // No need to specify method = 'POST' if schema has body!
41
+ *
42
+ * schema() {
43
+ * return {
44
+ * body: z.object({ ... }) // ← auto-detects POST!
45
+ * };
46
+ * }
35
47
  *
36
- * schema() { ... }
37
- * meta() { ... }
38
- * async handler(ctx: Context) { ... }
48
+ * async handler(ctx: Context) {
49
+ * const data = ctx.body;
50
+ * ...
51
+ * }
39
52
  * }
40
53
  * ```
41
54
  */
@@ -1 +1 @@
1
- {"version":3,"file":"file-router.d.ts","sourceRoot":"","sources":["../../../src/core/router/file-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACH,UAAU,EACV,OAAO,EAEP,YAAY,EACZ,SAAS,EACT,UAAU,EAGb,MAAM,UAAU,CAAC;AAsClB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,kDAAkD;IAClD,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,YAAY,CAAC;IAC5B,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,SAAS,CAAC;IACvB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,UAAU,EAAE,CAAC;IACjC,wBAAwB;IACxB,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,sCAAsC;IACtC,OAAO,CAAC,EAAE,cAAc,GAAG,CAAC,UAAU,cAAc,CAAC,CAAC;CACzD;AAED;;GAEG;AACH,UAAU,WAAW;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;;;GAQG;AACH,qBAAa,UAAU;IACnB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,eAAe,CAAyB;gBAEpC,OAAO,EAAE,iBAAiB;IAWtC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAoBpC;;OAEG;IACG,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B/C;;OAEG;YACW,aAAa;IA4C3B;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAgCpB;;OAEG;IACH,OAAO,CAAC,cAAc;IA+BtB;;OAEG;YACW,aAAa;IAgJ3B;;OAEG;YACW,cAAc;IAwB5B;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAKnC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAEvE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,aAAa,CAC/B,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,iBAAiB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAGf"}
1
+ {"version":3,"file":"file-router.d.ts","sourceRoot":"","sources":["../../../src/core/router/file-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACH,UAAU,EACV,OAAO,EAEP,YAAY,EACZ,SAAS,EACT,UAAU,EAGb,MAAM,UAAU,CAAC;AAsClB;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,kDAAkD;IAClD,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,YAAY,CAAC;IAC5B,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,SAAS,CAAC;IACvB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,UAAU,EAAE,CAAC;IACjC,wBAAwB;IACxB,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,sCAAsC;IACtC,OAAO,CAAC,EAAE,cAAc,GAAG,CAAC,UAAU,cAAc,CAAC,CAAC;CACzD;AAED;;GAEG;AACH,UAAU,WAAW;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;;;GAQG;AACH,qBAAa,UAAU;IACnB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,eAAe,CAAyB;gBAEpC,OAAO,EAAE,iBAAiB;IAWtC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAoBpC;;OAEG;IACG,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B/C;;OAEG;YACW,aAAa;IA4C3B;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAgCpB;;OAEG;IACH,OAAO,CAAC,cAAc;IA+BtB;;OAEG;YACW,aAAa;IAgK3B;;OAEG;YACW,cAAc;IAwB5B;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAKnC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAEvE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,aAAa,CAC/B,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,iBAAiB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAGf"}
@@ -5,20 +5,26 @@
5
5
  * Automatically scans a directory and registers routes based on file/folder structure.
6
6
  * Designed for class-based routing: 1 file = 1 class = 1 route.
7
7
  *
8
- * Smart filename conventions:
8
+ * Smart filename conventions (only if no body schema):
9
9
  * - `index.ts` → GET (default), maps to parent path
10
10
  * - `create.ts` → POST, maps to parent path (not /create)
11
11
  * - `update.ts` → PUT, maps to parent path (not /update)
12
12
  * - `delete.ts` → DELETE, maps to parent path (not /delete)
13
13
  * - `patch.ts` → PATCH, maps to parent path (not /patch)
14
- * - Other files → GET (or specify `method` in class)
14
+ * - Other files → GET (default)
15
+ *
16
+ * Smart body detection (HIGHEST PRIORITY after explicit method):
17
+ * - If schema() returns object with `body` property → POST
18
+ * - Works with inheritance (parent class schema is checked too)
19
+ * - Overrides smart filename detection!
20
+ * - Override by explicitly setting `method` property in class
15
21
  *
16
22
  * @example
17
23
  * ```
18
24
  * routes/
19
25
  * api/
20
26
  * auth/
21
- * register.ts → POST /api/auth/register (method = 'POST' in class)
27
+ * register.ts → POST /api/auth/register (auto-detected via ctx.body!)
22
28
  * login.ts → POST /api/auth/login
23
29
  * users/
24
30
  * index.ts → GET /api/users
@@ -32,11 +38,18 @@
32
38
  * Each file exports a class:
33
39
  * ```typescript
34
40
  * export default class RegisterRoute {
35
- * method = 'POST' // Optional if filename is create/update/delete
41
+ * // No need to specify method = 'POST' if schema has body!
42
+ *
43
+ * schema() {
44
+ * return {
45
+ * body: z.object({ ... }) // ← auto-detects POST!
46
+ * };
47
+ * }
36
48
  *
37
- * schema() { ... }
38
- * meta() { ... }
39
- * async handler(ctx: Context) { ... }
49
+ * async handler(ctx: Context) {
50
+ * const data = ctx.body;
51
+ * ...
52
+ * }
40
53
  * }
41
54
  * ```
42
55
  */
@@ -347,18 +360,33 @@ class FileRouter {
347
360
  }
348
361
  // Determine HTTP method:
349
362
  // 1. If class explicitly defines method → use it
350
- // 2. If filename is smart (create/update/delete/patch/index) → auto-detect
351
- // 3. Otherwisedefault GET
363
+ // 2. If schema has body definition → auto-detect as POST (highest priority for body!)
364
+ // 3. If filename is smart (create/update/delete/patch/index) auto-detect from filename
365
+ // 4. Otherwise → default GET
352
366
  let method;
353
367
  if (route.method) {
354
368
  // Handle both single method and array of methods (use first one for file-based routing)
355
369
  method = Array.isArray(route.method) ? route.method[0] : route.method;
356
370
  }
357
- else if (isSmartFilename(nameWithoutExt)) {
358
- method = getSmartMethod(nameWithoutExt);
359
- }
360
371
  else {
361
- method = DEFAULT_METHOD;
372
+ // Check schema for body definition first (works with inheritance!)
373
+ const schema = route.schema?.();
374
+ if (this.options.debug) {
375
+ console.log(`🔍 Smart detection for ${filePath}:`);
376
+ console.log(` - schema:`, schema);
377
+ console.log(` - has body:`, !!schema?.body);
378
+ }
379
+ if (schema?.body) {
380
+ // Schema has body → POST (overrides smart filename!)
381
+ method = 'POST';
382
+ }
383
+ else if (isSmartFilename(nameWithoutExt)) {
384
+ // Smart filename detection (create→POST, update→PUT, etc.)
385
+ method = getSmartMethod(nameWithoutExt);
386
+ }
387
+ else {
388
+ method = DEFAULT_METHOD;
389
+ }
362
390
  }
363
391
  // Validate method
364
392
  if (!HTTP_METHODS.includes(method)) {