@desaubv/quik 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,804 @@
1
+ # Quik
2
+
3
+ Quik is an Express-based TypeScript library designed to simplify the creation of modern Node.js backends.
4
+
5
+ It provides a clean API for building HTTP servers, routers, middleware, scheduled tasks, and cron-based jobs while reducing repetitive code.
6
+
7
+ ## Features
8
+
9
+ * Express-based HTTP server
10
+ * Fluent routing API
11
+ * Middleware support
12
+ * JSON, URL-encoded, raw, and text body parsing
13
+ * HTTP server configuration
14
+ * Cron task management powered by `node-cron`
15
+ * Cron schedule builder
16
+ * Time zone support
17
+ * Built-in logger
18
+ * TypeScript support
19
+ * ESM and CommonJS package entry points
20
+
21
+ ## Requirements
22
+
23
+ * Node.js 22 or later
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ npm install @desaubv/quik
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```ts
34
+ import { Server, Router } from "@desaubv/quik";
35
+
36
+ const router = Router();
37
+
38
+ router
39
+ .path("/hello")
40
+ .get((req, res) => {
41
+ res.json({
42
+ message: "Hello, world!",
43
+ });
44
+ });
45
+
46
+ const server = Server();
47
+
48
+ server
49
+ .addRoute("/", router)
50
+ .start();
51
+ ```
52
+
53
+ By default, the server listens on:
54
+
55
+ ```text
56
+ http://localhost:8080
57
+ ```
58
+
59
+ ## Cron
60
+
61
+ Cron functionality is available through the `/cron` subpath:
62
+
63
+ ```ts
64
+ import { Cron, Schedule } from "@desaubv/quik/cron";
65
+
66
+ const cron = Cron();
67
+
68
+ cron.add({
69
+ name: "backup",
70
+ schedule: Schedule.every(6).hours(),
71
+ task: async () => {
72
+ console.log("Running backup...");
73
+ },
74
+ });
75
+ ```
76
+
77
+ The cron manager can then be attached to the server:
78
+
79
+ ```ts
80
+ const server = Server();
81
+
82
+ server
83
+ .addCron(cron)
84
+ .start();
85
+ ```
86
+
87
+ ## HTTP Status Codes
88
+
89
+ HTTP status codes are available through the `/http` subpath:
90
+
91
+ ```ts
92
+ import { Status } from "@desaubv/quik/http";
93
+
94
+ router
95
+ .path("/users")
96
+ .get((req, res) => {
97
+ res
98
+ .status(Status.OK)
99
+ .json([]);
100
+ });
101
+ ```
102
+
103
+ ## Package Exports
104
+
105
+ Quik provides three public entry points:
106
+
107
+ ### Main
108
+
109
+ ```ts
110
+ import {
111
+ Server,
112
+ Router,
113
+ QuikRouter,
114
+ logger,
115
+ } from "@desaubv/quik";
116
+ ```
117
+
118
+ ### Cron
119
+
120
+ ```ts
121
+ import {
122
+ Cron,
123
+ QuikCron,
124
+ Schedule,
125
+ } from "@desaubv/quik/cron";
126
+ ```
127
+
128
+ ### HTTP
129
+
130
+ ```ts
131
+ import { Status } from "@desaubv/quik/http";
132
+ ```
133
+
134
+ ## Server Configuration
135
+
136
+ ```ts
137
+ const server = Server();
138
+
139
+ server.setConfig({
140
+ http: {
141
+ port: 3000,
142
+ host: "localhost",
143
+ },
144
+ });
145
+ ```
146
+
147
+ ### HTTP Options
148
+
149
+ ```ts
150
+ server.setConfig({
151
+ http: {
152
+ port: 8080,
153
+ host: "localhost",
154
+ keepAlive: 5000,
155
+ timeout: 10000,
156
+ maxConnections: 100,
157
+ shutdownTimeout: 5000,
158
+ },
159
+ });
160
+ ```
161
+
162
+ ### Express Options
163
+
164
+ ```ts
165
+ server.setConfig({
166
+ express: {
167
+ trustProxy: true,
168
+ },
169
+ });
170
+ ```
171
+
172
+ ## Body Parser
173
+
174
+ Quik supports the Express body parsers:
175
+
176
+ ```ts
177
+ server.setConfig({
178
+ bodyParser: {
179
+ type: "json",
180
+ },
181
+ });
182
+ ```
183
+
184
+ Available types:
185
+
186
+ ```text
187
+ json
188
+ urlencoded
189
+ raw
190
+ text
191
+ ```
192
+
193
+ Each type accepts the corresponding Express options.
194
+
195
+ For example:
196
+
197
+ ```ts
198
+ server.setConfig({
199
+ bodyParser: {
200
+ type: "json",
201
+ options: {
202
+ limit: "1mb",
203
+ },
204
+ },
205
+ });
206
+ ```
207
+
208
+ ## Middleware
209
+
210
+ Global middleware can be registered with `addMiddleware()`:
211
+
212
+ ```ts
213
+ server.addMiddleware(
214
+ middleware1,
215
+ middleware2,
216
+ );
217
+ ```
218
+
219
+ Route-specific middleware can be registered through the router:
220
+
221
+ ```ts
222
+ router
223
+ .path("/users")
224
+ .middleware(authMiddleware)
225
+ .get((req, res) => {
226
+ res.json([]);
227
+ });
228
+ ```
229
+
230
+ ## Router
231
+
232
+ Create a router with:
233
+
234
+ ```ts
235
+ const router = Router();
236
+ ```
237
+
238
+ Register routes using the fluent API:
239
+
240
+ ```ts
241
+ router
242
+ .path("/users")
243
+ .get(handler);
244
+
245
+ router
246
+ .path("/users")
247
+ .post(handler);
248
+
249
+ router
250
+ .path("/users/:id")
251
+ .put(handler);
252
+
253
+ router
254
+ .path("/users/:id")
255
+ .patch(handler);
256
+
257
+ router
258
+ .path("/users/:id")
259
+ .delete(handler);
260
+ ```
261
+
262
+ Supported HTTP methods:
263
+
264
+ ```text
265
+ GET
266
+ POST
267
+ PUT
268
+ PATCH
269
+ DELETE
270
+ ```
271
+
272
+ Mount the router on the server:
273
+
274
+ ```ts
275
+ server.addRoute("/api", router);
276
+ ```
277
+
278
+ A route registered as:
279
+
280
+ ```text
281
+ /users
282
+ ```
283
+
284
+ will therefore be available at:
285
+
286
+ ```text
287
+ /api/users
288
+ ```
289
+
290
+ ## Cron Schedule Builder
291
+
292
+ Instead of writing cron expressions manually, use `Schedule`:
293
+
294
+ ```ts
295
+ import { Schedule } from "@desaubv/quik/cron";
296
+ ```
297
+
298
+ Examples:
299
+
300
+ ```ts
301
+ Schedule.every(10).seconds();
302
+
303
+ Schedule.every(5).minutes();
304
+
305
+ Schedule.every(2).hours();
306
+
307
+ Schedule.every(3).days();
308
+
309
+ Schedule.every(2).months();
310
+
311
+ Schedule.at("08:30");
312
+
313
+ Schedule.weekday("monday", "09:00");
314
+
315
+ Schedule.weekdaysAt("09:00");
316
+
317
+ Schedule.weekendsAt("10:00");
318
+ ```
319
+
320
+ ### Examples
321
+
322
+ ```ts
323
+ Schedule.every(5).minutes();
324
+ // */5 * * * *
325
+
326
+ Schedule.every(6).hours();
327
+ // 0 */6 * * *
328
+
329
+ Schedule.at("08:30");
330
+ // 30 8 * * *
331
+
332
+ Schedule.weekday("monday", "09:00");
333
+ // 0 9 * * 1
334
+
335
+ Schedule.weekdaysAt("09:00");
336
+ // 0 9 * * 1-5
337
+
338
+ Schedule.weekendsAt("10:00");
339
+ // 0 10 * * 0,6
340
+ ```
341
+
342
+ ## Cron Configuration
343
+
344
+ Cron instances can be configured with `setConfig()`:
345
+
346
+ ```ts
347
+ cron.setConfig({
348
+ language: "en",
349
+ timeZone: "America/Los_Angeles",
350
+
351
+ onError: (error) => {
352
+ console.error(error);
353
+ },
354
+ });
355
+ ```
356
+
357
+ A task can also define its own time zone:
358
+
359
+ ```ts
360
+ cron.add({
361
+ name: "daily-report",
362
+ schedule: Schedule.at("12:00"),
363
+ timezone: "America/Los_Angeles",
364
+
365
+ task: async () => {
366
+ console.log("Generating report...");
367
+ },
368
+ });
369
+ ```
370
+
371
+ A task-specific time zone takes precedence over the default cron time zone.
372
+
373
+ ## Complete Example
374
+
375
+ ```ts
376
+ import {
377
+ Server,
378
+ Router,
379
+ } from "@desaubv/quik";
380
+
381
+ import {
382
+ Cron,
383
+ Schedule,
384
+ } from "@desaubv/quik/cron";
385
+
386
+ const router = Router();
387
+
388
+ router
389
+ .path("/health")
390
+ .get((req, res) => {
391
+ res
392
+ .status(200)
393
+ .json({
394
+ status: "ok",
395
+ });
396
+ });
397
+
398
+ router
399
+ .path("/users")
400
+ .get((req, res) => {
401
+ res.json([]);
402
+ });
403
+
404
+ const cron = Cron();
405
+
406
+ cron.add({
407
+ name: "cleanup",
408
+ schedule: Schedule.every(30).minutes(),
409
+
410
+ task: async () => {
411
+ console.log("Running cleanup...");
412
+ },
413
+ });
414
+
415
+ cron.add({
416
+ name: "daily-report",
417
+ schedule: Schedule.at("08:00"),
418
+ timezone: "America/Los_Angeles",
419
+
420
+ task: async () => {
421
+ console.log("Generating daily report...");
422
+ },
423
+ });
424
+
425
+ const server = Server();
426
+
427
+ server
428
+ .setConfig({
429
+ http: {
430
+ port: 8080,
431
+ },
432
+ })
433
+ .addMiddleware((req, res, next) => {
434
+ console.log(`${req.method} ${req.path}`);
435
+ next();
436
+ })
437
+ .addRoute("/api", router)
438
+ .addCron(cron)
439
+ .start();
440
+ ```
441
+
442
+ The resulting API includes:
443
+
444
+ ```text
445
+ GET /api/health
446
+ GET /api/users
447
+ ```
448
+
449
+ while the configured cron tasks run alongside the HTTP server.
450
+
451
+ ## Logger
452
+
453
+ Quik includes a configurable logger with support for multiple log levels, colors, timestamps, file output, formatting, and localization.
454
+
455
+ ```ts
456
+ import { logger } from "@desaubv/quik";
457
+ ```
458
+
459
+ ### Log Levels
460
+
461
+ Quik provides five predefined log levels:
462
+
463
+ ```ts
464
+ logger.log("Application message");
465
+
466
+ logger.info("Server started");
467
+
468
+ logger.warning("Configuration is missing");
469
+
470
+ logger.error("Something went wrong");
471
+
472
+ logger.debug("Debug information");
473
+ ```
474
+
475
+ The logger accepts multiple values:
476
+
477
+ ```ts
478
+ logger.info(
479
+ "User created:",
480
+ {
481
+ id: 123,
482
+ name: "John",
483
+ },
484
+ );
485
+ ```
486
+
487
+ Errors are handled automatically:
488
+
489
+ ```ts
490
+ try {
491
+ throw new Error("Something went wrong");
492
+ } catch (error) {
493
+ logger.error("Request failed:", error);
494
+ }
495
+ ```
496
+
497
+ ### Default Output
498
+
499
+ The default format is:
500
+
501
+ ```text
502
+ DD-MM-YYYY hh:mm:ss [LEVEL] message
503
+ ```
504
+
505
+ For example:
506
+
507
+ ```text
508
+ 11-08-2026 00:34:30 [INFO] Server started
509
+ ```
510
+
511
+ ### Configuration
512
+
513
+ Logger configuration can be changed using `setConfig()`:
514
+
515
+ ```ts
516
+ logger.setConfig({
517
+ color: {
518
+ infoColor: "green",
519
+ errorColor: "red",
520
+ warningColor: "yellow",
521
+ logColor: "blue",
522
+ debugColor: null,
523
+ },
524
+
525
+ format: {
526
+ timestampFormat: "DD-MM-YYYY hh:mm:ss",
527
+ titleCase: "uppercase",
528
+ },
529
+ });
530
+ ```
531
+
532
+ Configuration updates are merged with the existing configuration.
533
+
534
+ ### Getting Configuration
535
+
536
+ Use `config()` to retrieve the current logger configuration:
537
+
538
+ ```ts
539
+ const config = logger.config();
540
+
541
+ console.log(config);
542
+ ```
543
+
544
+ The returned configuration is read-only.
545
+
546
+ ### File Output
547
+
548
+ Each log level can optionally be written to its own file.
549
+
550
+ ```ts
551
+ logger.setConfig({
552
+ save: {
553
+ logFilePath: "logs/app.log",
554
+ infoFilePath: "logs/info.log",
555
+ warningFilePath: "logs/warning.log",
556
+ errorFilePath: "logs/error.log",
557
+ },
558
+ });
559
+ ```
560
+
561
+ Quik automatically creates the required directories.
562
+
563
+ For example:
564
+
565
+ ```text
566
+ logs/
567
+ ├── app.log
568
+ ├── info.log
569
+ ├── warning.log
570
+ └── error.log
571
+ ```
572
+
573
+ Set a path to `null` to disable file output for a level:
574
+
575
+ ```ts
576
+ logger.setConfig({
577
+ save: {
578
+ infoFilePath: null,
579
+ },
580
+ });
581
+ ```
582
+
583
+ ### Colors
584
+
585
+ The following colors are supported:
586
+
587
+ ```text
588
+ black
589
+ red
590
+ green
591
+ yellow
592
+ blue
593
+ magenta
594
+ cyan
595
+ white
596
+ ```
597
+
598
+ Configure colors per log level:
599
+
600
+ ```ts
601
+ logger.setConfig({
602
+ color: {
603
+ logColor: "blue",
604
+ infoColor: "green",
605
+ warningColor: "yellow",
606
+ errorColor: "red",
607
+ debugColor: "cyan",
608
+ },
609
+ });
610
+ ```
611
+
612
+ Set a color to `null` to disable coloring:
613
+
614
+ ```ts
615
+ logger.setConfig({
616
+ color: {
617
+ debugColor: null,
618
+ },
619
+ });
620
+ ```
621
+
622
+ ### Message Formatting
623
+
624
+ The logger supports custom prefixes and suffixes:
625
+
626
+ ```ts
627
+ logger.setConfig({
628
+ format: {
629
+ prefix: "[Quik] ",
630
+ suffix: " ",
631
+ },
632
+ });
633
+ ```
634
+
635
+ This can produce output such as:
636
+
637
+ ```text
638
+ [Quik] 11-08-2026 00:34:30 [INFO] Server started
639
+ ```
640
+
641
+ ### Title Case
642
+
643
+ The log level can be formatted using:
644
+
645
+ ```ts
646
+ logger.setConfig({
647
+ format: {
648
+ titleCase: "uppercase",
649
+ },
650
+ });
651
+ ```
652
+
653
+ Available values:
654
+
655
+ | Value | Output |
656
+ | -------------- | --------------- |
657
+ | `"uppercase"` | `[INFO]` |
658
+ | `"lowercase"` | `[info]` |
659
+ | `"capitalize"` | `[Info]` |
660
+ | `"none"` | `[INFO]` |
661
+ | `null` | No level header |
662
+
663
+ ### Timestamp
664
+
665
+ The timestamp can be customized:
666
+
667
+ ```ts
668
+ logger.setConfig({
669
+ format: {
670
+ timestampFormat: "YYYY-MM-DD hh:mm:ss",
671
+ },
672
+ });
673
+ ```
674
+
675
+ Disable timestamps by setting:
676
+
677
+ ```ts
678
+ logger.setConfig({
679
+ format: {
680
+ timestampFormat: null,
681
+ },
682
+ });
683
+ ```
684
+
685
+ ### Time Zone
686
+
687
+ A specific IANA time zone can be configured:
688
+
689
+ ```ts
690
+ logger.setConfig({
691
+ format: {
692
+ timeZone: "America/Los_Angeles",
693
+ },
694
+ });
695
+ ```
696
+
697
+ Quik validates configured time zones and falls back to the system time zone if an invalid value is provided.
698
+
699
+ ### Custom Log Levels
700
+
701
+ Use `custom()` when the predefined levels are not enough:
702
+
703
+ ```ts
704
+ logger.custom(
705
+ "SUCCESS",
706
+ "green",
707
+ "logs/success.log",
708
+ "Operation completed successfully",
709
+ );
710
+ ```
711
+
712
+ The method accepts:
713
+
714
+ ```ts
715
+ logger.custom(
716
+ level,
717
+ color,
718
+ file,
719
+ ...content,
720
+ );
721
+ ```
722
+
723
+ ### Clearing the Console
724
+
725
+ The console can be cleared using:
726
+
727
+ ```ts
728
+ logger.clear();
729
+ ```
730
+
731
+ ## Logger Configuration Reference
732
+
733
+ | Property | Type | Description |
734
+ | ------------------------ | ------------------------- | ----------------------------- |
735
+ | `save.logFilePath` | `string \| null \| false` | File for `log()` messages |
736
+ | `save.infoFilePath` | `string \| null \| false` | File for `info()` messages |
737
+ | `save.errorFilePath` | `string \| null \| false` | File for `error()` messages |
738
+ | `save.warningFilePath` | `string \| null \| false` | File for `warning()` messages |
739
+ | `color.logColor` | `ColorName \| null` | Color for `log()` |
740
+ | `color.infoColor` | `ColorName \| null` | Color for `info()` |
741
+ | `color.errorColor` | `ColorName \| null` | Color for `error()` |
742
+ | `color.warningColor` | `ColorName \| null` | Color for `warning()` |
743
+ | `color.debugColor` | `ColorName \| null` | Color for `debug()` |
744
+ | `format.timestampFormat` | `string \| null \| false` | Timestamp format |
745
+ | `format.titleCase` | `Cases` | Log-level formatting |
746
+ | `format.prefix` | `string` | Text before the log |
747
+ | `format.suffix` | `string` | Text after the log |
748
+ | `format.timeZone` | `string` | IANA time zone |
749
+
750
+ ## Logger Defaults
751
+
752
+ The default configuration is:
753
+
754
+ ```ts
755
+ {
756
+ language: "en",
757
+
758
+ save: {
759
+ logFilePath: null,
760
+ infoFilePath: null,
761
+ errorFilePath: "logs/error.log",
762
+ warningFilePath: "logs/warning.log",
763
+ },
764
+
765
+ color: {
766
+ logColor: "blue",
767
+ infoColor: "green",
768
+ errorColor: "red",
769
+ warningColor: "yellow",
770
+ debugColor: null,
771
+ },
772
+
773
+ format: {
774
+ timestampFormat: "DD-MM-YYYY hh:mm:ss",
775
+ titleCase: "uppercase",
776
+ },
777
+ }
778
+ ```
779
+
780
+ ## Development
781
+
782
+ Clone the repository and install dependencies:
783
+
784
+ ```bash
785
+ git clone https://github.com/DiegoBarajas/quik.git
786
+ cd quik
787
+ npm install
788
+ ```
789
+
790
+ Build the package:
791
+
792
+ ```bash
793
+ npm run build
794
+ ```
795
+
796
+ Start the TypeScript build in watch mode:
797
+
798
+ ```bash
799
+ npm run dev
800
+ ```
801
+
802
+ ## License
803
+
804
+ Quik is released under the MIT License.