wynkjs 1.0.6 → 1.0.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.
package/README.md CHANGED
@@ -19,7 +19,7 @@ _10x faster than Express/NestJs, built for modern TypeScript development for Bun
19
19
 
20
20
  ## About
21
21
 
22
- WynkJS is a modern, TypeScript-first web framework alternative to NestJs that brings Elegant Decorator-Based Architecture to the blazing-fast Elysia runtime built for **Bun**. It features familiar concepts—**Controllers, Dependency Injection, Guards, Pipes, Interceptors, and Exception Filters**—designed for building high‑performance REST APIs and backends on **Bun**. WynkJS embraces ESM, ships first-class types, and keeps things simple so you can move fast without the bloat.
22
+ WynkJS is a modern, TypeScript-first web framework alternative to NestJs that brings Elegant Decorator-Based Architecture to the blazing-fast Elysia runtime built for **Bun**. It features familiar concepts—**Controllers, Dependency Injection, Guards, Pipes, Interceptors, Plugins, and Exception Filters**—designed for building high‑performance REST APIs and backends on **Bun**. WynkJS embraces ESM, ships first-class types, and keeps things simple so you can move fast without the bloat.
23
23
 
24
24
  Keywords: Bun framework, Fast web server, TypeScript decorators, dependency injection (DI), guards, pipes, interceptors, exception filters, fast web framework, REST API, backend, modern TypeScript.
25
25
 
@@ -34,7 +34,8 @@ WynkJS combines the **speed of Elysia** with an **Elegant Decorator-Based Archit
34
34
  - 💉 **Dependency Injection** - Built-in DI (no need to import reflect-metadata!)
35
35
  - 🔒 **TypeScript First** - TypeScript is mandatory, not optional. Full type safety and IntelliSense support
36
36
  - 🎯 **Simple & Clean** - Easy to learn, powerful to use
37
- - 🔌 **Middleware Support** - Guards, interceptors, pipes, filters
37
+ - 🔌 **Plugin System** - Compression, custom middleware via app.use()
38
+ - 🛡️ **Middleware Support** - Guards, interceptors, pipes, filters
38
39
  - ⚡ **Bun Only** - Built exclusively for Bun runtime (not Node.js)
39
40
  - 📦 **Single Import** - Everything from `wynkjs` (Injectable, Controller, Get, etc.)
40
41
 
