lieko-express 0.0.2 β†’ 0.0.4

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 (3) hide show
  1. package/README.md +478 -78
  2. package/lieko-express.js +492 -127
  3. package/package.json +7 -2
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # πŸ“˜ **Lieko-express β€” A Modern, Minimal, REST API Framework for Node.js**
1
+ # **Lieko-express β€” A Modern, Minimal, REST API Framework for Node.js**
2
2
 
3
3
  A lightweight, fast, and modern Node.js REST API framework built on top of the native `http` module. Zero external dependencies for core functionality.
4
4
 
@@ -10,6 +10,10 @@ A lightweight, fast, and modern Node.js REST API framework built on top of the n
10
10
 
11
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
12
12
  [![Node.js Version](https://img.shields.io/badge/node-%3E%3D14.0.0-brightgreen)](https://nodejs.org)
13
+ [![npm version](https://img.shields.io/npm/v/lieko-express.svg)](https://www.npmjs.com/package/lieko-express)
14
+
15
+ [![GitHub](https://img.shields.io/badge/GitHub-Repository-black?logo=github)](https://github.com/eiwSrvt/lieko-express)
16
+ [![Discord](https://img.shields.io/discord/1399525160050102414?color=5865F2&logo=discord&logoColor=white)](https://discord.gg/EpgPqjvd)
13
17
 
14
18
 
15
19
 
@@ -102,7 +106,7 @@ app.get('/', (req, res) => {
102
106
  app.listen(3000, () => {
103
107
  console.log('Server running on port 3000');
104
108
  });
105
- ---
109
+ ```
106
110
 
107
111
  ## 🎯 Basic Usage
108
112
 
@@ -164,9 +168,13 @@ app.delete('/posts/:id', deletePost);
164
168
  ### Features
165
169
 
166
170
  βœ” Params automatically extracted
171
+
167
172
  βœ” Query auto-typed
173
+
168
174
  βœ” Body parsed and typed
175
+
169
176
  βœ” Wildcards available
177
+
170
178
  βœ” Trailing slashes handled intelligently
171
179
 
172
180
  ---
@@ -201,7 +209,7 @@ app.group('/api', auth, (api) => {
201
209
  * You can nest indefinitely
202
210
  * Works inside routers too
203
211
 
204
- ---
212
+
205
213
 
206
214
  # πŸ“¦ Nested Routers
207
215
 
@@ -210,11 +218,11 @@ Routers are fully nestable:
210
218
  ```js
211
219
  const { Router } = require('lieko-express');
212
220
 
213
- const users = Router();
221
+ const app = Router();
214
222
 
215
- users.get('/', listUsers);
216
- users.post('/', createUser);
217
- users.get('/:id', getUser);
223
+ app.get('/', listUsers);
224
+ app.post('/', createUser);
225
+ app.get('/:id', getUser);
218
226
 
219
227
  app.group('/api', auth, (api) => {
220
228
  api.group('/admin', requireAdmin, (admin) => {
@@ -243,12 +251,13 @@ api.group(
243
251
  }
244
252
  );
245
253
  ```
246
- ### βœ” Router inherits middleware from its parent groups
254
+ βœ” Router inherits middleware from its parent groups
255
+
256
+ βœ” Paths automatically expanded
257
+
258
+ βœ” Perfect for modular architecture
247
259
 
248
- ### βœ” Paths automatically expanded
249
260
 
250
- ### βœ” Perfect for modular architecture
251
- ---
252
261
  # 🧩 API Versioning
253
262
 
254
263
  With groups, versioning becomes trivial:
@@ -263,7 +272,6 @@ app.group('/api/v2', (v2) => {
263
272
  });
264
273
  ```
265
274
 
266
- ---
267
275
 
268
276
  ### Query Parameters
269
277
 
@@ -291,7 +299,6 @@ app.get('/search', (req, res) => {
291
299
  - `"true"` β†’ `true` (boolean)
292
300
  - `"false"` β†’ `false` (boolean)
293
301
 
294
- ---
295
302
 
296
303
  ## πŸ”§ Middlewares
297
304
 
@@ -304,7 +311,7 @@ app.use((req, res, next) => {
304
311
  next();
305
312
  });
306
313
 
307
- // CORS middleware
314
+ // CORS middleware (native, but you can use app.cors())
308
315
  app.use((req, res, next) => {
309
316
  res.set('Access-Control-Allow-Origin', '*');
310
317
  res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
@@ -375,8 +382,381 @@ app.use(async (req, res, next) => {
375
382
  });
376
383
  ```
377
384
 
385
+ # **CORS**
386
+
387
+
388
+ Lieko-Express includes a **fully built-in, high-performance CORS engine**, with:
389
+
390
+ * Global CORS (`app.cors()`)
391
+ * Route-level CORS (`app.get("/test", { cors: {...} }, handler)`β€”coming soon if you want it)
392
+ * Wildcard origins (`https://*.example.com`)
393
+ * Multiple allowed origins
394
+ * Strict mode (reject unknown origins)
395
+ * Credential support
396
+ * Private Network Access (Chrome PNA)
397
+ * Debug logging
398
+ * Full OPTIONS preflight support
399
+
400
+ ---
401
+
402
+ # **Enable CORS Globally**
403
+
404
+ ```js
405
+ app.cors();
406
+ ```
407
+
408
+ This enables default permissive CORS:
409
+
410
+ | Option | Default |
411
+ | --------------------- | ----------------------------- |
412
+ | `origin` | `"*"` |
413
+ | `methods` | all standard methods |
414
+ | `headers` | `Content-Type, Authorization` |
415
+ | `credentials` | false |
416
+ | `maxAge` | 86400 (24h) |
417
+ | `exposedHeaders` | none |
418
+ | `strictOrigin` | false |
419
+ | `allowPrivateNetwork` | false |
420
+
421
+ ---
422
+
423
+ # **Custom Global CORS Options**
424
+
425
+ ```js
426
+ app.cors({
427
+ origin: ["https://example.com", "https://api.example.com"],
428
+ methods: ["GET", "POST"],
429
+ headers: ["Content-Type", "Authorization", "X-Custom"],
430
+ credentials: true,
431
+ maxAge: 3600,
432
+ exposedHeaders: ["X-RateLimit-Remaining"],
433
+ });
434
+ ```
435
+
436
+ ---
437
+
438
+ # **Allow All Origins (Standard Mode)**
439
+
440
+ ```js
441
+ app.cors({
442
+ origin: "*"
443
+ });
444
+ ```
445
+
446
+ ⚠️ If you also set `credentials: true`, browsers will **reject** `*`.
447
+ Lieko will still output `*` because that's the correct spec behavior.
448
+
449
+ ---
450
+
451
+ # **Strict Origin Mode**
452
+
453
+ Strict mode ensures the incoming `Origin` header **must match exactly** one of your allowed origins.
454
+
455
+ ```js
456
+ app.cors({
457
+ origin: ["https://myapp.com"],
458
+ strictOrigin: true
459
+ });
460
+ ```
461
+
462
+ If the request comes from an unauthorized origin:
463
+
464
+ ```json
465
+ HTTP 403
466
+ {
467
+ "success": false,
468
+ "error": "Origin Forbidden",
469
+ "message": "Origin \"https://evil.com\" is not allowed"
470
+ }
471
+ ```
472
+
473
+ ---
474
+
475
+ # **Wildcard Origins**
476
+
477
+ Lieko-Express supports Express-style wildcard patterns:
478
+
479
+ ### Allow any subdomain
480
+
481
+ ```js
482
+ app.cors({
483
+ origin: "https://*.example.com"
484
+ });
485
+ ```
486
+
487
+ Matches:
488
+
489
+ * `https://api.example.com`
490
+ * `https://dashboard.example.com`
491
+
492
+ Does not match:
493
+
494
+ * `http://example.com`
495
+ * `https://example.net`
496
+
497
+ ---
498
+
499
+ # **Allow Private Network Access (Chrome PNA)**
500
+
501
+ ```js
502
+ app.cors({
503
+ allowPrivateNetwork: true
504
+ });
505
+ ```
506
+
507
+ When Chrome sends:
508
+
509
+ ```
510
+ Access-Control-Request-Private-Network: true
511
+ ```
512
+
513
+ Lieko automatically responds:
514
+
515
+ ```
516
+ Access-Control-Allow-Private-Network: true
517
+ ```
518
+
519
+ # Route-Level CORS
520
+
521
+ Lieko-Express allows each route to override or extend the global CORS settings using a `cors` property in the route options.
522
+ This gives you fine-grained control over cross-origin behavior on a per-endpoint basis.
523
+
524
+ Route-level CORS:
525
+
526
+ * Overrides global CORS
527
+ * Supports wildcards (`https://*.example.com`)
528
+ * Supports strict mode
529
+ * Sends its own preflight response
530
+ * Automatically merges with the global configuration
531
+ * Does **not** affect other routes
532
+
533
+ ---
534
+
535
+ ## Basic Example
536
+
537
+ ```js
538
+ app.get("/public", {
539
+ cors: { origin: "*" }
540
+ }, (req, res) => {
541
+ res.ok("Public endpoint with open CORS");
542
+ });
543
+ ```
544
+
545
+ This route allows requests from **any origin**, even if global CORS is configured differently.
546
+
547
+ ---
548
+
549
+ ## πŸ”’ Restrict a Sensitive Route
550
+
551
+ ```js
552
+ app.post("/admin/login", {
553
+ cors: {
554
+ origin: "https://dashboard.myapp.com",
555
+ credentials: true,
556
+ strictOrigin: true
557
+ }
558
+ }, (req, res) => {
559
+ res.ok("Login OK");
560
+ });
561
+ ```
562
+
563
+ ### Result:
564
+
565
+ * Only `https://dashboard.myapp.com` is allowed
566
+ * Cookies / sessions allowed
567
+ * Any other origin receives:
568
+
569
+ ```json
570
+ {
571
+ "success": false,
572
+ "error": "Origin Forbidden",
573
+ "message": "Origin \"https://evil.com\" is not allowed"
574
+ }
575
+ ```
576
+
577
+ Status: **403 Forbidden**
578
+
579
+ ---
580
+
581
+ ## ✨ Wildcard Origins on a Route
582
+
583
+ ```js
584
+ app.get("/api/data", {
585
+ cors: {
586
+ origin: "https://*.example.com"
587
+ }
588
+ }, (req, res) => {
589
+ res.ok({ data: 123 });
590
+ });
591
+ ```
592
+
593
+ Matches:
594
+
595
+ * `https://api.example.com`
596
+ * `https://dashboard.example.com`
597
+
598
+ ---
599
+
600
+ ## βš™οΈ Full Route-Level CORS Example
601
+
602
+ ```js
603
+ app.get("/user/profile", {
604
+ cors: {
605
+ origin: [
606
+ "https://app.example.com",
607
+ "https://*.trusted.dev"
608
+ ],
609
+ methods: ["GET", "PATCH"],
610
+ headers: ["Content-Type", "Authorization"],
611
+ exposedHeaders: ["X-User-Id"],
612
+ credentials: true,
613
+ maxAge: 600,
614
+ strictOrigin: true,
615
+ allowPrivateNetwork: true,
616
+ debug: true
617
+ }
618
+ }, (req, res) => {
619
+ res.ok({ profile: "OK" });
620
+ });
621
+ ```
622
+
623
+ ---
624
+
625
+ ## πŸ“Œ How Route-Level CORS Works Internally
626
+
627
+ When a request hits a route:
628
+
629
+ 1. If global CORS is enabled β†’ apply it.
630
+ 2. If the route defines `cors` β†’ merge with global config.
631
+ 3. Route CORS **overrides** global CORS.
632
+ 4. If request is `OPTIONS` (preflight) β†’ return automatic CORS response.
633
+ 5. Otherwise β†’ run route handler.
634
+
635
+ This ensures predictable behavior.
636
+
378
637
  ---
379
638
 
639
+ ## πŸ“˜ Route-Level CORS Options
640
+
641
+ | Option | Type | Description | |
642
+ | --------------------- | ---------- | ---------------------------------------- | ---------------------------------------- |
643
+ | `origin` | `string | string[]` | Allowed origins (`*`, domain, wildcard). |
644
+ | `methods` | `string[]` | Allowed HTTP methods. | |
645
+ | `headers` | `string[]` | Allowed request headers. | |
646
+ | `exposedHeaders` | `string[]` | Response headers exposed to the browser. | |
647
+ | `credentials` | `boolean` | Allow cookies/sessions. | |
648
+ | `maxAge` | `number` | Preflight cache lifetime (seconds). | |
649
+ | `strictOrigin` | `boolean` | Reject non-matching origins with 403. | |
650
+ | `allowPrivateNetwork` | `boolean` | Enables Chrome Private Network Access. | |
651
+ | `debug` | `boolean` | Logs detailed CORS decisions. | |
652
+
653
+ ---
654
+
655
+ ## 🧩 Interaction with Global CORS
656
+
657
+ | Feature | Global | Route |
658
+ | ------------------ | ------ | ------------- |
659
+ | Origin | βœ” | βœ” (overrides) |
660
+ | Wildcards | βœ” | βœ” |
661
+ | Credentials | βœ” | βœ” |
662
+ | Strict Origin | βœ” | βœ” |
663
+ | Private Network | βœ” | βœ” |
664
+ | Debug Logging | βœ” | βœ” |
665
+ | Preflight Handling | βœ” | βœ” |
666
+ | Overrides Global | ❌ | βœ” |
667
+
668
+
669
+
670
+
671
+ # **Enable CORS Debug Logging**
672
+
673
+ ```js
674
+ app.cors({
675
+ debug: true
676
+ });
677
+ ```
678
+
679
+ Console output example:
680
+
681
+ ```
682
+ [CORS DEBUG]
683
+ Request: GET /users
684
+ Origin: https://app.example.com
685
+ Applied CORS Policy:
686
+ - Access-Control-Allow-Origin: https://app.example.com
687
+ - Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
688
+ - Access-Control-Allow-Headers: Content-Type, Authorization
689
+ - Max-Age: 86400
690
+ Simple request handled normally
691
+ ```
692
+
693
+ ---
694
+
695
+ # **Preflight Handling (OPTIONS)**
696
+
697
+ Lieko-Express automatically handles it:
698
+
699
+ ### Request:
700
+
701
+ ```
702
+ OPTIONS /login
703
+ Access-Control-Request-Method: POST
704
+ Access-Control-Request-Headers: Content-Type
705
+ ```
706
+
707
+ ### Lieko Response:
708
+
709
+ ```
710
+ 204 No Content
711
+ Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
712
+ Access-Control-Allow-Headers: Content-Type, Authorization
713
+ Access-Control-Max-Age: 86400
714
+ ```
715
+
716
+ ---
717
+
718
+ # **Credentials Support**
719
+
720
+ ```js
721
+ app.cors({
722
+ credentials: true,
723
+ origin: "https://myapp.com"
724
+ });
725
+ ```
726
+
727
+ Response contains:
728
+
729
+ ```
730
+ Access-Control-Allow-Credentials: true
731
+ ```
732
+
733
+ ---
734
+
735
+
736
+ # **Disable CORS**
737
+
738
+ Just don’t call `app.cors()`.
739
+ CORS stays fully disabled.
740
+
741
+ ---
742
+
743
+ # **Default CORS Configuration**
744
+
745
+ ```js
746
+ this.corsOptions = {
747
+ enabled: false,
748
+ origin: "*",
749
+ strictOrigin: false,
750
+ allowPrivateNetwork: false,
751
+ methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
752
+ headers: ["Content-Type", "Authorization"],
753
+ credentials: false,
754
+ maxAge: 86400,
755
+ exposedHeaders: [],
756
+ debug: false
757
+ };
758
+ ```
759
+
380
760
  # πŸ” Request Object
381
761
 
382
762
  Lieko’s `req` object provides:
@@ -414,8 +794,6 @@ Lieko safely handles:
414
794
  * IPv4-mapped IPv6
415
795
  * Multiple proxies
416
796
 
417
- ---
418
-
419
797
 
420
798
  # 🎯 Response Object (`res`)
421
799
 
@@ -434,7 +812,6 @@ Lieko enhances Node's native response object with convenient helper methods.
434
812
  | `res.json(obj)` | Sends JSON with correct headers. |
435
813
  | `res.end(body)` | Ends the response manually. |
436
814
 
437
- ---
438
815
 
439
816
  # βœ… **High-Level Helpers**
440
817
 
@@ -447,7 +824,6 @@ Lieko enhances Node's native response object with convenient helper methods.
447
824
  | `res.noContent()` | Sends status `204` with no body. |
448
825
  | `res.paginated(payload)` | Standard API pagination output. |
449
826
 
450
- ---
451
827
 
452
828
  # ❌ **Error Helpers**
453
829
 
@@ -466,8 +842,6 @@ Lieko enhances Node's native response object with convenient helper methods.
466
842
  > { "success": false, "error": { "code": "...", "message": "..." } }
467
843
  > ```
468
844
 
469
- ---
470
-
471
845
  # 🧠 **Content-Type Helpers**
472
846
 
473
847
  ### **HTML**
@@ -482,7 +856,6 @@ Lieko enhances Node's native response object with convenient helper methods.
482
856
  | -------------------------- | ------------------------------------- |
483
857
  | `res.redirect(url, code?)` | Redirects the client (default `302`). |
484
858
 
485
- ---
486
859
 
487
860
  # πŸ“¦ **Low-Level Output Controls**
488
861
 
@@ -516,16 +889,82 @@ res.paginated(items, page, limit, total);
516
889
  * String errors also supported (`res.error("Invalid user")`)
517
890
 
518
891
  ---
892
+ # Body Parsing (JSON, URL-encoded, Multipart) β€” 100% Native, Zero Dependencies
893
+
894
+ Lieko Express ships with a **fast, secure, and fully native body parser** β€” no external packages, not even `body-parser`.
519
895
 
520
- # πŸ“¦ Body Parsing
896
+ As soon as you create your app, body parsing is **automatically enabled**:
521
897
 
522
- Lieko supports:
898
+ ```js
899
+ const app = Lieko(); // Ready to handle JSON, form-data, files, etc.
900
+ ```
901
+
902
+ ### Default Limits
903
+
904
+ | Content-Type | Default Limit | Bytes |
905
+ |---------------------------------------|---------------|-------------------|
906
+ | `application/json` | **1mb** | ~1,048,576 bytes |
907
+ | `application/x-www-form-urlencoded` | **1mb** | ~1,048,576 bytes |
908
+ | `multipart/form-data` (file uploads) | **10mb** | ~10,485,760 bytes |
909
+
910
+ That’s already **10Γ— more generous** than Express’s default 100kb!
911
+
912
+ ### Change Limits β€” Three Super-Simple Ways
913
+
914
+ #### 1. Per content-type (most common)
915
+
916
+ ```js
917
+ app.json({ limit: '100mb' }); // JSON payloads only
918
+ app.urlencoded({ limit: '50mb' }); // Classic HTML forms
919
+ ```
523
920
 
524
- ### βœ” JSON
921
+ #### 2. Global limit (JSON + urlencoded at once)
525
922
 
526
- ### βœ” URL-encoded
923
+ ```js
924
+ app.bodyParser({ limit: '50mb' });
925
+ // Applies 50mb to both JSON and urlencoded bodies
926
+ ```
527
927
 
528
- ### βœ” Multipart form-data (files)
928
+ #### 3. File upload limit (multipart/form-data)
929
+
930
+ ```js
931
+ app.multipart({ limit: '500mb' }); // For very large file uploads
932
+ ```
933
+
934
+ You can freely combine them:
935
+
936
+ ```js
937
+ const app = Lieko();
938
+
939
+ app.json({ limit: '10mb' }); // Small, fast JSON APIs
940
+ app.urlencoded({ limit: '5mb' });
941
+ app.multipart({ limit: '1gb' }); // Allow huge file uploads
942
+ ```
943
+
944
+ ### Real-world Example
945
+
946
+ ```js
947
+ const Lieko = require('lieko-express');
948
+ const app = Lieko();
949
+
950
+ // Accept reasonably large JSON payloads
951
+ app.json({ limit: '25mb' });
952
+
953
+ // Accept classic forms
954
+ app.urlencoded({ limit: '10mb' });
955
+
956
+ // Allow big file uploads (photos, videos, etc.)
957
+ app.multipart({ limit: '500mb' });
958
+
959
+ app.post('/upload', (req, res) => {
960
+ console.log('JSON body size :', Buffer.byteLength(JSON.stringify(req.body)), 'bytes');
961
+ console.log('Uploaded files :', Object.keys(req.files || {}));
962
+
963
+ res.ok({ received: true, files: req.files });
964
+ });
965
+
966
+ app.listen(3000);
967
+ ```
529
968
 
530
969
  Uploads end up in:
531
970
 
@@ -549,6 +988,12 @@ Query & body fields are **auto converted**:
549
988
  "null" β†’ null
550
989
  ```
551
990
 
991
+
992
+ **No `app.use(express.json())`, no `app.use(express.urlencoded())`, no extra dependencies** β€” everything works out of the box, blazing fast, and fully configurable in one line.
993
+
994
+ That’s the Lieko philosophy: **less boilerplate, more power**.
995
+
996
+
552
997
  ### Response Methods
553
998
 
554
999
  ```javascript
@@ -621,8 +1066,6 @@ app.post('/upload', (req, res) => {
621
1066
  });
622
1067
  ```
623
1068
 
624
- ---
625
-
626
1069
  ## βœ… Validation
627
1070
 
628
1071
  ### Built-in Validators
@@ -740,8 +1183,6 @@ const userSchema = schema({
740
1183
  });
741
1184
  ```
742
1185
 
743
- ---
744
-
745
1186
  ## **Boolean Example**
746
1187
 
747
1188
  ```js
@@ -758,8 +1199,6 @@ Accepted:
758
1199
  true, false, "true", "false", 1, 0, "1", "0"
759
1200
  ```
760
1201
 
761
- ---
762
-
763
1202
  ## **Email Example**
764
1203
 
765
1204
  ```js
@@ -771,8 +1210,6 @@ const schema = schema({
771
1210
  });
772
1211
  ```
773
1212
 
774
- ---
775
-
776
1213
  ## **Username with rules**
777
1214
 
778
1215
  ```js
@@ -787,8 +1224,6 @@ const usernameSchema = schema({
787
1224
  });
788
1225
  ```
789
1226
 
790
- ---
791
-
792
1227
  ## **Password strength**
793
1228
 
794
1229
  ```js
@@ -806,8 +1241,6 @@ const passwordSchema = schema({
806
1241
  });
807
1242
  ```
808
1243
 
809
- ---
810
-
811
1244
  ## **Multiple-choice fields**
812
1245
 
813
1246
  ```js
@@ -818,7 +1251,6 @@ const roleSchema = schema({
818
1251
  });
819
1252
  ```
820
1253
 
821
- ---
822
1254
 
823
1255
  ## **Blacklist Example**
824
1256
 
@@ -830,8 +1262,6 @@ const schema = schema({
830
1262
  });
831
1263
  ```
832
1264
 
833
- ---
834
-
835
1265
  ## **Starts / Ends With**
836
1266
 
837
1267
  ```js
@@ -842,11 +1272,9 @@ const schema = schema({
842
1272
  });
843
1273
  ```
844
1274
 
845
- ---
846
-
847
1275
  # **Advanced Validation Examples**
848
1276
 
849
- ---
1277
+
850
1278
 
851
1279
  ## **Cross-field validation (matching passwords)**
852
1280
 
@@ -863,7 +1291,6 @@ const registerSchema = schema({
863
1291
  });
864
1292
  ```
865
1293
 
866
- ---
867
1294
 
868
1295
  ## Conditional Validation (depends on another field)
869
1296
 
@@ -880,7 +1307,6 @@ const orderSchema = schema({
880
1307
  });
881
1308
  ```
882
1309
 
883
- ---
884
1310
 
885
1311
  ## Dynamic rules EX: `age` required only if user is not admin
886
1312
 
@@ -896,7 +1322,6 @@ const schema = schema({
896
1322
  });
897
1323
  ```
898
1324
 
899
- ---
900
1325
 
901
1326
  ## **Date validation**
902
1327
 
@@ -912,7 +1337,6 @@ const eventSchema = schema({
912
1337
  });
913
1338
  ```
914
1339
 
915
- ---
916
1340
 
917
1341
  # **Combining many validators**
918
1342
 
@@ -928,7 +1352,6 @@ const schema = schema({
928
1352
  });
929
1353
  ```
930
1354
 
931
- ---
932
1355
 
933
1356
  # **Optional field + rules if provided**
934
1357
 
@@ -945,7 +1368,6 @@ const schema = schema({
945
1368
  If nickname is empty β†’ no validation.
946
1369
  If present β†’ must follow rules.
947
1370
 
948
- ---
949
1371
 
950
1372
  # **Example of validation error response**
951
1373
 
@@ -1014,7 +1436,6 @@ const orderSchema = schema({
1014
1436
  });
1015
1437
  ```
1016
1438
 
1017
- ---
1018
1439
 
1019
1440
  ## πŸ—‚οΈ Routers
1020
1441
 
@@ -1138,8 +1559,6 @@ app.use('/api/posts', postsRouter);
1138
1559
  app.listen(3000);
1139
1560
  ```
1140
1561
 
1141
- ---
1142
-
1143
1562
  ## ⚠️ Error Handling
1144
1563
 
1145
1564
  ### Custom 404 Handler
@@ -1208,7 +1627,6 @@ res.error({ code: 'CUSTOM_ERROR', status: 418 });
1208
1627
  }
1209
1628
  ```
1210
1629
 
1211
- ---
1212
1630
 
1213
1631
  ## πŸ”₯ Advanced Examples
1214
1632
 
@@ -1551,7 +1969,6 @@ const requestLogger = (req, res, next) => {
1551
1969
  app.use(requestLogger);
1552
1970
  ```
1553
1971
 
1554
- ---
1555
1972
 
1556
1973
  ## 🎯 Complete Application Example
1557
1974
 
@@ -1564,7 +1981,6 @@ See the [examples](./examples) directory for a full-featured application with:
1564
1981
  - Middleware examples
1565
1982
  - Comprehensive test suite
1566
1983
 
1567
- ---
1568
1984
 
1569
1985
  # πŸ“Š Performance Tips (Suite)
1570
1986
 
@@ -1575,7 +1991,6 @@ See the [examples](./examples) directory for a full-featured application with:
1575
1991
  5. **Use reverse proxy headers correctly** (`trust proxy`) when hosting behind Nginx
1576
1992
  6. **Disable console logs in production** or use a real logger with adjustable log levels
1577
1993
 
1578
- ---
1579
1994
 
1580
1995
  ## Debug & Introspection Tools
1581
1996
 
@@ -1610,6 +2025,7 @@ DEBUG REQUEST
1610
2025
  β†’ Params: {"id":"42"}
1611
2026
  β†’ Query: {"page":2,"active":true}
1612
2027
  β†’ Body: {}
2028
+ β†’ Body Size: 0 bytes
1613
2029
  β†’ Files:
1614
2030
  ---------------------------------------------
1615
2031
  ```
@@ -1682,9 +2098,9 @@ You can configure:
1682
2098
  ```js
1683
2099
  app.set('trust proxy', value);
1684
2100
  app.set('debug', boolean);
1685
- app.set('x-powered-by', false);
1686
- app.set('strictTrailingSlash', false);
1687
- app.set('allowTrailingSlash', true);
2101
+ app.set('x-powered-by', boolean);
2102
+ app.set('strictTrailingSlash', boolean);
2103
+ app.set('allowTrailingSlash', boolean);
1688
2104
  ```
1689
2105
 
1690
2106
  # 🌐 Trust Proxy & IP Parsing
@@ -1720,7 +2136,6 @@ Lieko correctly handles:
1720
2136
  * IPv4-mapped IPv6 (`::ffff:127.0.0.1`)
1721
2137
  * Multi-proxy headers
1722
2138
 
1723
- ---
1724
2139
 
1725
2140
  ## 🧩 Internals & Architecture
1726
2141
 
@@ -1754,8 +2169,6 @@ This allows:
1754
2169
  * Fast matching
1755
2170
 
1756
2171
 
1757
- ---
1758
-
1759
2172
  ## 🧱 Extending Lieko Express
1760
2173
 
1761
2174
  Because the framework is intentionally small, you can easily extend it.
@@ -1786,8 +2199,6 @@ const timing = (req, res, next) => {
1786
2199
  app.use(timing);
1787
2200
  ```
1788
2201
 
1789
- ---
1790
-
1791
2202
  # πŸ”Œ Plugins
1792
2203
 
1793
2204
  A plugin is simply a function receiving `app`:
@@ -1799,16 +2210,6 @@ function myPlugin(app) {
1799
2210
 
1800
2211
  myPlugin(app);
1801
2212
  ```
1802
- ---
1803
-
1804
- ## πŸš€ Deploying Lieko Express
1805
-
1806
- ### Node.js (PM2)
1807
-
1808
- ```bash
1809
- pm2 start app.js
1810
- ```
1811
-
1812
2213
  ## πŸ“¦ API Reference
1813
2214
 
1814
2215
  ### `Lieko()`
@@ -1862,7 +2263,7 @@ app.notFound((req, res) => {
1862
2263
 
1863
2264
  Register a custom 500 handler.
1864
2265
 
1865
- ---
2266
+
1866
2267
 
1867
2268
  ## πŸ” Known Limitations
1868
2269
 
@@ -1876,7 +2277,6 @@ Because Lieko Express is minimalistic:
1876
2277
 
1877
2278
  Future versions may address some of these.
1878
2279
 
1879
- ---
1880
2280
 
1881
2281
  ## 🀝 Contributing
1882
2282
 
@@ -1887,7 +2287,7 @@ Contributions are welcome!
1887
2287
  3. Commit your changes
1888
2288
  4. Open a pull request
1889
2289
 
1890
- ---
2290
+
1891
2291
 
1892
2292
  ## πŸ“„ License
1893
2293