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/README.md +486 -347
- package/dist/cli/index.js +85 -55
- package/dist/cli/index.js.map +1 -1
- package/dist/cli.js +434 -373
- package/dist/core/router.d.ts +1 -0
- package/dist/core/router.d.ts.map +1 -1
- package/dist/core/router.js +73 -25
- package/dist/core/router.js.map +1 -1
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +36 -14
- package/dist/core/server.js.map +1 -1
- package/dist/http.d.ts +2 -2
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +3 -4
- package/dist/http.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.mjs +5 -5
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -2
- package/src/cli/index.ts +106 -70
- package/src/core/router.ts +85 -27
- package/src/core/server.ts +35 -14
- package/src/http.ts +8 -13
- package/src/types/index.ts +3 -0
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
|
-
}
|
|
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
|
-
|
|
645
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
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
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
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
|
-
|
|
814
|
-
|
|
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
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
config.
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
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
|
-
|
|
1216
|
+
console.log(` ${green}Ready${reset} \u2192 ${cyan}http://${config.hostname}:${config.port}${reset}
|
|
1172
1217
|
`);
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
}
|