@stacksjs/bun-router 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 (128) hide show
  1. package/dist/{chunk-r15a48wc.js → chunk-cjdekj87.js} +536 -98
  2. package/dist/cli.d.ts +1 -0
  3. package/dist/cli.js +2 -2
  4. package/dist/index.d.ts +3 -1
  5. package/dist/index.js +454 -119
  6. package/package.json +7 -9
  7. package/dist/auth.d.ts +0 -77
  8. package/dist/cache/lru-cache.d.ts +0 -88
  9. package/dist/cache/middleware-memoization.d.ts +0 -101
  10. package/dist/cache/route-cache-warmer.d.ts +0 -125
  11. package/dist/cache/sqlite-cache.d.ts +0 -114
  12. package/dist/cache/streaming-cache.d.ts +0 -86
  13. package/dist/cli/colors.d.ts +0 -12
  14. package/dist/cli/index.d.ts +0 -10
  15. package/dist/cli/middleware.d.ts +0 -31
  16. package/dist/cli/openapi.d.ts +0 -17
  17. package/dist/cli/router.d.ts +0 -15
  18. package/dist/cli/routes.d.ts +0 -30
  19. package/dist/cli/utils.d.ts +0 -68
  20. package/dist/config.d.ts +0 -274
  21. package/dist/container/container.d.ts +0 -141
  22. package/dist/container/contextual-binding.d.ts +0 -112
  23. package/dist/container/decorators.d.ts +0 -114
  24. package/dist/container/service-provider.d.ts +0 -221
  25. package/dist/development/hot-reload.d.ts +0 -129
  26. package/dist/development/index.d.ts +0 -144
  27. package/dist/development/performance-profiler.d.ts +0 -152
  28. package/dist/development/route-debugger.d.ts +0 -102
  29. package/dist/development/route-inspector.d.ts +0 -142
  30. package/dist/development/typescript-utilities.d.ts +0 -116
  31. package/dist/docs.d.ts +0 -10
  32. package/dist/errors/circuit-breaker.d.ts +0 -138
  33. package/dist/errors/error-handler.d.ts +0 -57
  34. package/dist/errors/error-reporting.d.ts +0 -135
  35. package/dist/errors/exceptions.d.ts +0 -178
  36. package/dist/errors/graceful-degradation.d.ts +0 -130
  37. package/dist/errors/index.d.ts +0 -6
  38. package/dist/errors/router-errors.d.ts +0 -97
  39. package/dist/file-serving/static-files.d.ts +0 -98
  40. package/dist/middleware/auth.d.ts +0 -34
  41. package/dist/middleware/content_security_policy.d.ts +0 -54
  42. package/dist/middleware/cors.d.ts +0 -5
  43. package/dist/middleware/csrf.d.ts +0 -7
  44. package/dist/middleware/ddos_protection.d.ts +0 -47
  45. package/dist/middleware/file_security.d.ts +0 -23
  46. package/dist/middleware/file_upload.d.ts +0 -41
  47. package/dist/middleware/helmet.d.ts +0 -54
  48. package/dist/middleware/index.d.ts +0 -55
  49. package/dist/middleware/input_validation.d.ts +0 -46
  50. package/dist/middleware/json_body.d.ts +0 -4
  51. package/dist/middleware/performance_alerting.d.ts +0 -88
  52. package/dist/middleware/performance_dashboard.d.ts +0 -97
  53. package/dist/middleware/performance_monitor.d.ts +0 -236
  54. package/dist/middleware/pipeline.d.ts +0 -90
  55. package/dist/middleware/rate_limit.d.ts +0 -33
  56. package/dist/middleware/request_id.d.ts +0 -4
  57. package/dist/middleware/request_signing.d.ts +0 -96
  58. package/dist/middleware/request_tracer.d.ts +0 -76
  59. package/dist/middleware/response_cache.d.ts +0 -90
  60. package/dist/middleware/security.d.ts +0 -70
  61. package/dist/middleware/security_suite.d.ts +0 -46
  62. package/dist/middleware/session.d.ts +0 -7
  63. package/dist/model-binding/index.d.ts +0 -17
  64. package/dist/model-binding/model-middleware.d.ts +0 -80
  65. package/dist/model-binding/model-registry.d.ts +0 -125
  66. package/dist/model-binding.d.ts +0 -123
  67. package/dist/model-resolver-factory.d.ts +0 -31
  68. package/dist/observability/correlation.d.ts +0 -131
  69. package/dist/observability/health-checks.d.ts +0 -129
  70. package/dist/observability/index.d.ts +0 -92
  71. package/dist/observability/integration.d.ts +0 -112
  72. package/dist/observability/metrics.d.ts +0 -135
  73. package/dist/observability/tracing.d.ts +0 -112
  74. package/dist/optimization/bun-utilities.d.ts +0 -106
  75. package/dist/query-builder-integration.d.ts +0 -24
  76. package/dist/request/enhanced-request.d.ts +0 -143
  77. package/dist/request/macros.d.ts +0 -267
  78. package/dist/response/macros.d.ts +0 -207
  79. package/dist/response/response-factory.d.ts +0 -93
  80. package/dist/router/file-based-routing.d.ts +0 -40
  81. package/dist/router/file-streaming.d.ts +0 -6
  82. package/dist/router/fluent-router.d.ts +0 -179
  83. package/dist/router/fluent-routing.d.ts +0 -198
  84. package/dist/router/group-organization.d.ts +0 -5
  85. package/dist/router/handler-resolver.d.ts +0 -13
  86. package/dist/router/http-methods.d.ts +0 -10
  87. package/dist/router/index.d.ts +0 -114
  88. package/dist/router/middleware-integration.d.ts +0 -86
  89. package/dist/router/middleware.d.ts +0 -5
  90. package/dist/router/model-binding.d.ts +0 -7
  91. package/dist/router/optimized-route-matching.d.ts +0 -6
  92. package/dist/router/route-building.d.ts +0 -5
  93. package/dist/router/route-compiler.d.ts +0 -67
  94. package/dist/router/route-matching.d.ts +0 -5
  95. package/dist/router/route-trie.d.ts +0 -69
  96. package/dist/router/router.d.ts +0 -133
  97. package/dist/router/server.d.ts +0 -5
  98. package/dist/router/validation-integration.d.ts +0 -116
  99. package/dist/router/view-rendering.d.ts +0 -5
  100. package/dist/router/websocket.d.ts +0 -5
  101. package/dist/routing/route-caching.d.ts +0 -105
  102. package/dist/routing/route-throttling.d.ts +0 -112
  103. package/dist/routing/subdomain-routing.d.ts +0 -159
  104. package/dist/streaming/index.d.ts +0 -15
  105. package/dist/streaming/sse-handler.d.ts +0 -81
  106. package/dist/streaming/stream-handler.d.ts +0 -81
  107. package/dist/testing/auth-testing.d.ts +0 -107
  108. package/dist/testing/file-upload-testing.d.ts +0 -139
  109. package/dist/testing/index.d.ts +0 -10
  110. package/dist/testing/middleware-testing.d.ts +0 -99
  111. package/dist/testing/model-binding-testing.d.ts +0 -132
  112. package/dist/testing/performance-testing.d.ts +0 -202
  113. package/dist/testing/test-client.d.ts +0 -58
  114. package/dist/testing/test-request.d.ts +0 -43
  115. package/dist/testing/test-response.d.ts +0 -45
  116. package/dist/testing/types.d.ts +0 -206
  117. package/dist/testing/websocket-testing.d.ts +0 -170
  118. package/dist/types/controller-types.d.ts +0 -303
  119. package/dist/types/core.d.ts +0 -526
  120. package/dist/types/middleware-types.d.ts +0 -315
  121. package/dist/types/request-response-augmentation.d.ts +0 -373
  122. package/dist/types/route-inference.d.ts +0 -287
  123. package/dist/types.d.ts +0 -1620
  124. package/dist/utils/index.d.ts +0 -1
  125. package/dist/utils/query-preservation.d.ts +0 -31
  126. package/dist/utils.d.ts +0 -69
  127. package/dist/validation/validator.d.ts +0 -169
  128. package/dist/websocket/clustering.d.ts +0 -114
