vector-framework 0.9.6 → 0.9.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/dist/cli.js CHANGED
@@ -28,210 +28,6 @@ var __export = (target, all) => {
28
28
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
29
  var __require = import.meta.require;
30
30
 
31
- // src/auth/protected.ts
32
- class AuthManager {
33
- protectedHandler = null;
34
- setProtectedHandler(handler) {
35
- this.protectedHandler = handler;
36
- }
37
- async authenticate(request) {
38
- if (!this.protectedHandler) {
39
- throw new Error("Protected handler not configured. Use vector.protected() to set authentication handler.");
40
- }
41
- try {
42
- const authUser = await this.protectedHandler(request);
43
- request.authUser = authUser;
44
- return authUser;
45
- } catch (error) {
46
- throw new Error(`Authentication failed: ${error instanceof Error ? error.message : String(error)}`);
47
- }
48
- }
49
- isAuthenticated(request) {
50
- return !!request.authUser;
51
- }
52
- getUser(request) {
53
- return request.authUser || null;
54
- }
55
- }
56
-
57
- // src/constants/index.ts
58
- var HTTP_STATUS, DEFAULT_CONFIG, CONTENT_TYPES;
59
- var init_constants = __esm(() => {
60
- HTTP_STATUS = {
61
- OK: 200,
62
- CREATED: 201,
63
- ACCEPTED: 202,
64
- NON_AUTHORITATIVE_INFORMATION: 203,
65
- NO_CONTENT: 204,
66
- RESET_CONTENT: 205,
67
- PARTIAL_CONTENT: 206,
68
- MULTI_STATUS: 207,
69
- ALREADY_REPORTED: 208,
70
- IM_USED: 226,
71
- MULTIPLE_CHOICES: 300,
72
- MOVED_PERMANENTLY: 301,
73
- FOUND: 302,
74
- SEE_OTHER: 303,
75
- NOT_MODIFIED: 304,
76
- USE_PROXY: 305,
77
- TEMPORARY_REDIRECT: 307,
78
- PERMANENT_REDIRECT: 308,
79
- BAD_REQUEST: 400,
80
- UNAUTHORIZED: 401,
81
- PAYMENT_REQUIRED: 402,
82
- FORBIDDEN: 403,
83
- NOT_FOUND: 404,
84
- METHOD_NOT_ALLOWED: 405,
85
- NOT_ACCEPTABLE: 406,
86
- PROXY_AUTHENTICATION_REQUIRED: 407,
87
- REQUEST_TIMEOUT: 408,
88
- CONFLICT: 409,
89
- GONE: 410,
90
- LENGTH_REQUIRED: 411,
91
- PRECONDITION_FAILED: 412,
92
- PAYLOAD_TOO_LARGE: 413,
93
- URI_TOO_LONG: 414,
94
- UNSUPPORTED_MEDIA_TYPE: 415,
95
- RANGE_NOT_SATISFIABLE: 416,
96
- EXPECTATION_FAILED: 417,
97
- IM_A_TEAPOT: 418,
98
- MISDIRECTED_REQUEST: 421,
99
- UNPROCESSABLE_ENTITY: 422,
100
- LOCKED: 423,
101
- FAILED_DEPENDENCY: 424,
102
- TOO_EARLY: 425,
103
- UPGRADE_REQUIRED: 426,
104
- PRECONDITION_REQUIRED: 428,
105
- TOO_MANY_REQUESTS: 429,
106
- REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
107
- UNAVAILABLE_FOR_LEGAL_REASONS: 451,
108
- INTERNAL_SERVER_ERROR: 500,
109
- NOT_IMPLEMENTED: 501,
110
- BAD_GATEWAY: 502,
111
- SERVICE_UNAVAILABLE: 503,
112
- GATEWAY_TIMEOUT: 504,
113
- HTTP_VERSION_NOT_SUPPORTED: 505,
114
- VARIANT_ALSO_NEGOTIATES: 506,
115
- INSUFFICIENT_STORAGE: 507,
116
- LOOP_DETECTED: 508,
117
- NOT_EXTENDED: 510,
118
- NETWORK_AUTHENTICATION_REQUIRED: 511
119
- };
120
- DEFAULT_CONFIG = {
121
- PORT: 3000,
122
- HOSTNAME: "localhost",
123
- ROUTES_DIR: "./routes",
124
- CACHE_TTL: 0,
125
- CORS_MAX_AGE: 86400
126
- };
127
- CONTENT_TYPES = {
128
- JSON: "application/json",
129
- TEXT: "text/plain",
130
- HTML: "text/html",
131
- FORM_URLENCODED: "application/x-www-form-urlencoded",
132
- MULTIPART: "multipart/form-data"
133
- };
134
- });
135
-
136
- // src/cache/manager.ts
137
- class CacheManager {
138
- cacheHandler = null;
139
- memoryCache = new Map;
140
- cleanupInterval = null;
141
- setCacheHandler(handler) {
142
- this.cacheHandler = handler;
143
- }
144
- async get(key, factory, ttl = DEFAULT_CONFIG.CACHE_TTL) {
145
- if (ttl <= 0) {
146
- return factory();
147
- }
148
- if (this.cacheHandler) {
149
- return this.cacheHandler(key, factory, ttl);
150
- }
151
- return this.getFromMemoryCache(key, factory, ttl);
152
- }
153
- async getFromMemoryCache(key, factory, ttl) {
154
- const now = Date.now();
155
- const cached = this.memoryCache.get(key);
156
- if (this.isCacheValid(cached, now)) {
157
- return cached.value;
158
- }
159
- const value = await factory();
160
- this.setInMemoryCache(key, value, ttl);
161
- return value;
162
- }
163
- isCacheValid(entry, now) {
164
- return entry !== undefined && entry.expires > now;
165
- }
166
- setInMemoryCache(key, value, ttl) {
167
- const expires = Date.now() + ttl * 1000;
168
- this.memoryCache.set(key, { value, expires });
169
- this.scheduleCleanup();
170
- }
171
- scheduleCleanup() {
172
- if (this.cleanupInterval)
173
- return;
174
- this.cleanupInterval = setInterval(() => {
175
- this.cleanupExpired();
176
- }, 60000);
177
- }
178
- cleanupExpired() {
179
- const now = Date.now();
180
- for (const [key, entry] of this.memoryCache.entries()) {
181
- if (entry.expires <= now) {
182
- this.memoryCache.delete(key);
183
- }
184
- }
185
- if (this.memoryCache.size === 0 && this.cleanupInterval) {
186
- clearInterval(this.cleanupInterval);
187
- this.cleanupInterval = null;
188
- }
189
- }
190
- clear() {
191
- this.memoryCache.clear();
192
- if (this.cleanupInterval) {
193
- clearInterval(this.cleanupInterval);
194
- this.cleanupInterval = null;
195
- }
196
- }
197
- async set(key, value, ttl = DEFAULT_CONFIG.CACHE_TTL) {
198
- if (ttl <= 0) {
199
- return;
200
- }
201
- if (this.cacheHandler) {
202
- await this.cacheHandler(key, async () => value, ttl);
203
- return;
204
- }
205
- this.setInMemoryCache(key, value, ttl);
206
- }
207
- delete(key) {
208
- return this.memoryCache.delete(key);
209
- }
210
- has(key) {
211
- const entry = this.memoryCache.get(key);
212
- if (!entry)
213
- return false;
214
- if (entry.expires <= Date.now()) {
215
- this.memoryCache.delete(key);
216
- return false;
217
- }
218
- return true;
219
- }
220
- generateKey(request, options) {
221
- const url = new URL(request.url);
222
- const parts = [
223
- request.method,
224
- url.pathname,
225
- url.search,
226
- options?.authUser?.id || "anonymous"
227
- ];
228
- return parts.join(":");
229
- }
230
- }
231
- var init_manager = __esm(() => {
232
- init_constants();
233
- });
234
-
235
31
  // src/dev/route-generator.ts
236
32
  var exports_route_generator = {};
237
33
  __export(exports_route_generator, {
@@ -410,6 +206,212 @@ class RouteScanner {
410
206
  }
411
207
  var init_route_scanner = () => {};
412
208
 
209
+ // src/cli/index.ts
210
+ import { watch } from "fs";
211
+ import { parseArgs } from "util";
212
+
213
+ // src/auth/protected.ts
214
+ class AuthManager {
215
+ protectedHandler = null;
216
+ setProtectedHandler(handler) {
217
+ this.protectedHandler = handler;
218
+ }
219
+ async authenticate(request) {
220
+ if (!this.protectedHandler) {
221
+ throw new Error("Protected handler not configured. Use vector.protected() to set authentication handler.");
222
+ }
223
+ try {
224
+ const authUser = await this.protectedHandler(request);
225
+ request.authUser = authUser;
226
+ return authUser;
227
+ } catch (error) {
228
+ throw new Error(`Authentication failed: ${error instanceof Error ? error.message : String(error)}`);
229
+ }
230
+ }
231
+ isAuthenticated(request) {
232
+ return !!request.authUser;
233
+ }
234
+ getUser(request) {
235
+ return request.authUser || null;
236
+ }
237
+ }
238
+
239
+ // src/constants/index.ts
240
+ var HTTP_STATUS = {
241
+ OK: 200,
242
+ CREATED: 201,
243
+ ACCEPTED: 202,
244
+ NON_AUTHORITATIVE_INFORMATION: 203,
245
+ NO_CONTENT: 204,
246
+ RESET_CONTENT: 205,
247
+ PARTIAL_CONTENT: 206,
248
+ MULTI_STATUS: 207,
249
+ ALREADY_REPORTED: 208,
250
+ IM_USED: 226,
251
+ MULTIPLE_CHOICES: 300,
252
+ MOVED_PERMANENTLY: 301,
253
+ FOUND: 302,
254
+ SEE_OTHER: 303,
255
+ NOT_MODIFIED: 304,
256
+ USE_PROXY: 305,
257
+ TEMPORARY_REDIRECT: 307,
258
+ PERMANENT_REDIRECT: 308,
259
+ BAD_REQUEST: 400,
260
+ UNAUTHORIZED: 401,
261
+ PAYMENT_REQUIRED: 402,
262
+ FORBIDDEN: 403,
263
+ NOT_FOUND: 404,
264
+ METHOD_NOT_ALLOWED: 405,
265
+ NOT_ACCEPTABLE: 406,
266
+ PROXY_AUTHENTICATION_REQUIRED: 407,
267
+ REQUEST_TIMEOUT: 408,
268
+ CONFLICT: 409,
269
+ GONE: 410,
270
+ LENGTH_REQUIRED: 411,
271
+ PRECONDITION_FAILED: 412,
272
+ PAYLOAD_TOO_LARGE: 413,
273
+ URI_TOO_LONG: 414,
274
+ UNSUPPORTED_MEDIA_TYPE: 415,
275
+ RANGE_NOT_SATISFIABLE: 416,
276
+ EXPECTATION_FAILED: 417,
277
+ IM_A_TEAPOT: 418,
278
+ MISDIRECTED_REQUEST: 421,
279
+ UNPROCESSABLE_ENTITY: 422,
280
+ LOCKED: 423,
281
+ FAILED_DEPENDENCY: 424,
282
+ TOO_EARLY: 425,
283
+ UPGRADE_REQUIRED: 426,
284
+ PRECONDITION_REQUIRED: 428,
285
+ TOO_MANY_REQUESTS: 429,
286
+ REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
287
+ UNAVAILABLE_FOR_LEGAL_REASONS: 451,
288
+ INTERNAL_SERVER_ERROR: 500,
289
+ NOT_IMPLEMENTED: 501,
290
+ BAD_GATEWAY: 502,
291
+ SERVICE_UNAVAILABLE: 503,
292
+ GATEWAY_TIMEOUT: 504,
293
+ HTTP_VERSION_NOT_SUPPORTED: 505,
294
+ VARIANT_ALSO_NEGOTIATES: 506,
295
+ INSUFFICIENT_STORAGE: 507,
296
+ LOOP_DETECTED: 508,
297
+ NOT_EXTENDED: 510,
298
+ NETWORK_AUTHENTICATION_REQUIRED: 511
299
+ };
300
+ var DEFAULT_CONFIG = {
301
+ PORT: 3000,
302
+ HOSTNAME: "localhost",
303
+ ROUTES_DIR: "./routes",
304
+ CACHE_TTL: 0,
305
+ CORS_MAX_AGE: 86400
306
+ };
307
+ var CONTENT_TYPES = {
308
+ JSON: "application/json",
309
+ TEXT: "text/plain",
310
+ HTML: "text/html",
311
+ FORM_URLENCODED: "application/x-www-form-urlencoded",
312
+ MULTIPART: "multipart/form-data"
313
+ };
314
+
315
+ // src/cache/manager.ts
316
+ class CacheManager {
317
+ cacheHandler = null;
318
+ memoryCache = new Map;
319
+ cleanupInterval = null;
320
+ setCacheHandler(handler) {
321
+ this.cacheHandler = handler;
322
+ }
323
+ async get(key, factory, ttl = DEFAULT_CONFIG.CACHE_TTL) {
324
+ if (ttl <= 0) {
325
+ return factory();
326
+ }
327
+ if (this.cacheHandler) {
328
+ return this.cacheHandler(key, factory, ttl);
329
+ }
330
+ return this.getFromMemoryCache(key, factory, ttl);
331
+ }
332
+ async getFromMemoryCache(key, factory, ttl) {
333
+ const now = Date.now();
334
+ const cached = this.memoryCache.get(key);
335
+ if (this.isCacheValid(cached, now)) {
336
+ return cached.value;
337
+ }
338
+ const value = await factory();
339
+ this.setInMemoryCache(key, value, ttl);
340
+ return value;
341
+ }
342
+ isCacheValid(entry, now) {
343
+ return entry !== undefined && entry.expires > now;
344
+ }
345
+ setInMemoryCache(key, value, ttl) {
346
+ const expires = Date.now() + ttl * 1000;
347
+ this.memoryCache.set(key, { value, expires });
348
+ this.scheduleCleanup();
349
+ }
350
+ scheduleCleanup() {
351
+ if (this.cleanupInterval)
352
+ return;
353
+ this.cleanupInterval = setInterval(() => {
354
+ this.cleanupExpired();
355
+ }, 60000);
356
+ }
357
+ cleanupExpired() {
358
+ const now = Date.now();
359
+ for (const [key, entry] of this.memoryCache.entries()) {
360
+ if (entry.expires <= now) {
361
+ this.memoryCache.delete(key);
362
+ }
363
+ }
364
+ if (this.memoryCache.size === 0 && this.cleanupInterval) {
365
+ clearInterval(this.cleanupInterval);
366
+ this.cleanupInterval = null;
367
+ }
368
+ }
369
+ clear() {
370
+ this.memoryCache.clear();
371
+ if (this.cleanupInterval) {
372
+ clearInterval(this.cleanupInterval);
373
+ this.cleanupInterval = null;
374
+ }
375
+ }
376
+ async set(key, value, ttl = DEFAULT_CONFIG.CACHE_TTL) {
377
+ if (ttl <= 0) {
378
+ return;
379
+ }
380
+ if (this.cacheHandler) {
381
+ await this.cacheHandler(key, async () => value, ttl);
382
+ return;
383
+ }
384
+ this.setInMemoryCache(key, value, ttl);
385
+ }
386
+ delete(key) {
387
+ return this.memoryCache.delete(key);
388
+ }
389
+ has(key) {
390
+ const entry = this.memoryCache.get(key);
391
+ if (!entry)
392
+ return false;
393
+ if (entry.expires <= Date.now()) {
394
+ this.memoryCache.delete(key);
395
+ return false;
396
+ }
397
+ return true;
398
+ }
399
+ generateKey(request, options) {
400
+ const url = new URL(request.url);
401
+ const parts = [
402
+ request.method,
403
+ url.pathname,
404
+ url.search,
405
+ options?.authUser?.id || "anonymous"
406
+ ];
407
+ return parts.join(":");
408
+ }
409
+ }
410
+
411
+ // src/core/vector.ts
412
+ init_route_generator();
413
+ init_route_scanner();
414
+
413
415
  // src/middleware/manager.ts
414
416
  class MiddlewareManager {
415
417
  beforeHandlers = [];
@@ -461,7 +463,17 @@ var r = (e = "text/plain; charset=utf-8", t) => (r2, o = {}) => {
461
463
  return r2;
462
464
  const a = new Response(t?.(r2) ?? r2, o.url ? undefined : o);
463
465
  return a.headers.set("content-type", e), a;
464
- }, o, p, f, u, h, g, y = (e = {}) => {
466
+ };
467
+ var o = r("application/json; charset=utf-8", JSON.stringify);
468
+ var p = r("text/plain; charset=utf-8", String);
469
+ var f = r("text/html");
470
+ var u = r("image/jpeg");
471
+ var h = r("image/png");
472
+ var g = r("image/webp");
473
+ var w = (e) => {
474
+ e.cookies = (e.headers.get("Cookie") || "").split(/;\s*/).map((e2) => e2.split(/=(.+)/)).reduce((e2, [t, r2]) => r2 ? (e2[t] = r2, e2) : e2, {});
475
+ };
476
+ var y = (e = {}) => {
465
477
  const { origin: t = "*", credentials: r2 = false, allowMethods: o2 = "*", allowHeaders: a, exposeHeaders: s, maxAge: c } = e, n = (e2) => {
466
478
  const o3 = e2?.headers.get("origin");
467
479
  return t === true ? o3 : t instanceof RegExp ? t.test(o3) ? o3 : undefined : Array.isArray(t) ? t.includes(o3) ? o3 : undefined : t instanceof Function ? t(o3) : t == "*" && r2 ? o3 : t;
@@ -477,16 +489,16 @@ var r = (e = "text/plain; charset=utf-8", t) => (r2, o = {}) => {
477
489
  }
478
490
  } };
479
491
  };
480
- var init_itty_router = __esm(() => {
481
- o = r("application/json; charset=utf-8", JSON.stringify);
482
- p = r("text/plain; charset=utf-8", String);
483
- f = r("text/html");
484
- u = r("image/jpeg");
485
- h = r("image/png");
486
- g = r("image/webp");
487
- });
488
492
 
489
493
  // src/http.ts
494
+ var { preflight, corsify } = y({
495
+ origin: "*",
496
+ credentials: true,
497
+ allowHeaders: "Content-Type, Authorization",
498
+ allowMethods: "GET, POST, PUT, PATCH, DELETE, OPTIONS",
499
+ exposeHeaders: "Authorization",
500
+ maxAge: 86400
501
+ });
490
502
  function stringifyData(data) {
491
503
  return JSON.stringify(data ?? null, (_key, value) => typeof value === "bigint" ? value.toString() : value);
492
504
  }
@@ -499,6 +511,51 @@ function createErrorResponse(code, message, contentType) {
499
511
  };
500
512
  return createResponse(code, errorBody, contentType);
501
513
  }
514
+ var APIError = {
515
+ badRequest: (msg = "Bad Request", contentType) => createErrorResponse(HTTP_STATUS.BAD_REQUEST, msg, contentType),
516
+ unauthorized: (msg = "Unauthorized", contentType) => createErrorResponse(HTTP_STATUS.UNAUTHORIZED, msg, contentType),
517
+ paymentRequired: (msg = "Payment Required", contentType) => createErrorResponse(402, msg, contentType),
518
+ forbidden: (msg = "Forbidden", contentType) => createErrorResponse(HTTP_STATUS.FORBIDDEN, msg, contentType),
519
+ notFound: (msg = "Not Found", contentType) => createErrorResponse(HTTP_STATUS.NOT_FOUND, msg, contentType),
520
+ methodNotAllowed: (msg = "Method Not Allowed", contentType) => createErrorResponse(405, msg, contentType),
521
+ notAcceptable: (msg = "Not Acceptable", contentType) => createErrorResponse(406, msg, contentType),
522
+ requestTimeout: (msg = "Request Timeout", contentType) => createErrorResponse(408, msg, contentType),
523
+ conflict: (msg = "Conflict", contentType) => createErrorResponse(HTTP_STATUS.CONFLICT, msg, contentType),
524
+ gone: (msg = "Gone", contentType) => createErrorResponse(410, msg, contentType),
525
+ lengthRequired: (msg = "Length Required", contentType) => createErrorResponse(411, msg, contentType),
526
+ preconditionFailed: (msg = "Precondition Failed", contentType) => createErrorResponse(412, msg, contentType),
527
+ payloadTooLarge: (msg = "Payload Too Large", contentType) => createErrorResponse(413, msg, contentType),
528
+ uriTooLong: (msg = "URI Too Long", contentType) => createErrorResponse(414, msg, contentType),
529
+ unsupportedMediaType: (msg = "Unsupported Media Type", contentType) => createErrorResponse(415, msg, contentType),
530
+ rangeNotSatisfiable: (msg = "Range Not Satisfiable", contentType) => createErrorResponse(416, msg, contentType),
531
+ expectationFailed: (msg = "Expectation Failed", contentType) => createErrorResponse(417, msg, contentType),
532
+ imATeapot: (msg = "I'm a teapot", contentType) => createErrorResponse(418, msg, contentType),
533
+ misdirectedRequest: (msg = "Misdirected Request", contentType) => createErrorResponse(421, msg, contentType),
534
+ unprocessableEntity: (msg = "Unprocessable Entity", contentType) => createErrorResponse(HTTP_STATUS.UNPROCESSABLE_ENTITY, msg, contentType),
535
+ locked: (msg = "Locked", contentType) => createErrorResponse(423, msg, contentType),
536
+ failedDependency: (msg = "Failed Dependency", contentType) => createErrorResponse(424, msg, contentType),
537
+ tooEarly: (msg = "Too Early", contentType) => createErrorResponse(425, msg, contentType),
538
+ upgradeRequired: (msg = "Upgrade Required", contentType) => createErrorResponse(426, msg, contentType),
539
+ preconditionRequired: (msg = "Precondition Required", contentType) => createErrorResponse(428, msg, contentType),
540
+ tooManyRequests: (msg = "Too Many Requests", contentType) => createErrorResponse(429, msg, contentType),
541
+ requestHeaderFieldsTooLarge: (msg = "Request Header Fields Too Large", contentType) => createErrorResponse(431, msg, contentType),
542
+ unavailableForLegalReasons: (msg = "Unavailable For Legal Reasons", contentType) => createErrorResponse(451, msg, contentType),
543
+ internalServerError: (msg = "Internal Server Error", contentType) => createErrorResponse(HTTP_STATUS.INTERNAL_SERVER_ERROR, msg, contentType),
544
+ notImplemented: (msg = "Not Implemented", contentType) => createErrorResponse(501, msg, contentType),
545
+ badGateway: (msg = "Bad Gateway", contentType) => createErrorResponse(502, msg, contentType),
546
+ serviceUnavailable: (msg = "Service Unavailable", contentType) => createErrorResponse(503, msg, contentType),
547
+ gatewayTimeout: (msg = "Gateway Timeout", contentType) => createErrorResponse(504, msg, contentType),
548
+ httpVersionNotSupported: (msg = "HTTP Version Not Supported", contentType) => createErrorResponse(505, msg, contentType),
549
+ variantAlsoNegotiates: (msg = "Variant Also Negotiates", contentType) => createErrorResponse(506, msg, contentType),
550
+ insufficientStorage: (msg = "Insufficient Storage", contentType) => createErrorResponse(507, msg, contentType),
551
+ loopDetected: (msg = "Loop Detected", contentType) => createErrorResponse(508, msg, contentType),
552
+ notExtended: (msg = "Not Extended", contentType) => createErrorResponse(510, msg, contentType),
553
+ networkAuthenticationRequired: (msg = "Network Authentication Required", contentType) => createErrorResponse(511, msg, contentType),
554
+ invalidArgument: (msg = "Invalid Argument", contentType) => createErrorResponse(HTTP_STATUS.UNPROCESSABLE_ENTITY, msg, contentType),
555
+ rateLimitExceeded: (msg = "Rate Limit Exceeded", contentType) => createErrorResponse(429, msg, contentType),
556
+ maintenance: (msg = "Service Under Maintenance", contentType) => createErrorResponse(503, msg, contentType),
557
+ custom: (statusCode, msg, contentType) => createErrorResponse(statusCode, msg, contentType)
558
+ };
502
559
  function createResponse(statusCode, data, contentType = CONTENT_TYPES.JSON) {
503
560
  const body = contentType === CONTENT_TYPES.JSON ? stringifyData(data) : data;
504
561
  return new Response(body, {
@@ -506,64 +563,6 @@ function createResponse(statusCode, data, contentType = CONTENT_TYPES.JSON) {
506
563
  headers: { "content-type": contentType }
507
564
  });
508
565
  }
509
- var preflight, corsify, APIError;
510
- var init_http = __esm(() => {
511
- init_itty_router();
512
- init_constants();
513
- ({ preflight, corsify } = y({
514
- origin: "*",
515
- credentials: true,
516
- allowHeaders: "Content-Type, Authorization",
517
- allowMethods: "GET, POST, PUT, PATCH, DELETE, OPTIONS",
518
- exposeHeaders: "Authorization",
519
- maxAge: 86400
520
- }));
521
- APIError = {
522
- badRequest: (msg = "Bad Request", contentType) => createErrorResponse(HTTP_STATUS.BAD_REQUEST, msg, contentType),
523
- unauthorized: (msg = "Unauthorized", contentType) => createErrorResponse(HTTP_STATUS.UNAUTHORIZED, msg, contentType),
524
- paymentRequired: (msg = "Payment Required", contentType) => createErrorResponse(402, msg, contentType),
525
- forbidden: (msg = "Forbidden", contentType) => createErrorResponse(HTTP_STATUS.FORBIDDEN, msg, contentType),
526
- notFound: (msg = "Not Found", contentType) => createErrorResponse(HTTP_STATUS.NOT_FOUND, msg, contentType),
527
- methodNotAllowed: (msg = "Method Not Allowed", contentType) => createErrorResponse(405, msg, contentType),
528
- notAcceptable: (msg = "Not Acceptable", contentType) => createErrorResponse(406, msg, contentType),
529
- requestTimeout: (msg = "Request Timeout", contentType) => createErrorResponse(408, msg, contentType),
530
- conflict: (msg = "Conflict", contentType) => createErrorResponse(HTTP_STATUS.CONFLICT, msg, contentType),
531
- gone: (msg = "Gone", contentType) => createErrorResponse(410, msg, contentType),
532
- lengthRequired: (msg = "Length Required", contentType) => createErrorResponse(411, msg, contentType),
533
- preconditionFailed: (msg = "Precondition Failed", contentType) => createErrorResponse(412, msg, contentType),
534
- payloadTooLarge: (msg = "Payload Too Large", contentType) => createErrorResponse(413, msg, contentType),
535
- uriTooLong: (msg = "URI Too Long", contentType) => createErrorResponse(414, msg, contentType),
536
- unsupportedMediaType: (msg = "Unsupported Media Type", contentType) => createErrorResponse(415, msg, contentType),
537
- rangeNotSatisfiable: (msg = "Range Not Satisfiable", contentType) => createErrorResponse(416, msg, contentType),
538
- expectationFailed: (msg = "Expectation Failed", contentType) => createErrorResponse(417, msg, contentType),
539
- imATeapot: (msg = "I'm a teapot", contentType) => createErrorResponse(418, msg, contentType),
540
- misdirectedRequest: (msg = "Misdirected Request", contentType) => createErrorResponse(421, msg, contentType),
541
- unprocessableEntity: (msg = "Unprocessable Entity", contentType) => createErrorResponse(HTTP_STATUS.UNPROCESSABLE_ENTITY, msg, contentType),
542
- locked: (msg = "Locked", contentType) => createErrorResponse(423, msg, contentType),
543
- failedDependency: (msg = "Failed Dependency", contentType) => createErrorResponse(424, msg, contentType),
544
- tooEarly: (msg = "Too Early", contentType) => createErrorResponse(425, msg, contentType),
545
- upgradeRequired: (msg = "Upgrade Required", contentType) => createErrorResponse(426, msg, contentType),
546
- preconditionRequired: (msg = "Precondition Required", contentType) => createErrorResponse(428, msg, contentType),
547
- tooManyRequests: (msg = "Too Many Requests", contentType) => createErrorResponse(429, msg, contentType),
548
- requestHeaderFieldsTooLarge: (msg = "Request Header Fields Too Large", contentType) => createErrorResponse(431, msg, contentType),
549
- unavailableForLegalReasons: (msg = "Unavailable For Legal Reasons", contentType) => createErrorResponse(451, msg, contentType),
550
- internalServerError: (msg = "Internal Server Error", contentType) => createErrorResponse(HTTP_STATUS.INTERNAL_SERVER_ERROR, msg, contentType),
551
- notImplemented: (msg = "Not Implemented", contentType) => createErrorResponse(501, msg, contentType),
552
- badGateway: (msg = "Bad Gateway", contentType) => createErrorResponse(502, msg, contentType),
553
- serviceUnavailable: (msg = "Service Unavailable", contentType) => createErrorResponse(503, msg, contentType),
554
- gatewayTimeout: (msg = "Gateway Timeout", contentType) => createErrorResponse(504, msg, contentType),
555
- httpVersionNotSupported: (msg = "HTTP Version Not Supported", contentType) => createErrorResponse(505, msg, contentType),
556
- variantAlsoNegotiates: (msg = "Variant Also Negotiates", contentType) => createErrorResponse(506, msg, contentType),
557
- insufficientStorage: (msg = "Insufficient Storage", contentType) => createErrorResponse(507, msg, contentType),
558
- loopDetected: (msg = "Loop Detected", contentType) => createErrorResponse(508, msg, contentType),
559
- notExtended: (msg = "Not Extended", contentType) => createErrorResponse(510, msg, contentType),
560
- networkAuthenticationRequired: (msg = "Network Authentication Required", contentType) => createErrorResponse(511, msg, contentType),
561
- invalidArgument: (msg = "Invalid Argument", contentType) => createErrorResponse(HTTP_STATUS.UNPROCESSABLE_ENTITY, msg, contentType),
562
- rateLimitExceeded: (msg = "Rate Limit Exceeded", contentType) => createErrorResponse(429, msg, contentType),
563
- maintenance: (msg = "Service Under Maintenance", contentType) => createErrorResponse(503, msg, contentType),
564
- custom: (statusCode, msg, contentType) => createErrorResponse(statusCode, msg, contentType)
565
- };
566
- });
567
566
 
568
567
  // src/core/router.ts
569
568
  class VectorRouter {
@@ -638,23 +637,45 @@ class VectorRouter {
638
637
  createRouteRegex(path) {
639
638
  return RegExp(`^${path.replace(/\/+(\/|$)/g, "$1").replace(/(\/?\.?):(\w+)\+/g, "($1(?<$2>*))").replace(/(\/?\.?):(\w+)/g, "($1(?<$2>[^$1/]+?))").replace(/\./g, "\\.").replace(/(\/?)\*/g, "($1.*)?")}/*$`);
640
639
  }
640
+ prepareRequest(request, options) {
641
+ if (!request.context) {
642
+ request.context = {};
643
+ }
644
+ if (options?.params !== undefined) {
645
+ request.params = options.params;
646
+ }
647
+ if (options?.route !== undefined) {
648
+ request.route = options.route;
649
+ }
650
+ if (options?.metadata !== undefined) {
651
+ request.metadata = options.metadata;
652
+ }
653
+ if (!request.query && request.url) {
654
+ const url = new URL(request.url);
655
+ const query = {};
656
+ for (const [key, value] of url.searchParams) {
657
+ if (key in query) {
658
+ if (Array.isArray(query[key])) {
659
+ query[key].push(value);
660
+ } else {
661
+ query[key] = [query[key], value];
662
+ }
663
+ } else {
664
+ query[key] = value;
665
+ }
666
+ }
667
+ request.query = query;
668
+ }
669
+ if (!request.cookies) {
670
+ w(request);
671
+ }
672
+ }
641
673
  wrapHandler(options, handler) {
642
674
  return async (request) => {
643
675
  const vectorRequest = request;
644
- if (!vectorRequest.context) {
645
- vectorRequest.context = {};
646
- }
647
- if (!vectorRequest.query && vectorRequest.url) {
648
- const url = new URL(vectorRequest.url);
649
- const query = {};
650
- for (let [k, v] of url.searchParams) {
651
- query[k] = query[k] ? [].concat(query[k], v) : v;
652
- }
653
- vectorRequest.query = query;
654
- }
655
- if (options.metadata) {
656
- vectorRequest.metadata = options.metadata;
657
- }
676
+ this.prepareRequest(vectorRequest, {
677
+ metadata: options.metadata
678
+ });
658
679
  request = vectorRequest;
659
680
  try {
660
681
  if (options.expose === false) {
@@ -690,19 +711,37 @@ class VectorRouter {
690
711
  }
691
712
  let result;
692
713
  const cacheOptions = options.cache;
714
+ const cacheFactory = async () => {
715
+ const res = await handler(request);
716
+ if (res instanceof Response) {
717
+ return {
718
+ _isResponse: true,
719
+ body: await res.text(),
720
+ status: res.status,
721
+ headers: Object.fromEntries(res.headers.entries())
722
+ };
723
+ }
724
+ return res;
725
+ };
693
726
  if (cacheOptions && typeof cacheOptions === "number" && cacheOptions > 0) {
694
727
  const cacheKey = this.cacheManager.generateKey(request, {
695
728
  authUser: request.authUser
696
729
  });
697
- result = await this.cacheManager.get(cacheKey, () => handler(request), cacheOptions);
730
+ result = await this.cacheManager.get(cacheKey, cacheFactory, cacheOptions);
698
731
  } else if (cacheOptions && typeof cacheOptions === "object" && cacheOptions.ttl) {
699
732
  const cacheKey = cacheOptions.key || this.cacheManager.generateKey(request, {
700
733
  authUser: request.authUser
701
734
  });
702
- result = await this.cacheManager.get(cacheKey, () => handler(request), cacheOptions.ttl);
735
+ result = await this.cacheManager.get(cacheKey, cacheFactory, cacheOptions.ttl);
703
736
  } else {
704
737
  result = await handler(request);
705
738
  }
739
+ if (result && typeof result === "object" && result._isResponse === true) {
740
+ result = new Response(result.body, {
741
+ status: result.status,
742
+ headers: result.headers
743
+ });
744
+ }
706
745
  let response;
707
746
  if (options.rawResponse || result instanceof Response) {
708
747
  response = result instanceof Response ? result : new Response(result);
@@ -730,15 +769,15 @@ class VectorRouter {
730
769
  async handle(request) {
731
770
  const url = new URL(request.url);
732
771
  const pathname = url.pathname;
733
- for (const [method, regex, handlers] of this.routes) {
772
+ for (const [method, regex, handlers, path] of this.routes) {
734
773
  if (request.method === "OPTIONS" || request.method === method) {
735
774
  const match = pathname.match(regex);
736
775
  if (match) {
737
776
  const req = request;
738
- if (!req.context) {
739
- req.context = {};
740
- }
741
- req.params = match.groups || {};
777
+ this.prepareRequest(req, {
778
+ params: match.groups || {},
779
+ route: path || pathname
780
+ });
742
781
  for (const handler of handlers) {
743
782
  const response = await handler(req);
744
783
  if (response)
@@ -753,9 +792,6 @@ class VectorRouter {
753
792
  this.routes = [];
754
793
  }
755
794
  }
756
- var init_router = __esm(() => {
757
- init_http();
758
- });
759
795
 
760
796
  // src/core/server.ts
761
797
  class VectorServer {
@@ -799,19 +835,36 @@ class VectorServer {
799
835
  return new Response("Internal Server Error", { status: 500 });
800
836
  }
801
837
  };
802
- this.server = Bun.serve({
803
- port,
804
- hostname,
805
- reusePort: this.config.reusePort !== false,
806
- fetch,
807
- idleTimeout: this.config.idleTimeout || 60,
808
- error: (error) => {
809
- console.error("[ERROR] Server error:", error);
810
- return new Response("Internal Server Error", { status: 500 });
838
+ try {
839
+ this.server = Bun.serve({
840
+ port,
841
+ hostname,
842
+ reusePort: this.config.reusePort !== false,
843
+ fetch,
844
+ idleTimeout: this.config.idleTimeout || 60,
845
+ error: (error) => {
846
+ console.error("[ERROR] Server error:", error);
847
+ return new Response("Internal Server Error", { status: 500 });
848
+ }
849
+ });
850
+ if (!this.server || !this.server.port) {
851
+ throw new Error(`Failed to start server on ${hostname}:${port} - server object is invalid`);
811
852
  }
812
- });
813
- console.log(`\u2192 Vector server running at http://${hostname}:${port}`);
814
- return this.server;
853
+ console.log(`\u2192 Vector server running at http://${hostname}:${port}`);
854
+ return this.server;
855
+ } catch (error) {
856
+ if (error.code === "EADDRINUSE" || error.message?.includes("address already in use")) {
857
+ error.message = `Port ${port} is already in use`;
858
+ error.port = port;
859
+ } else if (error.code === "EACCES" || error.message?.includes("permission denied")) {
860
+ error.message = `Permission denied to bind to port ${port}`;
861
+ error.port = port;
862
+ } else if (error.message?.includes("EADDRNOTAVAIL")) {
863
+ error.message = `Cannot bind to hostname ${hostname}`;
864
+ error.hostname = hostname;
865
+ }
866
+ throw error;
867
+ }
815
868
  }
816
869
  stop() {
817
870
  if (this.server) {
@@ -835,9 +888,6 @@ class VectorServer {
835
888
  return `http://${hostname}:${port}`;
836
889
  }
837
890
  }
838
- var init_server = __esm(() => {
839
- init_itty_router();
840
- });
841
891
 
842
892
  // src/core/vector.ts
843
893
  class Vector {
@@ -986,25 +1036,11 @@ class Vector {
986
1036
  Vector.instance = null;
987
1037
  }
988
1038
  }
989
- var getVectorInstance;
990
- var init_vector = __esm(() => {
991
- init_manager();
992
- init_route_generator();
993
- init_route_scanner();
994
- init_router();
995
- init_server();
996
- getVectorInstance = Vector.getInstance;
997
- });
998
-
999
- // src/cli/index.ts
1000
- init_vector();
1001
- import { watch } from "fs";
1002
- import { parseArgs } from "util";
1039
+ var getVectorInstance = Vector.getInstance;
1003
1040
 
1004
1041
  // src/core/config-loader.ts
1005
1042
  import { existsSync as existsSync2 } from "fs";
1006
1043
  import { resolve as resolve2, isAbsolute } from "path";
1007
-
1008
1044
  class ConfigLoader {
1009
1045
  configPath;
1010
1046
  config = null;
@@ -1127,54 +1163,64 @@ async function runDev() {
1127
1163
  let server = null;
1128
1164
  let vector = null;
1129
1165
  async function startServer() {
1130
- try {
1131
- const configLoader = new ConfigLoader(values.config);
1132
- const config = await configLoader.load();
1133
- const configSource = configLoader.getConfigSource();
1134
- config.port = config.port ?? Number.parseInt(values.port);
1135
- config.hostname = config.hostname ?? values.host;
1136
- config.routesDir = config.routesDir ?? values.routes;
1137
- config.development = config.development ?? isDev;
1138
- config.autoDiscover = true;
1139
- if (!config.cors && values.cors) {
1140
- config.cors = {
1141
- origin: "*",
1142
- credentials: true,
1143
- allowHeaders: "Content-Type, Authorization",
1144
- allowMethods: "GET, POST, PUT, PATCH, DELETE, OPTIONS",
1145
- exposeHeaders: "Authorization",
1146
- maxAge: 86400
1147
- };
1148
- }
1149
- vector = getVectorInstance();
1150
- const authHandler = await configLoader.loadAuthHandler();
1151
- if (authHandler) {
1152
- vector.setProtectedHandler(authHandler);
1153
- }
1154
- const cacheHandler = await configLoader.loadCacheHandler();
1155
- if (cacheHandler) {
1156
- vector.setCacheHandler(cacheHandler);
1157
- }
1158
- server = await vector.startServer(config);
1159
- const gray = "\x1B[90m";
1160
- const reset = "\x1B[0m";
1161
- const cyan = "\x1B[36m";
1162
- const green = "\x1B[32m";
1163
- console.log(` ${gray}Config${reset} ${configSource === "user" ? "User config loaded" : "Using defaults"}`);
1164
- console.log(` ${gray}Routes${reset} ${config.routesDir}`);
1165
- if (isDev && values.watch) {
1166
- console.log(` ${gray}Watching${reset} All project files`);
1167
- }
1168
- console.log(` ${gray}CORS${reset} ${config.cors ? "Enabled" : "Disabled"}`);
1169
- console.log(` ${gray}Mode${reset} ${config.development ? "Development" : "Production"}
1166
+ const timeoutPromise = new Promise((_, reject) => {
1167
+ setTimeout(() => {
1168
+ reject(new Error("Server startup timed out (10s)"));
1169
+ }, 1e4);
1170
+ });
1171
+ const serverStartPromise = (async () => {
1172
+ try {
1173
+ const configLoader = new ConfigLoader(values.config);
1174
+ const config = await configLoader.load();
1175
+ const configSource = configLoader.getConfigSource();
1176
+ config.port = config.port ?? Number.parseInt(values.port);
1177
+ config.hostname = config.hostname ?? values.host;
1178
+ config.routesDir = config.routesDir ?? values.routes;
1179
+ config.development = config.development ?? isDev;
1180
+ config.autoDiscover = true;
1181
+ if (!config.cors && values.cors) {
1182
+ config.cors = {
1183
+ origin: "*",
1184
+ credentials: true,
1185
+ allowHeaders: "Content-Type, Authorization",
1186
+ allowMethods: "GET, POST, PUT, PATCH, DELETE, OPTIONS",
1187
+ exposeHeaders: "Authorization",
1188
+ maxAge: 86400
1189
+ };
1190
+ }
1191
+ vector = getVectorInstance();
1192
+ const authHandler = await configLoader.loadAuthHandler();
1193
+ if (authHandler) {
1194
+ vector.setProtectedHandler(authHandler);
1195
+ }
1196
+ const cacheHandler = await configLoader.loadCacheHandler();
1197
+ if (cacheHandler) {
1198
+ vector.setCacheHandler(cacheHandler);
1199
+ }
1200
+ server = await vector.startServer(config);
1201
+ if (!server || !server.port) {
1202
+ throw new Error("Server started but is not responding correctly");
1203
+ }
1204
+ const gray = "\x1B[90m";
1205
+ const reset = "\x1B[0m";
1206
+ const cyan = "\x1B[36m";
1207
+ const green = "\x1B[32m";
1208
+ console.log(` ${gray}Config${reset} ${configSource === "user" ? "User config loaded" : "Using defaults"}`);
1209
+ console.log(` ${gray}Routes${reset} ${config.routesDir}`);
1210
+ if (isDev && values.watch) {
1211
+ console.log(` ${gray}Watching${reset} All project files`);
1212
+ }
1213
+ console.log(` ${gray}CORS${reset} ${config.cors ? "Enabled" : "Disabled"}`);
1214
+ console.log(` ${gray}Mode${reset} ${config.development ? "Development" : "Production"}
1170
1215
  `);
1171
- console.log(` ${green}Ready${reset} \u2192 ${cyan}http://${config.hostname}:${config.port}${reset}
1216
+ console.log(` ${green}Ready${reset} \u2192 ${cyan}http://${config.hostname}:${config.port}${reset}
1172
1217
  `);
1173
- return { server, vector, config };
1174
- } catch (error) {
1175
- console.error("[ERROR] Failed to start server:", error);
1176
- throw error;
1177
- }
1218
+ return { server, vector, config };
1219
+ } catch (error) {
1220
+ throw error;
1221
+ }
1222
+ })();
1223
+ return await Promise.race([serverStartPromise, timeoutPromise]);
1178
1224
  }
1179
1225
  try {
1180
1226
  const result = await startServer();
@@ -1214,7 +1260,8 @@ async function runDev() {
1214
1260
  server = result2.server;
1215
1261
  vector = result2.vector;
1216
1262
  } catch (error) {
1217
- console.error(" \u274C Failed to reload server:", error);
1263
+ console.error(`
1264
+ [Reload Error]`, error.message || error);
1218
1265
  } finally {
1219
1266
  setTimeout(() => {
1220
1267
  isReloading = false;
@@ -1228,7 +1275,21 @@ async function runDev() {
1228
1275
  }
1229
1276
  }
1230
1277
  } catch (error) {
1231
- console.error("[ERROR] Failed to start server:", error);
1278
+ const red = "\x1B[31m";
1279
+ const reset = "\x1B[0m";
1280
+ console.error(`
1281
+ ${red}[ERROR] Failed to start server${reset}
1282
+ `);
1283
+ if (error.message) {
1284
+ console.error(`Message: ${error.message}`);
1285
+ }
1286
+ if (error.stack) {
1287
+ console.error(`
1288
+ Stack trace:`);
1289
+ console.error(error.stack);
1290
+ } else if (!error.message) {
1291
+ console.error(`Raw error:`, error);
1292
+ }
1232
1293
  process.exit(1);
1233
1294
  }
1234
1295
  }