vector-framework 0.9.7 → 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.js +332 -313
- 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/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 +6 -6
- package/dist/index.mjs +6 -6
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -2
- package/src/core/router.ts +85 -27
- 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 {
|
|
@@ -852,9 +888,6 @@ class VectorServer {
|
|
|
852
888
|
return `http://${hostname}:${port}`;
|
|
853
889
|
}
|
|
854
890
|
}
|
|
855
|
-
var init_server = __esm(() => {
|
|
856
|
-
init_itty_router();
|
|
857
|
-
});
|
|
858
891
|
|
|
859
892
|
// src/core/vector.ts
|
|
860
893
|
class Vector {
|
|
@@ -1003,25 +1036,11 @@ class Vector {
|
|
|
1003
1036
|
Vector.instance = null;
|
|
1004
1037
|
}
|
|
1005
1038
|
}
|
|
1006
|
-
var getVectorInstance;
|
|
1007
|
-
var init_vector = __esm(() => {
|
|
1008
|
-
init_manager();
|
|
1009
|
-
init_route_generator();
|
|
1010
|
-
init_route_scanner();
|
|
1011
|
-
init_router();
|
|
1012
|
-
init_server();
|
|
1013
|
-
getVectorInstance = Vector.getInstance;
|
|
1014
|
-
});
|
|
1015
|
-
|
|
1016
|
-
// src/cli/index.ts
|
|
1017
|
-
init_vector();
|
|
1018
|
-
import { watch } from "fs";
|
|
1019
|
-
import { parseArgs } from "util";
|
|
1039
|
+
var getVectorInstance = Vector.getInstance;
|
|
1020
1040
|
|
|
1021
1041
|
// src/core/config-loader.ts
|
|
1022
1042
|
import { existsSync as existsSync2 } from "fs";
|
|
1023
1043
|
import { resolve as resolve2, isAbsolute } from "path";
|
|
1024
|
-
|
|
1025
1044
|
class ConfigLoader {
|
|
1026
1045
|
configPath;
|
|
1027
1046
|
config = null;
|