@carno.js/core 1.1.1 → 1.2.0

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 (124) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +188 -188
  3. package/dist/Carno.js +45 -26
  4. package/dist/Carno.mjs +45 -26
  5. package/dist/bun/index.js +4 -4
  6. package/dist/bun/index.js.map +30 -29
  7. package/dist/compression/CompressionMiddleware.js +110 -0
  8. package/dist/compression/CompressionMiddleware.mjs +90 -0
  9. package/dist/index.js +3 -1
  10. package/dist/index.mjs +2 -0
  11. package/package.json +2 -2
  12. package/src/Carno.ts +728 -673
  13. package/src/DefaultRoutes.ts +34 -34
  14. package/src/cache/CacheDriver.ts +50 -50
  15. package/src/cache/CacheService.ts +139 -139
  16. package/src/cache/MemoryDriver.ts +104 -104
  17. package/src/cache/RedisDriver.ts +116 -116
  18. package/src/compiler/JITCompiler.ts +167 -167
  19. package/src/compression/CompressionMiddleware.ts +221 -0
  20. package/src/container/Container.ts +168 -168
  21. package/src/context/Context.ts +130 -130
  22. package/src/cors/CorsHandler.ts +145 -145
  23. package/src/decorators/Controller.ts +63 -63
  24. package/src/decorators/Inject.ts +16 -16
  25. package/src/decorators/Middleware.ts +22 -22
  26. package/src/decorators/Service.ts +18 -18
  27. package/src/decorators/methods.ts +58 -58
  28. package/src/decorators/params.ts +47 -47
  29. package/src/events/Lifecycle.ts +97 -97
  30. package/src/exceptions/HttpException.ts +99 -99
  31. package/src/index.ts +99 -95
  32. package/src/metadata.ts +46 -46
  33. package/src/middleware/CarnoMiddleware.ts +20 -14
  34. package/src/router/RadixRouter.ts +225 -225
  35. package/src/testing/TestHarness.ts +185 -185
  36. package/src/utils/Metadata.ts +43 -43
  37. package/src/utils/parseQuery.ts +161 -161
  38. package/src/validation/ValibotAdapter.ts +95 -95
  39. package/src/validation/ValidatorAdapter.ts +69 -69
  40. package/src/validation/ZodAdapter.ts +102 -102
  41. package/dist/Carno.d.js +0 -14
  42. package/dist/Carno.d.mjs +0 -1
  43. package/dist/DefaultRoutes.d.js +0 -13
  44. package/dist/DefaultRoutes.d.mjs +0 -0
  45. package/dist/cache/CacheDriver.d.js +0 -13
  46. package/dist/cache/CacheDriver.d.mjs +0 -0
  47. package/dist/cache/CacheService.d.js +0 -13
  48. package/dist/cache/CacheService.d.mjs +0 -0
  49. package/dist/cache/MemoryDriver.d.js +0 -13
  50. package/dist/cache/MemoryDriver.d.mjs +0 -0
  51. package/dist/cache/RedisDriver.d.js +0 -13
  52. package/dist/cache/RedisDriver.d.mjs +0 -0
  53. package/dist/compiler/JITCompiler.d.js +0 -13
  54. package/dist/compiler/JITCompiler.d.mjs +0 -0
  55. package/dist/container/Container.d.js +0 -13
  56. package/dist/container/Container.d.mjs +0 -0
  57. package/dist/context/Context.d.js +0 -13
  58. package/dist/context/Context.d.mjs +0 -0
  59. package/dist/cors/CorsHandler.d.js +0 -13
  60. package/dist/cors/CorsHandler.d.mjs +0 -0
  61. package/dist/decorators/Controller.d.js +0 -13
  62. package/dist/decorators/Controller.d.mjs +0 -0
  63. package/dist/decorators/Inject.d.js +0 -13
  64. package/dist/decorators/Inject.d.mjs +0 -0
  65. package/dist/decorators/Middleware.d.js +0 -13
  66. package/dist/decorators/Middleware.d.mjs +0 -0
  67. package/dist/decorators/Service.d.js +0 -13
  68. package/dist/decorators/Service.d.mjs +0 -0
  69. package/dist/decorators/methods.d.js +0 -13
  70. package/dist/decorators/methods.d.mjs +0 -0
  71. package/dist/decorators/params.d.js +0 -13
  72. package/dist/decorators/params.d.mjs +0 -0
  73. package/dist/events/Lifecycle.d.js +0 -13
  74. package/dist/events/Lifecycle.d.mjs +0 -0
  75. package/dist/exceptions/HttpException.d.js +0 -13
  76. package/dist/exceptions/HttpException.d.mjs +0 -0
  77. package/dist/index.d.js +0 -130
  78. package/dist/index.d.mjs +0 -78
  79. package/dist/metadata.d.js +0 -13
  80. package/dist/metadata.d.mjs +0 -0
  81. package/dist/middleware/CarnoMiddleware.d.js +0 -13
  82. package/dist/middleware/CarnoMiddleware.d.mjs +0 -0
  83. package/dist/router/RadixRouter.d.js +0 -13
  84. package/dist/router/RadixRouter.d.mjs +0 -0
  85. package/dist/testing/TestHarness.d.js +0 -13
  86. package/dist/testing/TestHarness.d.mjs +0 -0
  87. package/dist/utils/Metadata.d.js +0 -13
  88. package/dist/utils/Metadata.d.mjs +0 -0
  89. package/dist/utils/parseQuery.d.js +0 -13
  90. package/dist/utils/parseQuery.d.mjs +0 -0
  91. package/dist/validation/ValibotAdapter.d.js +0 -13
  92. package/dist/validation/ValibotAdapter.d.mjs +0 -0
  93. package/dist/validation/ValidatorAdapter.d.js +0 -13
  94. package/dist/validation/ValidatorAdapter.d.mjs +0 -0
  95. package/dist/validation/ZodAdapter.d.js +0 -13
  96. package/dist/validation/ZodAdapter.d.mjs +0 -0
  97. package/src/Carno.d.ts +0 -135
  98. package/src/DefaultRoutes.d.ts +0 -19
  99. package/src/cache/CacheDriver.d.ts +0 -43
  100. package/src/cache/CacheService.d.ts +0 -89
  101. package/src/cache/MemoryDriver.d.ts +0 -32
  102. package/src/cache/RedisDriver.d.ts +0 -34
  103. package/src/compiler/JITCompiler.d.ts +0 -36
  104. package/src/container/Container.d.ts +0 -38
  105. package/src/context/Context.d.ts +0 -36
  106. package/src/cors/CorsHandler.d.ts +0 -47
  107. package/src/decorators/Controller.d.ts +0 -13
  108. package/src/decorators/Inject.d.ts +0 -6
  109. package/src/decorators/Middleware.d.ts +0 -5
  110. package/src/decorators/Service.d.ts +0 -9
  111. package/src/decorators/methods.d.ts +0 -7
  112. package/src/decorators/params.d.ts +0 -13
  113. package/src/events/Lifecycle.d.ts +0 -54
  114. package/src/exceptions/HttpException.d.ts +0 -43
  115. package/src/index.d.ts +0 -42
  116. package/src/metadata.d.ts +0 -41
  117. package/src/middleware/CarnoMiddleware.d.ts +0 -12
  118. package/src/router/RadixRouter.d.ts +0 -19
  119. package/src/testing/TestHarness.d.ts +0 -71
  120. package/src/utils/Metadata.d.ts +0 -20
  121. package/src/utils/parseQuery.d.ts +0 -23
  122. package/src/validation/ValibotAdapter.d.ts +0 -30
  123. package/src/validation/ValidatorAdapter.d.ts +0 -54
  124. package/src/validation/ZodAdapter.d.ts +0 -35