@@ -1,12 +1,16 @@
1
1
  // @bun
2
2
  var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
3
7
  var __export = (target, all) => {
4
8
  for (var name in all)
5
9
  __defProp(target, name, {
6
10
  get: all[name],
7
11
  enumerable: true,
8
12
  configurable: true,
9
- set: (newValue) => all[name] = () => newValue
13
+ set: __exportSetter.bind(all, name)
10
14
  });
11
15
  };
12
16
  var __require = import.meta.require;
@@ -21918,23 +21922,468 @@ async function verifySignature(stringToSign, signature, secret, algorithm = "sha
21918
21922
  return result === 0;
21919
21923
  }
21920
21924
 
21925
+ // src/session/memory-store.ts
21926
+ class MemorySessionStore {
21927
+ defaultTtl;
21928
+ sessions = new Map;
21929
+ cleanupInterval = null;
21930
+ constructor(defaultTtl = 86400) {
21931
+ this.defaultTtl = defaultTtl;
21932
+ this.cleanupInterval = setInterval(() => this.cleanup(), 5 * 60 * 1000);
21933
+ }
21934
+ async get(sid) {
21935
+ const stored = this.sessions.get(sid);
21936
+ if (!stored)
21937
+ return null;
21938
+ if (Date.now() > stored.expiresAt) {
21939
+ this.sessions.delete(sid);
21940
+ return null;
21941
+ }
21942
+ return stored.data;
21943
+ }
21944
+ async set(sid, session, ttl) {
21945
+ const expiresAt = Date.now() + (ttl ?? this.defaultTtl) * 1000;
21946
+ this.sessions.set(sid, { data: session, expiresAt });
21947
+ }
21948
+ async destroy(sid) {
21949
+ this.sessions.delete(sid);
21950
+ }
21951
+ async touch(sid, session, ttl) {
21952
+ const stored = this.sessions.get(sid);
21953
+ if (stored) {
21954
+ stored.expiresAt = Date.now() + (ttl ?? this.defaultTtl) * 1000;
21955
+ stored.data = session;
21956
+ }
21957
+ }
21958
+ async all() {
21959
+ const result = {};
21960
+ const now = Date.now();
21961
+ for (const [sid, stored] of this.sessions) {
21962
+ if (now <= stored.expiresAt) {
21963
+ result[sid] = stored.data;
21964
+ }
21965
+ }
21966
+ return result;
21967
+ }
21968
+ async length() {
21969
+ return this.sessions.size;
21970
+ }
21971
+ async clear() {
21972
+ this.sessions.clear();
21973
+ }
21974
+ cleanup() {
21975
+ const now = Date.now();
21976
+ for (const [sid, stored] of this.sessions) {
21977
+ if (now > stored.expiresAt) {
21978
+ this.sessions.delete(sid);
21979
+ }
21980
+ }
21981
+ }
21982
+ dispose() {
21983
+ if (this.cleanupInterval) {
21984
+ clearInterval(this.cleanupInterval);
21985
+ this.cleanupInterval = null;
21986
+ }
21987
+ this.sessions.clear();
21988
+ }
21989
+ }
21990
+
21991
+ // src/session/file-store.ts
21992
+ import { existsSync as existsSync9, mkdirSync as mkdirSync6, readdirSync as readdirSync6, unlinkSync, writeFileSync as writeFileSync8, readFileSync } from "fs";
21993
+ import { join as join4 } from "path";
21994
+ import { tmpdir } from "os";
21995
+
21996
+ class FileSessionStore {
21997
+ defaultTtl;
21998
+ dir;
21999
+ cleanupInterval = null;
22000
+ constructor(defaultTtl = 86400, dir) {
22001
+ this.defaultTtl = defaultTtl;
22002
+ this.dir = dir || join4(tmpdir(), "bun-router-sessions");
22003
+ if (!existsSync9(this.dir)) {
22004
+ mkdirSync6(this.dir, { recursive: true });
22005
+ }
22006
+ this.cleanupInterval = setInterval(() => this.cleanup(), 10 * 60 * 1000);
22007
+ }
22008
+ filePath(sid) {
22009
+ const safeSid = sid.replace(/[^a-zA-Z0-9_-]/g, "");
22010
+ return join4(this.dir, `${safeSid}.json`);
22011
+ }
22012
+ async get(sid) {
22013
+ const path = this.filePath(sid);
22014
+ if (!existsSync9(path))
22015
+ return null;
22016
+ try {
22017
+ const content = readFileSync(path, "utf-8");
22018
+ const stored = JSON.parse(content);
22019
+ if (Date.now() > stored.expiresAt) {
22020
+ unlinkSync(path);
22021
+ return null;
22022
+ }
22023
+ return stored.data;
22024
+ } catch {
22025
+ return null;
22026
+ }
22027
+ }
22028
+ async set(sid, session, ttl) {
22029
+ const stored = {
22030
+ data: session,
22031
+ expiresAt: Date.now() + (ttl ?? this.defaultTtl) * 1000
22032
+ };
22033
+ writeFileSync8(this.filePath(sid), JSON.stringify(stored), "utf-8");
22034
+ }
22035
+ async destroy(sid) {
22036
+ const path = this.filePath(sid);
22037
+ if (existsSync9(path)) {
22038
+ unlinkSync(path);
22039
+ }
22040
+ }
22041
+ async touch(sid, session, ttl) {
22042
+ const path = this.filePath(sid);
22043
+ if (!existsSync9(path))
22044
+ return;
22045
+ const stored = {
22046
+ data: session,
22047
+ expiresAt: Date.now() + (ttl ?? this.defaultTtl) * 1000
22048
+ };
22049
+ writeFileSync8(path, JSON.stringify(stored), "utf-8");
22050
+ }
22051
+ async all() {
22052
+ const result = {};
22053
+ const now = Date.now();
22054
+ try {
22055
+ const files = readdirSync6(this.dir).filter((f) => f.endsWith(".json"));
22056
+ for (const file of files) {
22057
+ const content = readFileSync(join4(this.dir, file), "utf-8");
22058
+ const stored = JSON.parse(content);
22059
+ if (now <= stored.expiresAt) {
22060
+ const sid = file.replace(".json", "");
22061
+ result[sid] = stored.data;
22062
+ }
22063
+ }
22064
+ } catch {}
22065
+ return result;
22066
+ }
22067
+ async length() {
22068
+ try {
22069
+ return readdirSync6(this.dir).filter((f) => f.endsWith(".json")).length;
22070
+ } catch {
22071
+ return 0;
22072
+ }
22073
+ }
22074
+ async clear() {
22075
+ try {
22076
+ const files = readdirSync6(this.dir).filter((f) => f.endsWith(".json"));
22077
+ for (const file of files) {
22078
+ unlinkSync(join4(this.dir, file));
22079
+ }
22080
+ } catch {}
22081
+ }
22082
+ cleanup() {
22083
+ const now = Date.now();
22084
+ try {
22085
+ const files = readdirSync6(this.dir).filter((f) => f.endsWith(".json"));
22086
+ for (const file of files) {
22087
+ const path = join4(this.dir, file);
22088
+ const content = readFileSync(path, "utf-8");
22089
+ const stored = JSON.parse(content);
22090
+ if (now > stored.expiresAt) {
22091
+ unlinkSync(path);
22092
+ }
22093
+ }
22094
+ } catch {}
22095
+ }
22096
+ dispose() {
22097
+ if (this.cleanupInterval) {
22098
+ clearInterval(this.cleanupInterval);
22099
+ this.cleanupInterval = null;
22100
+ }
22101
+ }
22102
+ }
22103
+
22104
+ // src/session/redis-store.ts
22105
+ class RedisSessionStore {
22106
+ client;
22107
+ defaultTtl;
22108
+ prefix;
22109
+ constructor(client, defaultTtl = 86400, prefix = "sess:") {
22110
+ this.client = client;
22111
+ this.defaultTtl = defaultTtl;
22112
+ this.prefix = prefix;
22113
+ }
22114
+ key(sid) {
22115
+ return `${this.prefix}${sid}`;
22116
+ }
22117
+ async get(sid) {
22118
+ const data = await this.client.get(this.key(sid));
22119
+ if (!data)
22120
+ return null;
22121
+ try {
22122
+ return JSON.parse(data);
22123
+ } catch {
22124
+ return null;
22125
+ }
22126
+ }
22127
+ async set(sid, session, ttl) {
22128
+ const key = this.key(sid);
22129
+ const seconds = ttl ?? this.defaultTtl;
22130
+ await this.client.set(key, JSON.stringify(session), "EX", seconds);
22131
+ }
22132
+ async destroy(sid) {
22133
+ await this.client.del(this.key(sid));
22134
+ }
22135
+ async touch(sid, session, ttl) {
22136
+ const key = this.key(sid);
22137
+ const seconds = ttl ?? this.defaultTtl;
22138
+ await this.client.set(key, JSON.stringify(session), "EX", seconds);
22139
+ }
22140
+ async all() {
22141
+ const keys = await this.client.keys(`${this.prefix}*`);
22142
+ const result = {};
22143
+ for (const key of keys) {
22144
+ const data = await this.client.get(key);
22145
+ if (data) {
22146
+ try {
22147
+ const sid = key.slice(this.prefix.length);
22148
+ result[sid] = JSON.parse(data);
22149
+ } catch {}
22150
+ }
22151
+ }
22152
+ return result;
22153
+ }
22154
+ async length() {
22155
+ const keys = await this.client.keys(`${this.prefix}*`);
22156
+ return keys.length;
22157
+ }
22158
+ async clear() {
22159
+ const keys = await this.client.keys(`${this.prefix}*`);
22160
+ if (keys.length > 0) {
22161
+ await this.client.del(keys);
22162
+ }
22163
+ }
22164
+ }
22165
+
22166
+ // src/session/database-store.ts
22167
+ class DatabaseSessionStore {
22168
+ adapter;
22169
+ defaultTtl;
22170
+ cleanupInterval = null;
22171
+ constructor(adapter, defaultTtl = 86400) {
22172
+ this.adapter = adapter;
22173
+ this.defaultTtl = defaultTtl;
22174
+ this.cleanupInterval = setInterval(() => {
22175
+ const maxAge = Date.now() - this.defaultTtl * 1000;
22176
+ this.adapter.deleteExpiredSessions(maxAge);
22177
+ }, 30 * 60 * 1000);
22178
+ }
22179
+ async get(sid) {
22180
+ const record = await this.adapter.findSession(sid);
22181
+ if (!record)
22182
+ return null;
22183
+ const maxAge = Date.now() - this.defaultTtl * 1000;
22184
+ if (record.last_activity < maxAge) {
22185
+ await this.adapter.deleteSession(sid);
22186
+ return null;
22187
+ }
22188
+ try {
22189
+ return JSON.parse(record.payload);
22190
+ } catch {
22191
+ return null;
22192
+ }
22193
+ }
22194
+ async set(sid, session, _ttl) {
22195
+ await this.adapter.upsertSession(sid, JSON.stringify(session), Date.now());
22196
+ }
22197
+ async destroy(sid) {
22198
+ await this.adapter.deleteSession(sid);
22199
+ }
22200
+ async touch(sid, session, _ttl) {
22201
+ await this.adapter.upsertSession(sid, JSON.stringify(session), Date.now());
22202
+ }
22203
+ async all() {
22204
+ const records = await this.adapter.getAllSessions();
22205
+ const result = {};
22206
+ const maxAge = Date.now() - this.defaultTtl * 1000;
22207
+ for (const record of records) {
22208
+ if (record.last_activity >= maxAge) {
22209
+ try {
22210
+ result[record.id] = JSON.parse(record.payload);
22211
+ } catch {}
22212
+ }
22213
+ }
22214
+ return result;
22215
+ }
22216
+ async length() {
22217
+ return this.adapter.countSessions();
22218
+ }
22219
+ async clear() {
22220
+ await this.adapter.clearAllSessions();
22221
+ }
22222
+ dispose() {
22223
+ if (this.cleanupInterval) {
22224
+ clearInterval(this.cleanupInterval);
22225
+ this.cleanupInterval = null;
22226
+ }
22227
+ }
22228
+ }
22229
+
22230
+ // src/session/index.ts
22231
+ function createSessionStore(config4) {
22232
+ const ttl = config4.ttl ?? 86400;
22233
+ switch (config4.driver) {
22234
+ case "memory":
22235
+ return new MemorySessionStore(ttl);
22236
+ case "file":
22237
+ return new FileSessionStore(ttl, config4.file?.dir);
22238
+ case "redis": {
22239
+ if (!config4.redis?.client) {
22240
+ throw new Error("Redis client is required for redis session driver");
22241
+ }
22242
+ return new RedisSessionStore(config4.redis.client, ttl, config4.redis.prefix);
22243
+ }
22244
+ case "database": {
22245
+ if (!config4.database?.adapter) {
22246
+ throw new Error("Database adapter is required for database session driver");
22247
+ }
22248
+ return new DatabaseSessionStore(config4.database.adapter, ttl);
22249
+ }
22250
+ default:
22251
+ return new MemorySessionStore(ttl);
22252
+ }
22253
+ }
22254
+
22255
+ class SessionManager {
22256
+ sessionId;
22257
+ data;
22258
+ store;
22259
+ flashedKeys = [];
22260
+ previousFlash = {};
22261
+ dirty = false;
22262
+ constructor(sessionId, data, store) {
22263
+ this.sessionId = sessionId;
22264
+ this.data = data;
22265
+ this.store = store;
22266
+ this.previousFlash = { ...data.flash || {} };
22267
+ }
22268
+ get id() {
22269
+ return this.sessionId;
22270
+ }
22271
+ get(key) {
22272
+ if (this.data.flash && key in this.data.flash) {
22273
+ return this.data.flash[key];
22274
+ }
22275
+ if (this.data.data && key in this.data.data) {
22276
+ return this.data.data[key];
22277
+ }
22278
+ return;
22279
+ }
22280
+ set(key, value) {
22281
+ if (!this.data.data)
22282
+ this.data.data = {};
22283
+ this.data.data[key] = value;
22284
+ this.dirty = true;
22285
+ }
22286
+ has(key) {
22287
+ return this.data.data && key in this.data.data || this.data.flash && key in this.data.flash || false;
22288
+ }
22289
+ forget(key) {
22290
+ if (this.data.data) {
22291
+ delete this.data.data[key];
22292
+ this.dirty = true;
22293
+ }
22294
+ }
22295
+ all() {
22296
+ return { ...this.data.data || {}, ...this.data.flash || {} };
22297
+ }
22298
+ flash(key, value) {
22299
+ if (!this.data.flash)
22300
+ this.data.flash = {};
22301
+ this.data.flash[key] = value;
22302
+ this.flashedKeys.push(key);
22303
+ this.dirty = true;
22304
+ }
22305
+ getFlash(key) {
22306
+ return this.previousFlash[key];
22307
+ }
22308
+ keep(keys) {
22309
+ for (const key of keys) {
22310
+ if (key in this.previousFlash) {
22311
+ this.flash(key, this.previousFlash[key]);
22312
+ }
22313
+ }
22314
+ }
22315
+ reflash() {
22316
+ for (const [key, value] of Object.entries(this.previousFlash)) {
22317
+ this.flash(key, value);
22318
+ }
22319
+ }
22320
+ async regenerate() {
22321
+ const oldId = this.sessionId;
22322
+ this.sessionId = generateSessionId();
22323
+ await this.store.set(this.sessionId, this.data);
22324
+ await this.store.destroy(oldId);
22325
+ return this.sessionId;
22326
+ }
22327
+ async invalidate() {
22328
+ const oldId = this.sessionId;
22329
+ this.sessionId = generateSessionId();
22330
+ this.data = { id: this.sessionId };
22331
+ await this.store.destroy(oldId);
22332
+ await this.store.set(this.sessionId, this.data);
22333
+ return this.sessionId;
22334
+ }
22335
+ async save() {
22336
+ if (this.data.flash) {
22337
+ const newFlash = {};
22338
+ for (const key of this.flashedKeys) {
22339
+ if (this.data.flash[key] !== undefined) {
22340
+ newFlash[key] = this.data.flash[key];
22341
+ }
22342
+ }
22343
+ this.data.flash = Object.keys(newFlash).length > 0 ? newFlash : undefined;
22344
+ }
22345
+ await this.store.set(this.sessionId, this.data);
22346
+ }
22347
+ async destroy() {
22348
+ await this.store.destroy(this.sessionId);
22349
+ this.data = {};
22350
+ }
22351
+ }
22352
+ function generateSessionId() {
22353
+ const bytes = new Uint8Array(32);
22354
+ crypto.getRandomValues(bytes);
22355
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
22356
+ }
22357
+
21921
22358
  // src/middleware/session.ts