@@ -510,7 +511,145 @@ const corsOptions: CorsOptions = {
510
511
 
511
512
  See [CORS.md](./CORS.md) for complete documentation.
512
513
 
513
- ### 🔒 Authentication with Guards
514
+ ### Plugins & Middleware
515
+
516
+ WynkJS provides a flexible plugin system to extend your application. Add compression, rate limiting, caching, and more using the `app.use()` API.
517
+
518
+ #### Compression Plugin (Built-in)
519
+
520
+ Automatically compress HTTP responses with Brotli, Gzip, or Deflate:
521
+
522
+ ```typescript
523
+ import { WynkFactory, compression } from "wynkjs";
524
+
525
+ const app = WynkFactory.create({
526
+ controllers: [UserController],
527
+ });
528
+
529
+ // Add compression middleware
530
+ app.use(
531
+ compression({
532
+ threshold: 1024, // Compress responses > 1KB
533
+ encodings: ["br", "gzip", "deflate"], // Prefer brotli, then gzip
534
+ })
535
+ );
536
+
537
+ await app.listen(3000);
538
+ ```
539
+
540
+ **Real-world performance:**
541
+
542
+ - Brotli: 58KB → 2.9KB (95% reduction) ⚡
543
+ - Gzip: 58KB → 7.7KB (87% reduction)
544
+
545
+ **Features:**
546
+
547
+ - Smart compression (only compresses if it reduces size)
548
+ - Auto-detects client support
549
+ - Configurable threshold and compression levels
550
+ - No external dependencies
551
+
552
+ See [Plugins README](./core/plugins/README.md) for full documentation and options.
553
+
554
+ #### Custom Plugins
555
+
556
+ Create your own plugins:
557
+
558
+ ```typescript
559
+ export function myPlugin(options = {}) {
560
+ return (app: Elysia) => {
561
+ return app
562
+ .onBeforeHandle(async (context) => {
563
+ // Before request
564
+ })
565
+ .onAfterHandle(async (context) => {
566
+ // After request
567
+ return context.response;
568
+ });
569
+ };
570
+ }
571
+
572
+ // Use it
573
+ app.use(myPlugin({ option: "value" }));
574
+ ```
575
+
576
+ #### Swagger / OpenAPI Documentation
577
+
578
+ **✨ New Feature**: WynkJS can use Elysia's Swagger plugin for automatic API documentation!
579
+
580
+ Since WynkJS is built on top of Elysia, you can use the official `@elysiajs/swagger` plugin to generate interactive API documentation from your WynkJS decorators.
581
+
582
+ ```bash
583
+ bun add @elysiajs/swagger
584
+ ```
585
+
586
+ ```typescript
587
+ import { WynkFactory } from "wynkjs";
588
+ import { swagger } from "@elysiajs/swagger";
589
+
590
+ const app = WynkFactory.create({
591
+ controllers: [UserController, ProductController],
592
+ });
593
+
594
+ const server = await app.build();
595
+
596
+ // Add Swagger documentation
597
+ server.use(
598
+ swagger({
599
+ documentation: {
600
+ info: {
601
+ title: "My API Documentation",
602
+ version: "1.0.0",
603
+ description: "Auto-generated from WynkJS decorators",
604
+ },
605
+ tags: [
606
+ { name: "users", description: "User management" },
607
+ { name: "products", description: "Product catalog" },
608
+ ],
609
+ },
610
+ path: "/docs",
611
+ })
612
+ );
613
+
614
+ server.listen(3000);
615
+ // 📚 Visit: http://localhost:3000/docs
616
+ ```
617
+
618
+ **What gets auto-documented:**
619
+
620
+ ✅ All HTTP routes (@Get, @Post, etc.)
621
+ ✅ Query parameters (from DTOs)
622
+ ✅ Request body schemas (from DTOs)
623
+ ✅ Path parameters (from DTOs)
624
+ ✅ Validation rules (min, max, format)
625
+ ✅ JWT Authentication support
626
+
627
+ **With JWT Authentication:**
628
+
629
+ ```typescript
630
+ server.use(
631
+ swagger({
632
+ documentation: {
633
+ info: { title: "Secure API", version: "1.0.0" },
634
+ components: {
635
+ securitySchemes: {
636
+ bearerAuth: {
637
+ type: "http",
638
+ scheme: "bearer",
639
+ bearerFormat: "JWT",
640
+ },
641
+ },
642
+ },
643
+ security: [{ bearerAuth: [] }],
644
+ },
645
+ path: "/docs",
646
+ })
647
+ );
648
+ ```
649
+
650
+ 📚 See [Swagger Integration Guide](./docs/SWAGGER_INTEGRATION.md) for complete examples and best practices.
651
+
652
+ ### �🔒 Authentication with Guards
514
653
 
515
654
  ```typescript
516
655
  import { Controller, Get, Use } from "wynkjs";
package/dist/factory.d.ts CHANGED
@@ -72,6 +72,39 @@ export declare class WynkFramework {
72
72
  * Providers with onModuleDestroy() method will be called
73
73
  */
74
74
  private destroyProviders;
75
+ /**
76
+ * Use an Elysia plugin or middleware (fully compatible with Elysia.js ecosystem)
77
+ *
78
+ * This method directly proxies to Elysia's use() method, making all Elysia plugins
79
+ * and middleware work seamlessly with WynkJS.
80
+ *
81
+ * @param plugin - Any Elysia plugin or instance
82
+ * @returns this for method chaining
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * import { WynkFactory } from "wynkjs";
87
+ * import { compression } from "wynkjs";
88
+ * import { cors } from "@elysiajs/cors";
89
+ * import { swagger } from "@elysiajs/swagger";
90
+ * import { jwt } from "@elysiajs/jwt";
91
+ *
92
+ * const app = WynkFactory.create({
93
+ * controllers: [UserController],
94
+ * });
95
+ *
96
+ * // Use WynkJS built-in plugins
97
+ * app.use(compression({ threshold: 1024 }));
98
+ *
99
+ * // Use any Elysia plugin from npm
100
+ * app.use(cors());
101
+ * app.use(swagger());
102
+ * app.use(jwt({ name: 'jwt', secret: 'secret' }));
103
+ *
104
+ * await app.listen(3000);
105
+ * ```
106
+ */
107
+ use(...plugins: any[]): this;
75
108
  /**
76
109
  * Start listening on a port
77
110
  */
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../core/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,kBAAkB,CAAC;AAc1B,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEnE,OAAO,EAAE,WAAW,EAAa,MAAM,QAAQ,CAAC;AAOhD;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wBAAwB,CAAC,EAAE,cAAc,CAAC;IAC1C,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;CACnB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,mBAAmB,CAAC,CAAiB;IAC7C,OAAO,CAAC,0BAA0B,CAAS;IAC3C,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,kBAAuB;IA2L5C;;OAEG;IACH,MAAM,CAAC,MAAM,CACX,OAAO,GAAE,kBAAkB,GAAG;QAC5B,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC;QACpB,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;KACd,GACL,aAAa;IAahB;;;OAGG;IACH,iBAAiB,CAAC,GAAG,SAAS,EAAE,GAAG,EAAE,GAAG,IAAI;IAK5C;;OAEG;IACH,mBAAmB,CAAC,GAAG,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI;IAKhD;;OAEG;IACH,eAAe,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI;IAKvC;;OAEG;IACH,qBAAqB,CAAC,GAAG,YAAY,EAAE,GAAG,EAAE,GAAG,IAAI;IAKnD;;OAEG;IACH,cAAc,CAAC,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI;IAKrC;;OAEG;IACH,gBAAgB,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI;IAKzC;;;OAGG;YACW,mBAAmB;IAkCjC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAwD9B;;;OAGG;YACW,gBAAgB;IA0B9B;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCzC;;OAEG;IACH,MAAM,IAAI,MAAM;IAIhB;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOjD;;OAEG;YACW,kBAAkB;CAwLjC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa,CAEzE;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,MAAM,CAAC,MAAM,CACX,OAAO,GAAE,kBAAkB,GAAG;QAC5B,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC;QACpB,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;KACd,GACL,aAAa;CAYjB;AAGD,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../core/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,kBAAkB,CAAC;AAc1B,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEnE,OAAO,EAAE,WAAW,EAAa,MAAM,QAAQ,CAAC;AAOhD;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wBAAwB,CAAC,EAAE,cAAc,CAAC;IAC1C,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;CACnB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,mBAAmB,CAAC,CAAiB;IAC7C,OAAO,CAAC,0BAA0B,CAAS;IAC3C,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,kBAAuB;IA2L5C;;OAEG;IACH,MAAM,CAAC,MAAM,CACX,OAAO,GAAE,kBAAkB,GAAG;QAC5B,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC;QACpB,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;KACd,GACL,aAAa;IAahB;;;OAGG;IACH,iBAAiB,CAAC,GAAG,SAAS,EAAE,GAAG,EAAE,GAAG,IAAI;IAK5C;;OAEG;IACH,mBAAmB,CAAC,GAAG,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI;IAKhD;;OAEG;IACH,eAAe,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI;IAKvC;;OAEG;IACH,qBAAqB,CAAC,GAAG,YAAY,EAAE,GAAG,EAAE,GAAG,IAAI;IAKnD;;OAEG;IACH,cAAc,CAAC,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI;IAKrC;;OAEG;IACH,gBAAgB,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI;IAKzC;;;OAGG;YACW,mBAAmB;IAkCjC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAwD9B;;;OAGG;YACW,gBAAgB;IA0B9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI;IAK5B;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCzC;;OAEG;IACH,MAAM,IAAI,MAAM;IAIhB;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOjD;;OAEG;YACW,kBAAkB;CAwLjC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa,CAEzE;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,MAAM,CAAC,MAAM,CACX,OAAO,GAAE,kBAAkB,GAAG;QAC5B,WAAW,CAAC,EAAE,GAAG,EAAE,CAAC;QACpB,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;KACd,GACL,aAAa;CAYjB;AAGD,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,CAAC"}
package/dist/factory.js CHANGED
@@ -316,6 +316,42 @@ export class WynkFramework {
316
316
  }
317
317
  console.log(`✅ All providers cleaned up\n`);
318
318
  }