@@ -0,0 +1,110 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: !0 });
8
+ }, __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from == "object" || typeof from == "function")
10
+ for (let key of __getOwnPropNames(from))
11
+ !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod);
15
+ var CompressionMiddleware_exports = {};
16
+ __export(CompressionMiddleware_exports, {
17
+ CompressionMiddleware: () => CompressionMiddleware
18
+ });
19
+ module.exports = __toCommonJS(CompressionMiddleware_exports);
20
+ var import_zlib = require("zlib");
21
+ const DEFAULT_THRESHOLD = 1024, DEFAULT_ENCODINGS = ["br", "gzip"], DEFAULT_COMPRESSIBLE_TYPES = [
22
+ "text/",
23
+ "application/json",
24
+ "application/javascript",
25
+ "application/xml",
26
+ "application/xhtml+xml",
27
+ "image/svg+xml"
28
+ ], DEFAULT_BROTLI_QUALITY = 4, DEFAULT_GZIP_LEVEL = 6;
29
+ class CompressionMiddleware {
30
+ constructor(config) {
31
+ this.threshold = config?.threshold ?? DEFAULT_THRESHOLD, this.compressibleTypes = (config?.compressibleTypes ?? DEFAULT_COMPRESSIBLE_TYPES).map((t) => t.toLowerCase());
32
+ const encodings = config?.encodings ?? DEFAULT_ENCODINGS;
33
+ this.encodingOrder = encodings;
34
+ const brotliQuality = config?.brotliQuality ?? DEFAULT_BROTLI_QUALITY, gzipLevel = config?.gzipLevel ?? DEFAULT_GZIP_LEVEL;
35
+ this.compressors = /* @__PURE__ */ new Map();
36
+ for (const enc of encodings)
37
+ switch (enc) {
38
+ case "br":
39
+ this.compressors.set("br", (data) => {
40
+ const buf = (0, import_zlib.brotliCompressSync)(data, {
41
+ params: { [import_zlib.constants.BROTLI_PARAM_QUALITY]: brotliQuality }
42
+ });
43
+ return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
44
+ });
45
+ break;
46
+ case "gzip":
47
+ this.compressors.set(
48
+ "gzip",
49
+ (data) => Bun.gzipSync(data, { level: gzipLevel })
50
+ );
51
+ break;
52
+ case "deflate":
53
+ this.compressors.set(
54
+ "deflate",
55
+ (data) => Bun.deflateSync(data)
56
+ );
57
+ break;
58
+ }
59
+ }
60
+ async handle(ctx, next) {
61
+ const response = await next(), acceptEncoding = ctx.req.headers.get("accept-encoding");
62
+ if (!acceptEncoding || response.headers.get("content-encoding"))
63
+ return response;
64
+ const contentType = response.headers.get("content-type");
65
+ if (!contentType || !this.isCompressible(contentType))
66
+ return response;
67
+ const encoding = this.negotiateEncoding(acceptEncoding);
68
+ if (!encoding)
69
+ return response;
70
+ const buffer = await response.arrayBuffer();
71
+ if (buffer.byteLength < this.threshold)
72
+ return new Response(buffer, {
73
+ status: response.status,
74
+ statusText: response.statusText,
75
+ headers: response.headers
76
+ });
77
+ const compressor = this.compressors.get(encoding), bodyBytes = new Uint8Array(buffer), compressed = compressor(bodyBytes);
78
+ if (compressed.byteLength >= buffer.byteLength)
79
+ return new Response(buffer, {
80
+ status: response.status,
81
+ statusText: response.statusText,
82
+ headers: response.headers
83
+ });
84
+ const headers = new Headers(response.headers);
85
+ return headers.set("Content-Encoding", encoding), headers.set("Content-Length", String(compressed.byteLength)), headers.set("Vary", this.buildVaryHeader(headers.get("Vary"))), new Response(compressed, {
86
+ status: response.status,
87
+ statusText: response.statusText,
88
+ headers
89
+ });
90
+ }
91
+ isCompressible(contentType) {
92
+ const lower = contentType.toLowerCase();
93
+ for (const pattern of this.compressibleTypes)
94
+ if (lower.includes(pattern)) return !0;
95
+ return !1;
96
+ }
97
+ negotiateEncoding(acceptEncoding) {
98
+ const lower = acceptEncoding.toLowerCase();
99
+ for (const encoding of this.encodingOrder)
100
+ if (lower.includes(encoding)) return encoding;
101
+ return null;
102
+ }
103
+ buildVaryHeader(existing) {
104
+ return existing ? existing.toLowerCase().includes("accept-encoding") ? existing : `${existing}, Accept-Encoding` : "Accept-Encoding";
105
+ }
106
+ }
107
+ // Annotate the CommonJS export names for ESM import in node:
108
+ 0 && (module.exports = {
109
+ CompressionMiddleware
110
+ });
@@ -0,0 +1,90 @@
1
+ import { brotliCompressSync, constants } from "zlib";
2
+ const DEFAULT_THRESHOLD = 1024, DEFAULT_ENCODINGS = ["br", "gzip"], DEFAULT_COMPRESSIBLE_TYPES = [
3
+ "text/",
4
+ "application/json",
5
+ "application/javascript",
6
+ "application/xml",
7
+ "application/xhtml+xml",
8
+ "image/svg+xml"
9
+ ], DEFAULT_BROTLI_QUALITY = 4, DEFAULT_GZIP_LEVEL = 6;
10
+ class CompressionMiddleware {
11
+ constructor(config) {
12
+ this.threshold = config?.threshold ?? DEFAULT_THRESHOLD, this.compressibleTypes = (config?.compressibleTypes ?? DEFAULT_COMPRESSIBLE_TYPES).map((t) => t.toLowerCase());
13
+ const encodings = config?.encodings ?? DEFAULT_ENCODINGS;
14
+ this.encodingOrder = encodings;
15
+ const brotliQuality = config?.brotliQuality ?? DEFAULT_BROTLI_QUALITY, gzipLevel = config?.gzipLevel ?? DEFAULT_GZIP_LEVEL;
16
+ this.compressors = /* @__PURE__ */ new Map();
17
+ for (const enc of encodings)
18
+ switch (enc) {
19
+ case "br":
20
+ this.compressors.set("br", (data) => {
21
+ const buf = brotliCompressSync(data, {
22
+ params: { [constants.BROTLI_PARAM_QUALITY]: brotliQuality }
23
+ });
24
+ return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
25
+ });
26
+ break;
27
+ case "gzip":
28
+ this.compressors.set(
29
+ "gzip",
30
+ (data) => Bun.gzipSync(data, { level: gzipLevel })
31
+ );
32
+ break;
33
+ case "deflate":
34
+ this.compressors.set(
35
+ "deflate",
36
+ (data) => Bun.deflateSync(data)
37
+ );
38
+ break;
39
+ }
40
+ }
41
+ async handle(ctx, next) {
42
+ const response = await next(), acceptEncoding = ctx.req.headers.get("accept-encoding");
43
+ if (!acceptEncoding || response.headers.get("content-encoding"))
44
+ return response;
45
+ const contentType = response.headers.get("content-type");
46
+ if (!contentType || !this.isCompressible(contentType))
47
+ return response;
48
+ const encoding = this.negotiateEncoding(acceptEncoding);
49
+ if (!encoding)
50
+ return response;
51
+ const buffer = await response.arrayBuffer();
52
+ if (buffer.byteLength < this.threshold)
53
+ return new Response(buffer, {
54
+ status: response.status,
55
+ statusText: response.statusText,
56
+ headers: response.headers
57
+ });
58
+ const compressor = this.compressors.get(encoding), bodyBytes = new Uint8Array(buffer), compressed = compressor(bodyBytes);
59
+ if (compressed.byteLength >= buffer.byteLength)
60
+ return new Response(buffer, {
61
+ status: response.status,
62
+ statusText: response.statusText,
63
+ headers: response.headers
64
+ });
65
+ const headers = new Headers(response.headers);
66
+ return headers.set("Content-Encoding", encoding), headers.set("Content-Length", String(compressed.byteLength)), headers.set("Vary", this.buildVaryHeader(headers.get("Vary"))), new Response(compressed, {
67
+ status: response.status,
68
+ statusText: response.statusText,
69
+ headers
70
+ });
71
+ }
72
+ isCompressible(contentType) {
73
+ const lower = contentType.toLowerCase();
74
+ for (const pattern of this.compressibleTypes)
75
+ if (lower.includes(pattern)) return !0;
76
+ return !1;
77
+ }
78
+ negotiateEncoding(acceptEncoding) {
79
+ const lower = acceptEncoding.toLowerCase();
80
+ for (const encoding of this.encodingOrder)
81
+ if (lower.includes(encoding)) return encoding;
82
+ return null;
83
+ }
84
+ buildVaryHeader(existing) {
85
+ return existing ? existing.toLowerCase().includes("accept-encoding") ? existing : `${existing}, Accept-Encoding` : "Accept-Encoding";
86
+ }
87
+ }
88
+ export {
89
+ CompressionMiddleware
90
+ };
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ __export(index_exports, {
18
18
  Body: () => import_params.Body,
19
19
  CacheService: () => import_CacheService.CacheService,
20
20
  Carno: () => import_Carno.Carno,
21
+ CompressionMiddleware: () => import_CompressionMiddleware.CompressionMiddleware,
21
22
  ConflictException: () => import_HttpException.ConflictException,
22
23
  Container: () => import_Container.Container,
23
24
  Context: () => import_Context.Context,
@@ -70,13 +71,14 @@ __export(index_exports, {
70
71
  withTestApp: () => import_TestHarness.withTestApp
71
72
  });
72
73
  module.exports = __toCommonJS(index_exports);
73
- var import_reflect_metadata = require("reflect-metadata"), import_Carno = require('./Carno.js'), import_Context = require('./context/Context.js'), import_Controller = require('./decorators/Controller.js'), import_methods = require('./decorators/methods.js'), import_params = require('./decorators/params.js'), import_Middleware = require('./decorators/Middleware.js'), import_Service = require('./decorators/Service.js'), import_Inject = require('./decorators/Inject.js'), import_Container = require('./container/Container.js'), import_RadixRouter = require('./router/RadixRouter.js'), import_CorsHandler = require('./cors/CorsHandler.js'), import_ValidatorAdapter = require('./validation/ValidatorAdapter.js'), import_ZodAdapter = require('./validation/ZodAdapter.js'), import_ValibotAdapter = require('./validation/ValibotAdapter.js'), import_HttpException = require('./exceptions/HttpException.js'), import_Lifecycle = require('./events/Lifecycle.js'), import_CacheService = require('./cache/CacheService.js'), import_MemoryDriver = require('./cache/MemoryDriver.js'), import_RedisDriver = require('./cache/RedisDriver.js'), import_TestHarness = require('./testing/TestHarness.js'), import_Metadata = require('./utils/Metadata.js');
74
+ var import_reflect_metadata = require("reflect-metadata"), import_Carno = require('./Carno.js'), import_Context = require('./context/Context.js'), import_Controller = require('./decorators/Controller.js'), import_methods = require('./decorators/methods.js'), import_params = require('./decorators/params.js'), import_Middleware = require('./decorators/Middleware.js'), import_Service = require('./decorators/Service.js'), import_Inject = require('./decorators/Inject.js'), import_Container = require('./container/Container.js'), import_RadixRouter = require('./router/RadixRouter.js'), import_CorsHandler = require('./cors/CorsHandler.js'), import_CompressionMiddleware = require('./compression/CompressionMiddleware.js'), import_ValidatorAdapter = require('./validation/ValidatorAdapter.js'), import_ZodAdapter = require('./validation/ZodAdapter.js'), import_ValibotAdapter = require('./validation/ValibotAdapter.js'), import_HttpException = require('./exceptions/HttpException.js'), import_Lifecycle = require('./events/Lifecycle.js'), import_CacheService = require('./cache/CacheService.js'), import_MemoryDriver = require('./cache/MemoryDriver.js'), import_RedisDriver = require('./cache/RedisDriver.js'), import_TestHarness = require('./testing/TestHarness.js'), import_Metadata = require('./utils/Metadata.js');
74
75
  // Annotate the CommonJS export names for ESM import in node:
75
76
  0 && (module.exports = {
76
77
  BadRequestException,
77
78
  Body,
78
79
  CacheService,
79
80
  Carno,
81
+ CompressionMiddleware,
80
82
  ConflictException,
81
83
  Container,
82
84
  Context,
package/dist/index.mjs CHANGED
@@ -10,6 +10,7 @@ import { Inject } from "./decorators/Inject.mjs";
10
10
  import { Container, Scope } from "./container/Container.mjs";
11
11
  import { RadixRouter } from "./router/RadixRouter.mjs";
12
12
  import { CorsHandler } from "./cors/CorsHandler.mjs";
13
+ import { CompressionMiddleware } from "./compression/CompressionMiddleware.mjs";
13
14
  import { Schema, getSchema, VALIDATION_SCHEMA } from "./validation/ValidatorAdapter.mjs";
14
15
  import { ZodAdapter, ValidationException } from "./validation/ZodAdapter.mjs";
15
16
  import { ValibotAdapter } from "./validation/ValibotAdapter.mjs";
@@ -42,6 +43,7 @@ export {
42
43
  Body,
43
44
  CacheService,
44
45
  Carno,
46
+ CompressionMiddleware,
45
47
  ConflictException,
46
48
  Container,
47
49
  Context,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carno.js/core",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Ultra-fast HTTP framework with aggressive AOT/JIT compilation",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -21,5 +21,5 @@
21
21
  "esbuild-fix-imports-plugin": "^1.0.23",
22
22
  "tsup": "^8.5.1"
23
23
  },
24
- "gitHead": "2dd228ee12d4ebf16263f4cb81587893e67e1961"
24
+ "gitHead": "39c9361e3ffaab51d2d1a40515eafb3e15c12f8c"
25
25
  }