21922
22359
  class Session {
21923
- static sessions = new Map;
22360
+ store;
22361
+ constructor(options) {
22362
+ this.store = options?.store || new MemorySessionStore;
22363
+ }
21924
22364
  async handle(req, next) {
21925
22365
  const sessionConfig = config3.server?.security?.auth?.session;
21926
- req.session = {};
21927
- const sessionId = req.cookies?.get(sessionConfig?.name || "session") || this.generateSessionId();
21928
- if (sessionId && Session.sessions.has(sessionId)) {
21929
- req.session = Session.sessions.get(sessionId);
21930
- }
22366
+ const cookieName = sessionConfig?.name || "session";
22367
+ let sessionId = req.cookies?.get(cookieName) || "";
22368
+ let isNewSession = false;
22369
+ if (!sessionId) {
22370
+ sessionId = generateSessionId();
22371
+ isNewSession = true;
22372
+ }
22373
+ let sessionData = isNewSession ? null : await this.store.get(sessionId);
22374
+ if (!sessionData) {
22375
+ sessionData = { id: sessionId };
22376
+ isNewSession = true;
22377
+ }
22378
+ const manager = new SessionManager(sessionId, sessionData, this.store);
22379
+ req.session = manager;
21931
22380
  const response = await next();
21932
- Session.sessions.set(sessionId, req.session);
22381
+ await manager.save();
21933
22382
  const cookieOptions = {
21934
22383
  maxAge: sessionConfig?.cookie?.maxAge || 86400000,
21935
22384
  path: sessionConfig?.cookie?.path || "/"
21936
22385
  };
21937
- if (sessionConfig?.cookie?.httpOnly) {
22386
+ if (sessionConfig?.cookie?.httpOnly !== false) {
21938
22387
  cookieOptions.httpOnly = true;
21939
22388
  }
21940
22389
  if (sessionConfig?.cookie?.secure) {
@@ -21947,25 +22396,12 @@ class Session {
21947
22396
  req._cookiesToSet = [];
21948
22397
  }
21949
22398
  req._cookiesToSet.push({
21950
- name: sessionConfig?.name || "session",
21951
- value: sessionId,
22399
+ name: cookieName,
22400
+ value: manager.id,
21952
22401
  options: cookieOptions
21953
22402
  });
21954
22403
  return response || new Response("Not Found", { status: 404 });
21955
22404
  }
21956
- parseCookies(req) {
21957
- const cookieHeader = req.headers.get("cookie");
21958
- if (!cookieHeader)
21959
- return {};
21960
- return cookieHeader.split(";").reduce((cookies, cookie) => {
21961
- const [name, value] = cookie.trim().split("=");
21962
- cookies[name] = value;
21963
- return cookies;
21964
- }, {});
21965
- }
21966
- generateSessionId() {
21967
- return Array.from({ length: 32 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
21968
- }
21969
22405
  }
21970
22406
 
21971
22407
  // src/middleware/content_security_policy.ts
@@ -22407,8 +22843,8 @@ class FileSecurity {
22407
22843
 
22408
22844
  // src/middleware/file_upload.ts
22409
22845
  import { randomUUID as randomUUID2 } from "crypto";
22410
- import { existsSync as existsSync9, mkdirSync as mkdirSync6, writeFileSync as writeFileSync8 } from "fs";
22411
- import { basename, extname, join as join4 } from "path";
22846
+ import { existsSync as existsSync11, mkdirSync as mkdirSync7, writeFileSync as writeFileSync9 } from "fs";
22847
+ import { basename, extname, join as join6 } from "path";
22412
22848
  class FileUpload {
22413
22849
  config;
22414
22850
  fileSecurity;
@@ -22429,8 +22865,8 @@ class FileUpload {
22429
22865
  maxFilenameLength: config4.maxFilenameLength ?? 255
22430
22866
  };
22431
22867
  this.fileSecurity = new FileSecurity(config4);
22432
- if (this.config.createDestination && !existsSync9(this.config.destination)) {
22433
- mkdirSync6(this.config.destination, { recursive: true });
22868
+ if (this.config.createDestination && !existsSync11(this.config.destination)) {
22869
+ mkdirSync7(this.config.destination, { recursive: true });
22434
22870
  }
22435
22871
  }
22436
22872
  async handle(req, next) {
@@ -22462,7 +22898,7 @@ class FileUpload {
22462
22898
  return this.createErrorResponse(`File extension ${fileExtension} not allowed. Allowed extensions: ${this.config.allowedExtensions.join(", ")}`, 415);
22463
22899
  }
22464
22900
  const filename = this.generateFilename(value.name);
22465
- const filePath = join4(this.config.destination, filename);
22901
+ const filePath = join6(this.config.destination, filename);
22466
22902
  const buffer = await value.arrayBuffer();
22467
22903
  const uploadedFile = {
22468
22904
  fieldName: key,
@@ -22477,7 +22913,7 @@ class FileUpload {
22477
22913
  if (!securityCheck.isValid) {
22478
22914
  return this.createErrorResponse(`Security validation failed: ${securityCheck.errors.join(", ")}`, 400);
22479
22915
  }
22480
- writeFileSync8(filePath, new Uint8Array(buffer));
22916
+ writeFileSync9(filePath, new Uint8Array(buffer));
22481
22917
  uploadedFiles.push(uploadedFile);
22482
22918
  } else {
22483
22919
  if (fields[key]) {
@@ -22540,7 +22976,7 @@ class FileUpload {
22540
22976
  function fileUpload(config4 = {}) {
22541
22977
  return new FileUpload(config4);
22542
22978
  }
22543
- function singleFileUpload(fieldName, config4 = {}) {
22979
+ function singleFileUpload(_fieldName, config4 = {}) {
22544
22980
  return new FileUpload({ ...config4, maxFiles: 1 });
22545
22981
  }
22546
22982
  function multipleFileUpload(maxFiles = 10, config4 = {}) {
@@ -23540,7 +23976,7 @@ class PerformanceDashboard {
23540
23976
  <html lang="en">
23541
23977
  <head>
23542
23978
  <meta charset="UTF-8">
23543
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
23979
+ <meta name='viewport' content='width=device-width, initial-scale=1.0'>
23544
23980
  <title>${this.options.title}</title>
23545
23981
  <style>
23546
23982
  * { margin: 0; padding: 0; box-sizing: border-box; }
@@ -23707,92 +24143,92 @@ class PerformanceDashboard {
23707
24143
  </style>
23708
24144
  </head>
23709
24145
  <body>
23710
- <div class="header">
24146
+ <div class='header'>
23711
24147
  <h1>${this.options.title}</h1>
23712
- <div class="status">
23713
- <div class="status-item">
23714
- <div class="status-value">${data.metrics.current.totalRequests}</div>
24148
+ <div class='status'>
24149
+ <div class='status-item'>
24150
+ <div class='status-value'>${data.metrics.current.totalRequests}</div>
23715
24151
  <div>Total Requests</div>
23716
24152
  </div>
23717
- <div class="status-item">
23718
- <div class="status-value">${Math.round(data.metrics.current.averageResponseTime)}ms</div>
24153
+ <div class='status-item'>
24154
+ <div class='status-value'>${Math.round(data.metrics.current.averageResponseTime)}ms</div>
23719
24155
  <div>Avg Response</div>
23720
24156
  </div>
23721
- <div class="status-item">
23722
- <div class="status-value">${Math.round(data.metrics.current.errorRate * 100)}%</div>
24157
+ <div class='status-item'>
24158
+ <div class='status-value'>${Math.round(data.metrics.current.errorRate * 100)}%</div>
23723
24159
  <div>Error Rate</div>
23724
24160
  </div>
23725
- <div class="status-item">
23726
- <div class="status-value">${Math.round(data.metrics.current.requestsPerSecond)}/s</div>
24161
+ <div class='status-item'>
24162
+ <div class='status-value'>${Math.round(data.metrics.current.requestsPerSecond)}/s</div>
23727
24163
  <div>Requests/sec</div>
23728
24164
  </div>
23729
24165
  </div>
23730
24166
  </div>
23731
24167
 
23732
- <div class="container">
24168
+ <div class='container'>
23733
24169
  ${this.options.features?.realTimeMetrics ? `
23734
- <div class="card">
24170
+ <div class='card'>
23735
24171
  <h2>Real-time Metrics</h2>
23736
- <div class="metric">
23737
- <span class="metric-label">Response Time</span>
23738
- <span class="metric-value">${Math.round(data.metrics.current.averageResponseTime)}ms</span>
24172
+ <div class='metric'>
24173
+ <span class='metric-label'>Response Time</span>
24174
+ <span class='metric-value'>${Math.round(data.metrics.current.averageResponseTime)}ms</span>
23739
24175
  </div>
23740
- <div class="metric">
23741
- <span class="metric-label">Memory Usage</span>
23742
- <span class="metric-value">${Math.round(data.metrics.current.memoryUsage / 1024 / 1024)}MB</span>
24176
+ <div class='metric'>
24177
+ <span class='metric-label'>Memory Usage</span>
24178
+ <span class='metric-value'>${Math.round(data.metrics.current.memoryUsage / 1024 / 1024)}MB</span>
23743
24179
  </div>
23744
- <div class="metric">
23745
- <span class="metric-label">CPU Usage</span>
23746
- <span class="metric-value">${Math.round(data.metrics.current.cpuUsage)}%</span>
24180
+ <div class='metric'>
24181
+ <span class='metric-label'>CPU Usage</span>
24182
+ <span class='metric-value'>${Math.round(data.metrics.current.cpuUsage)}%</span>
23747
24183
  </div>
23748
- <div class="metric">
23749
- <span class="metric-label">Requests/sec</span>
23750
- <span class="metric-value">${Math.round(data.metrics.current.requestsPerSecond)}</span>
24184
+ <div class='metric'>
24185
+ <span class='metric-label'>Requests/sec</span>
24186
+ <span class='metric-value'>${Math.round(data.metrics.current.requestsPerSecond)}</span>
23751
24187
  </div>
23752
- <div class="metric">
23753
- <span class="metric-label">Error Rate</span>
23754
- <span class="metric-value ${data.metrics.current.errorRate > 0.1 ? "critical" : data.metrics.current.errorRate > 0.05 ? "warning" : ""}">${Math.round(data.metrics.current.errorRate * 100)}%</span>
24188
+ <div class='metric'>
24189
+ <span class='metric-label'>Error Rate</span>
24190
+ <span class='metric-value ${data.metrics.current.errorRate > 0.1 ? "critical" : data.metrics.current.errorRate > 0.05 ? "warning" : ""}'>${Math.round(data.metrics.current.errorRate * 100)}%</span>
23755
24191
  </div>
23756
24192
  </div>
23757
24193
  ` : ""}
23758
24194
 
23759
24195
  ${this.options.features?.historicalCharts ? `
23760
- <div class="card">
24196
+ <div class='card'>
23761
24197
  <h2>Historical Performance</h2>
23762
- <div class="chart-container">
24198
+ <div class='chart-container'>
23763
24199
  Response Time Chart (${data.metrics.historical.length} data points)
23764
24200
  </div>
23765
24201
  </div>
23766
24202
  ` : ""}
23767
24203
 
23768
- <div class="card">
24204
+ <div class='card'>
23769
24205
  <h2>Request Distribution</h2>
23770
- <div class="distribution">
24206
+ <div class='distribution'>
23771
24207
  ${Object.entries(data.metrics.distribution.statusCodes).map(([code, count]) => `
23772
- <div class="distribution-item">
23773
- <div class="distribution-value">${count}</div>
23774
- <div class="distribution-label">HTTP ${code}</div>
24208
+ <div class='distribution-item'>
24209
+ <div class='distribution-value'>${count}</div>
24210
+ <div class='distribution-label'>HTTP ${code}</div>
23775
24211
  </div>
23776
24212
  `).join("")}
23777
24213
  </div>
23778
24214
  </div>
23779
24215
 
23780
- <div class="card">
24216
+ <div class='card'>
23781
24217
  <h2>Top Endpoints</h2>
23782
24218
  ${Object.entries(data.metrics.distribution.paths).sort(([, a], [, b]) => b - a).slice(0, 10).map(([path, count]) => `
23783
- <div class="metric">
23784
- <span class="metric-label">${path}</span>
23785
- <span class="metric-value">${count}</span>
24219
+ <div class='metric'>
24220
+ <span class='metric-label'>${path}</span>
24221
+ <span class='metric-value'>${count}</span>
23786
24222
  </div>
23787
24223
  `).join("")}
23788
24224
  </div>
23789
24225
 
23790
24226
  ${this.options.features?.alertsPanel ? `
23791
- <div class="card">
24227
+ <div class='card'>
23792
24228
  <h2>Active Alerts</h2>
23793
24229
  ${data.alerts.length === 0 ? "<p>No active alerts</p>" : ""}
23794
24230
  ${data.alerts.filter((alert) => !alert.resolved).map((alert) => `
23795
- <div class="alert ${alert.type}">
24231
+ <div class='alert ${alert.type}'>
23796
24232
  <strong>${alert.type.toUpperCase()}:</strong> ${alert.message}
23797
24233
  <br><small>${new Date(alert.timestamp).toLocaleString()}</small>
23798
24234
  </div>
@@ -23801,15 +24237,15 @@ class PerformanceDashboard {
23801
24237
  ` : ""}
23802
24238
 
23803
24239
  ${this.options.features?.tracingView ? `
23804
- <div class="card">
24240
+ <div class='card'>
23805
24241
  <h2>Recent Traces</h2>
23806
24242
  ${data.traces.slice(0, 10).map((trace) => `
23807
- <div class="trace">
23808
- <div class="trace-header">
23809
- <span class="trace-operation">${trace.operationName}</span>
23810
- <span class="trace-duration">${Math.round((trace.duration || 0) * 100) / 100}ms</span>
24243
+ <div class='trace'>
24244
+ <div class='trace-header'>
24245
+ <span class='trace-operation'>${trace.operationName}</span>
24246
+ <span class='trace-duration'>${Math.round((trace.duration || 0) * 100) / 100}ms</span>
23811
24247
  </div>
23812
- <div class="trace-details">
24248
+ <div class='trace-details'>
23813
24249
  Trace ID: ${trace.traceId} | Status: ${trace.status}
23814
24250
  ${trace.error ? ` | Error: ${trace.error}` : ""}
23815
24251
  </div>
@@ -23819,33 +24255,33 @@ class PerformanceDashboard {
23819
24255
  ` : ""}
23820
24256
 
23821
24257
  ${this.options.features?.systemMetrics ? `
23822
- <div class="card">
24258
+ <div class='card'>
23823
24259
  <h2>System Information</h2>
23824
- <div class="metric">
23825
- <span class="metric-label">Uptime</span>
23826
- <span class="metric-value">${Math.round(data.system.uptime / 1000 / 60)} minutes</span>
24260
+ <div class='metric'>
24261
+ <span class='metric-label'>Uptime</span>
24262
+ <span class='metric-value'>${Math.round(data.system.uptime / 1000 / 60)} minutes</span>
23827
24263
  </div>
23828
- <div class="metric">
23829
- <span class="metric-label">Node.js</span>
23830
- <span class="metric-value">${data.system.nodeVersion}</span>
24264
+ <div class='metric'>
24265
+ <span class='metric-label'>Node.js</span>
24266
+ <span class='metric-value'>${data.system.nodeVersion}</span>
23831
24267
  </div>
23832
- <div class="metric">
23833
- <span class="metric-label">Platform</span>
23834
- <span class="metric-value">${data.system.platform} ${data.system.arch}</span>
24268
+ <div class='metric'>
24269
+ <span class='metric-label'>Platform</span>
24270
+ <span class='metric-value'>${data.system.platform} ${data.system.arch}</span>
23835
24271
  </div>
23836
- <div class="metric">
23837
- <span class="metric-label">Heap Used</span>
23838
- <span class="metric-value">${Math.round(data.system.memory.heapUsed / 1024 / 1024)}MB</span>
24272
+ <div class='metric'>
24273
+ <span class='metric-label'>Heap Used</span>
24274
+ <span class='metric-value'>${Math.round(data.system.memory.heapUsed / 1024 / 1024)}MB</span>
23839
24275
  </div>
23840
- <div class="metric">
23841
- <span class="metric-label">RSS</span>
23842
- <span class="metric-value">${Math.round(data.system.memory.rss / 1024 / 1024)}MB</span>
24276
+ <div class='metric'>
24277
+ <span class='metric-label'>RSS</span>
24278
+ <span class='metric-value'>${Math.round(data.system.memory.rss / 1024 / 1024)}MB</span>
23843
24279
  </div>
23844
24280
  </div>
23845
24281
  ` : ""}
23846
24282
  </div>
23847
24283
 
23848
- <div class="refresh-indicator" id="refreshIndicator">Updated</div>
24284
+ <div class='refresh-indicator' id='refreshIndicator'>Updated</div>
23849
24285
 
23850
24286
  <script>
23851
24287
  let refreshInterval;
@@ -23863,7 +24299,8 @@ class PerformanceDashboard {
23863
24299
  // For now, we'll just refresh the page
23864
24300
  setTimeout(() => window.location.reload(), ${this.options.refreshInterval});
23865
24301
  }
23866
- } catch (error) {
24302
+ }
24303
+ catch (error) {
23867
24304
  console.error('Failed to refresh data:', error);
23868
24305
  }
23869
24306
  }, ${this.options.refreshInterval});
@@ -23876,7 +24313,8 @@ class PerformanceDashboard {
23876
24313
  document.addEventListener('visibilitychange', () => {
23877
24314
  if (document.hidden) {
23878
24315
  clearInterval(refreshInterval);
23879
- } else {
24316
+ }
24317
+ else {
23880
24318
  startAutoRefresh();
23881
24319
  }
23882
24320
  });
@@ -25445,4 +25883,4 @@ var middleware = new Proxy({}, {
25445
25883
  }
25446
25884
  });
25447
25885
 
25448
- export { __export, __require, defaultConfig3 as defaultConfig, getConfig, config3 as config, extractBasicAuth, extractBearerToken, extractApiKey, basicAuth, bearerAuth, jwtAuth, apiKeyAuth, oauth2Auth, Cors, Csrf, JsonBody, RateLimit, rateLimit, RequestId, SignatureError, InMemoryNonceStore, RequestSigning, requestSigning, signRequest, verifySignature, Session, ContentSecurityPolicy, contentSecurityPolicy, DDoSProtection, ddosProtection, FileSecurity, FileUpload, fileUpload, singleFileUpload, multipleFileUpload, imageUpload, documentUpload, Helmet, InputValidation, inputValidation, PerformanceAlerting, performanceAlerting, PerformanceDashboard, performanceDashboard, PerformanceMonitor2 as PerformanceMonitor, performanceMonitor, RequestTracer, requestTracer, Security, security, SecuritySuite, securitySuite, cors, jsonBody, requestId, session, csrf, auth, middleware };
25886
+ export { __export, __require, defaultConfig3 as defaultConfig, getConfig, config3 as config, extractBasicAuth, extractBearerToken, extractApiKey, basicAuth, bearerAuth, jwtAuth, apiKeyAuth, oauth2Auth, Cors, Csrf, JsonBody, RateLimit, rateLimit, RequestId, SignatureError, InMemoryNonceStore, RequestSigning, requestSigning, signRequest, verifySignature, MemorySessionStore, FileSessionStore, RedisSessionStore, DatabaseSessionStore, createSessionStore, SessionManager, generateSessionId, Session, ContentSecurityPolicy, contentSecurityPolicy, DDoSProtection, ddosProtection, FileSecurity, FileUpload, fileUpload, singleFileUpload, multipleFileUpload, imageUpload, documentUpload, Helmet, InputValidation, inputValidation, PerformanceAlerting, performanceAlerting, PerformanceDashboard, performanceDashboard, PerformanceMonitor2 as PerformanceMonitor, performanceMonitor, RequestTracer, requestTracer, Security, security, SecuritySuite, securitySuite, cors, jsonBody, requestId, session, csrf, auth, middleware };