319
+ /**
320
+ * Use an Elysia plugin or middleware (fully compatible with Elysia.js ecosystem)
321
+ *
322
+ * This method directly proxies to Elysia's use() method, making all Elysia plugins
323
+ * and middleware work seamlessly with WynkJS.
324
+ *
325
+ * @param plugin - Any Elysia plugin or instance
326
+ * @returns this for method chaining
327
+ *
328
+ * @example
329
+ * ```typescript
330
+ * import { WynkFactory } from "wynkjs";
331
+ * import { compression } from "wynkjs";
332
+ * import { cors } from "@elysiajs/cors";
333
+ * import { swagger } from "@elysiajs/swagger";
334
+ * import { jwt } from "@elysiajs/jwt";
335
+ *
336
+ * const app = WynkFactory.create({
337
+ * controllers: [UserController],
338
+ * });
339
+ *
340
+ * // Use WynkJS built-in plugins
341
+ * app.use(compression({ threshold: 1024 }));
342
+ *
343
+ * // Use any Elysia plugin from npm
344
+ * app.use(cors());
345
+ * app.use(swagger());
346
+ * app.use(jwt({ name: 'jwt', secret: 'secret' }));
347
+ *
348
+ * await app.listen(3000);
349
+ * ```
350
+ */
351
+ use(...plugins) {
352
+ this.app.use(...plugins);
353
+ return this;
354
+ }
319
355
  /**
320
356
  * Start listening on a port
321
357
  */
package/dist/index.d.ts CHANGED
@@ -21,12 +21,21 @@ export * from "./decorators/formatter.decorators";
21
21
  export * from "./filters/exception.filters";
22
22
  export * from "./decorators/database.decorators";
23
23
  export * from "./dto";
24
+ export { Request } from "./request";
25
+ export { Response } from "./response";
26
+ export type { WynkRequest } from "./request";
27
+ export type { WynkResponse } from "./response";
28
+ export type { CookieOptions } from "./response";
29
+ export type { Request as RequestType } from "./request";
30
+ export type { Response as ResponseType } from "./response";
24
31
  export { schemaRegistry } from "./schema-registry";
25
32
  export * from "./factory";
26
33
  export type { CorsOptions } from "./cors";
27
34
  export { setupCors, validateCorsOptions } from "./cors";
28
35
  export type { GlobalPrefixOptions } from "./global-prefix";
29
36
  export { applyGlobalPrefix, normalizePrefixPath, validateGlobalPrefix, wrapWithPrefix, } from "./global-prefix";
37
+ export { compression } from "./plugins/compression";
38
+ export type { CompressionOptions } from "./plugins/compression";
30
39
  export * from "./testing";
31
40
  /**
32
41
  * Framework version
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../core/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,kBAAkB,CAAC;AAI1B,OAAO,EACL,UAAU,EACV,MAAM,EACN,SAAS,EACT,cAAc,EACd,QAAQ,EACR,SAAS,GACV,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGpD,OAAO,EACL,UAAU,IAAI,UAAU,EACxB,MAAM,IAAI,MAAM,EAChB,SAAS,IAAI,SAAS,EACtB,cAAc,IAAI,cAAc,EAChC,QAAQ,IAAI,QAAQ,EACpB,SAAS,IAAI,SAAS,GACvB,MAAM,UAAU,CAAC;AAGlB,cAAc,8BAA8B,CAAC;AAG7C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAGlD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAI3C,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC;AAI5C,cAAc,kCAAkC,CAAC;AASjD,cAAc,OAAO,CAAC;AAGtB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,cAAc,WAAW,CAAC;AAG1B,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAGxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,GACf,MAAM,iBAAiB,CAAC;AAGzB,cAAc,WAAW,CAAC;AAE1B;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../core/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,kBAAkB,CAAC;AAI1B,OAAO,EACL,UAAU,EACV,MAAM,EACN,SAAS,EACT,cAAc,EACd,QAAQ,EACR,SAAS,GACV,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGpD,OAAO,EACL,UAAU,IAAI,UAAU,EACxB,MAAM,IAAI,MAAM,EAChB,SAAS,IAAI,SAAS,EACtB,cAAc,IAAI,cAAc,EAChC,QAAQ,IAAI,QAAQ,EACpB,SAAS,IAAI,SAAS,GACvB,MAAM,UAAU,CAAC;AAGlB,cAAc,8BAA8B,CAAC;AAG7C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,+BAA+B,CAAC;AAG9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAGlD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAI3C,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC;AAI5C,cAAc,kCAAkC,CAAC;AASjD,cAAc,OAAO,CAAC;AAGtB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,YAAY,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnD,cAAc,WAAW,CAAC;AAG1B,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAGxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,GACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,cAAc,WAAW,CAAC;AAE1B;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -40,12 +40,17 @@ export * from "./decorators/database.decorators";
40
40
  // See: plugins/drizzle and plugins/mongoose
41
41
  // DTO Utilities
42
42
  export * from "./dto";
43
+ // Request and Response wrappers
44
+ export { Request } from "./request";
45
+ export { Response } from "./response";
43
46
  // Schema Registry for custom error messages
44
47
  export { schemaRegistry } from "./schema-registry";
45
48
  // Application Factory
46
49
  export * from "./factory";
47
50
  export { setupCors, validateCorsOptions } from "./cors";
48
51
  export { applyGlobalPrefix, normalizePrefixPath, validateGlobalPrefix, wrapWithPrefix, } from "./global-prefix";
52
+ // Plugins
53
+ export { compression } from "./plugins/compression";
49
54
  // Testing Module
50
55
  export * from "./testing";
51
56
  /**
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Compression Plugin Options
3
+ */
4
+ export interface CompressionOptions {
5
+ /**
6
+ * Minimum byte size for compression
7
+ * @default 1024
8
+ */
9
+ threshold?: number;
10
+ /**
11
+ * Preferred encoding order (first match will be used)
12
+ * @default ["br", "gzip", "deflate"]
13
+ */
14
+ encodings?: ("br" | "gzip" | "deflate")[];
15
+ /**
16
+ * Brotli compression options
17
+ */
18
+ brotliOptions?: {
19
+ params?: Record<number, number>;
20
+ };
21
+ /**
22
+ * Zlib (gzip/deflate) compression options
23
+ */
24
+ zlibOptions?: {
25
+ level?: number;
26
+ memLevel?: number;
27
+ strategy?: number;
28
+ };
29
+ }
30
+ /**
31
+ * Compression Plugin for WynkJS
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * import { WynkFactory } from "wynkjs";
36
+ * import { compression } from "wynkjs/plugins/compression";
37
+ *
38
+ * const app = WynkFactory.create({
39
+ * controllers: [UserController],
40
+ * });
41
+ *
42
+ * // Add compression middleware
43
+ * app.use(compression({
44
+ * threshold: 1024,
45
+ * encodings: ["br", "gzip", "deflate"]
46
+ * }));
47
+ *
48
+ * await app.listen(3000);
49
+ * ```
50
+ */
51
+ /**
52
+ * Compression Plugin for WynkJS
53
+ *
54
+ * Simple compression middleware using Elysia's onAfterHandle hook
55
+ * Supports Brotli, Gzip, and Deflate compression
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * import { WynkFactory, compression } from "wynkjs";
60
+ *
61
+ * const app = WynkFactory.create({
62
+ * controllers: [UserController],
63
+ * });
64
+ *
65
+ * // Add compression middleware
66
+ * app.use(compression({
67
+ * threshold: 1024,
68
+ * encodings: ["gzip", "br"]
69
+ * }));
70
+ *
71
+ * await app.listen(3000);
72
+ * ```
73
+ */
74
+ export declare function compression(options?: CompressionOptions): (app: any) => any;
75
+ //# sourceMappingURL=compression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../../core/plugins/compression.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAE1C;;OAEG;IACH,aAAa,CAAC,EAAE;QACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjC,CAAC;IAEF;;OAEG;IACH,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CACzB,OAAO,GAAE,kBAAuB,GAC/B,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CA4FnB"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Compression Plugin for WynkJS
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * import { WynkFactory } from "wynkjs";
7
+ * import { compression } from "wynkjs/plugins/compression";
8
+ *
9
+ * const app = WynkFactory.create({
10
+ * controllers: [UserController],
11
+ * });
12
+ *
13
+ * // Add compression middleware
14
+ * app.use(compression({
15
+ * threshold: 1024,
16
+ * encodings: ["br", "gzip", "deflate"]
17
+ * }));
18
+ *
19
+ * await app.listen(3000);
20
+ * ```
21
+ */
22
+ /**
23
+ * Compression Plugin for WynkJS
24
+ *
25
+ * Simple compression middleware using Elysia's onAfterHandle hook
26
+ * Supports Brotli, Gzip, and Deflate compression
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import { WynkFactory, compression } from "wynkjs";
31
+ *
32
+ * const app = WynkFactory.create({
33
+ * controllers: [UserController],
34
+ * });
35
+ *
36
+ * // Add compression middleware
37
+ * app.use(compression({
38
+ * threshold: 1024,
39
+ * encodings: ["gzip", "br"]
40
+ * }));
41
+ *
42
+ * await app.listen(3000);
43
+ * ```
44
+ */
45
+ export function compression(options = {}) {
46
+ const config = {
47
+ threshold: options.threshold ?? 1024,
48
+ encodings: options.encodings ?? ["gzip", "br", "deflate"],
49
+ brotliOptions: options.brotliOptions ?? {},
50
+ zlibOptions: options.zlibOptions ?? {},
51
+ };
52
+ return (app) => {
53
+ return app.onAfterHandle(async function compressionHandler(context) {
54
+ const { response, request, set } = context;
55
+ // Skip if no response
56
+ if (!response)
57
+ return;
58
+ // Skip if already compressed
59
+ if (set.headers?.["content-encoding"])
60
+ return;
61
+ // Get client's accepted encodings
62
+ const acceptEncoding = (request.headers.get("accept-encoding") || "").toLowerCase();
63
+ // Find best compression match
64
+ let encoding = null;
65
+ for (const enc of config.encodings) {
66
+ if (acceptEncoding.includes(enc)) {
67
+ encoding = enc;
68
+ break;
69
+ }
70
+ }
71
+ if (!encoding)
72
+ return; // No supported encoding
73
+ // Convert response to buffer
74
+ let body;
75
+ if (Buffer.isBuffer(response)) {
76
+ body = response;
77
+ }
78
+ else if (typeof response === "string") {
79
+ body = Buffer.from(response);
80
+ }
81
+ else if (typeof response === "object") {
82
+ body = Buffer.from(JSON.stringify(response));
83
+ set.headers["content-type"] =
84
+ set.headers["content-type"] || "application/json";
85
+ }
86
+ else {
87
+ body = Buffer.from(String(response));
88
+ }
89
+ // Check size threshold
90
+ if (body.length < config.threshold)
91
+ return;
92
+ // Compress
93
+ try {
94
+ const zlib = await import("node:zlib");
95
+ const { promisify } = await import("node:util");
96
+ let compressed;
97
+ switch (encoding) {
98
+ case "br":
99
+ compressed = await promisify(zlib.brotliCompress)(body, config.brotliOptions);
100
+ break;
101
+ case "gzip":
102
+ compressed = await promisify(zlib.gzip)(body, config.zlibOptions);
103
+ break;
104
+ case "deflate":
105
+ compressed = await promisify(zlib.deflate)(body, config.zlibOptions);
106
+ break;
107
+ default:
108
+ return;
109
+ }
110
+ // Only use if smaller
111
+ if (compressed.length >= body.length)
112
+ return;
113
+ // Set headers and return compressed body
114
+ set.headers["content-encoding"] = encoding;
115
+ set.headers["vary"] = "Accept-Encoding";
116
+ delete set.headers["content-length"]; // Let Elysia set this
117
+ return compressed;
118
+ }
119
+ catch (error) {
120
+ console.error("[Compression Error]:", error);
121
+ return; // Return original on error
122
+ }
123
+ });
124
+ };
125
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Request Wrapper for WynkJS Framework
3
+ * Provides a clean API for accessing request data and adding custom properties
4
+ */
5
+ export interface CookieOptions {
6
+ domain?: string;
7
+ expires?: Date;
8
+ httpOnly?: boolean;
9
+ maxAge?: number;
10
+ path?: string;
11
+ sameSite?: boolean | "lax" | "strict" | "none";
12
+ secure?: boolean;
13
+ priority?: "low" | "medium" | "high";
14
+ partitioned?: boolean;
15
+ }
16
+ /**
17
+ * Request class - wraps Elysia context for request operations
18
+ * Allows middleware to add custom properties that persist through the request lifecycle
19
+ */
20
+ export declare class Request {
21
+ private ctx;
22
+ private customData;
23
+ private originalRequest;
24
+ constructor(ctx: any);
25
+ /**
26
+ * Get request body
27
+ */
28
+ get body(): any;
29
+ /**
30
+ * Get route parameters
31
+ */
32
+ get params(): any;
33
+ /**
34
+ * Get query parameters
35
+ */
36
+ get query(): any;
37
+ /**
38
+ * Get request headers
39
+ */
40
+ get headers(): any;
41
+ /**
42
+ * Get request method (GET, POST, etc.)
43
+ */
44
+ get method(): string;
45
+ /**
46
+ * Get request URL
47
+ */
48
+ get url(): string;
49
+ /**
50
+ * Get request path
51
+ */
52
+ get path(): string;
53
+ /**
54
+ * Get client IP address
55
+ */
56
+ get ip(): string | undefined;
57
+ /**
58
+ * Get cookies from request
59
+ */
60
+ get cookies(): Record<string, string>;
61
+ /**
62
+ * Get a specific cookie value
63
+ */
64
+ getCookie(name: string): string | undefined;
65
+ /**
66
+ * Get user object (set by authentication middleware)
67
+ */
68
+ get user(): any;
69
+ /**
70
+ * Set user object (typically used by authentication middleware)
71
+ */
72
+ set user(value: any);
73
+ /**
74
+ * Get the raw Elysia context
75
+ */
76
+ get raw(): any;
77
+ /**
78
+ * Get the Response wrapper instance
79
+ */
80
+ getResponse(): any;
81
+ /**
82
+ * Set custom data that persists through request lifecycle
83
+ * Useful for middleware to pass data to handlers
84
+ *
85
+ * @example
86
+ * // In middleware
87
+ * request.set('startTime', Date.now());
88
+ *
89
+ * // In handler
90
+ * const startTime = request.get('startTime');
91
+ */
92
+ set(key: string, value: any): this;
93
+ /**
94
+ * Get custom data set by middleware
95
+ */
96
+ get(key: string): any;
97
+ /**
98
+ * Check if custom data exists
99
+ */
100
+ has(key: string): boolean;
101
+ /**
102
+ * Delete custom data
103
+ */
104
+ delete(key: string): boolean;
105
+ /**
106
+ * Get all custom data
107
+ */
108
+ getAllCustomData(): Record<string, any>;
109
+ /**
110
+ * Check if request accepts a certain content type
111
+ */
112
+ accepts(type: string): boolean;
113
+ /**
114
+ * Check if request is JSON
115
+ */
116
+ isJson(): boolean;
117
+ /**
118
+ * Check if request is form data
119
+ */
120
+ isFormData(): boolean;
121
+ /**
122
+ * Get bearer token from Authorization header
123
+ */
124
+ getBearerToken(): string | undefined;
125
+ }
126
+ export type WynkRequest = Request;
127
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../core/request.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAAM;gBAEjB,GAAG,EAAE,GAAG;IAMpB;;OAEG;IACH,IAAI,IAAI,IAAI,GAAG,CAEd;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,GAAG,CAEhB;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,GAAG,CAEf;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,GAAG,CAoBjB;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,IAAI,EAAE,IAAI,MAAM,GAAG,SAAS,CAM3B;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAapC;IAED;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI3C;;OAEG;IACH,IAAI,IAAI,IAAI,GAAG,CAEd;IAED;;OAEG;IACH,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,EAElB;IAED;;OAEG;IACH,IAAI,GAAG,IAAI,GAAG,CAEb;IAED;;OAEG;IACH,WAAW,IAAI,GAAG;IAIlB;;;;;;;;;;OAUG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAUlC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;IAIrB;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQ5B;;OAEG;IACH,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAQvC;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAK9B;;OAEG;IACH,MAAM,IAAI,OAAO;IAKjB;;OAEG;IACH,UAAU,IAAI,OAAO;IAKrB;;OAEG;IACH,cAAc,IAAI,MAAM,GAAG,SAAS;CAOrC;AAGD,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC"}