@stacksjs/bun-router 0.0.2 → 0.0.3
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/{chunk-r15a48wc.js → chunk-cjdekj87.js} +536 -98
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +454 -119
- package/package.json +6 -8
- package/dist/auth.d.ts +0 -77
- package/dist/cache/lru-cache.d.ts +0 -88
- package/dist/cache/middleware-memoization.d.ts +0 -101
- package/dist/cache/route-cache-warmer.d.ts +0 -125
- package/dist/cache/sqlite-cache.d.ts +0 -114
- package/dist/cache/streaming-cache.d.ts +0 -86
- package/dist/cli/colors.d.ts +0 -12
- package/dist/cli/index.d.ts +0 -10
- package/dist/cli/middleware.d.ts +0 -31
- package/dist/cli/openapi.d.ts +0 -17
- package/dist/cli/router.d.ts +0 -15
- package/dist/cli/routes.d.ts +0 -30
- package/dist/cli/utils.d.ts +0 -68
- package/dist/config.d.ts +0 -274
- package/dist/container/container.d.ts +0 -141
- package/dist/container/contextual-binding.d.ts +0 -112
- package/dist/container/decorators.d.ts +0 -114
- package/dist/container/service-provider.d.ts +0 -221
- package/dist/development/hot-reload.d.ts +0 -129
- package/dist/development/index.d.ts +0 -144
- package/dist/development/performance-profiler.d.ts +0 -152
- package/dist/development/route-debugger.d.ts +0 -102
- package/dist/development/route-inspector.d.ts +0 -142
- package/dist/development/typescript-utilities.d.ts +0 -116
- package/dist/docs.d.ts +0 -10
- package/dist/errors/circuit-breaker.d.ts +0 -138
- package/dist/errors/error-handler.d.ts +0 -57
- package/dist/errors/error-reporting.d.ts +0 -135
- package/dist/errors/exceptions.d.ts +0 -178
- package/dist/errors/graceful-degradation.d.ts +0 -130
- package/dist/errors/index.d.ts +0 -6
- package/dist/errors/router-errors.d.ts +0 -97
- package/dist/file-serving/static-files.d.ts +0 -98
- package/dist/middleware/auth.d.ts +0 -34
- package/dist/middleware/content_security_policy.d.ts +0 -54
- package/dist/middleware/cors.d.ts +0 -5
- package/dist/middleware/csrf.d.ts +0 -7
- package/dist/middleware/ddos_protection.d.ts +0 -47
- package/dist/middleware/file_security.d.ts +0 -23
- package/dist/middleware/file_upload.d.ts +0 -41
- package/dist/middleware/helmet.d.ts +0 -54
- package/dist/middleware/index.d.ts +0 -55
- package/dist/middleware/input_validation.d.ts +0 -46
- package/dist/middleware/json_body.d.ts +0 -4
- package/dist/middleware/performance_alerting.d.ts +0 -88
- package/dist/middleware/performance_dashboard.d.ts +0 -97
- package/dist/middleware/performance_monitor.d.ts +0 -236
- package/dist/middleware/pipeline.d.ts +0 -90
- package/dist/middleware/rate_limit.d.ts +0 -33
- package/dist/middleware/request_id.d.ts +0 -4
- package/dist/middleware/request_signing.d.ts +0 -96
- package/dist/middleware/request_tracer.d.ts +0 -76
- package/dist/middleware/response_cache.d.ts +0 -90
- package/dist/middleware/security.d.ts +0 -70
- package/dist/middleware/security_suite.d.ts +0 -46
- package/dist/middleware/session.d.ts +0 -7
- package/dist/model-binding/index.d.ts +0 -17
- package/dist/model-binding/model-middleware.d.ts +0 -80
- package/dist/model-binding/model-registry.d.ts +0 -125
- package/dist/model-binding.d.ts +0 -123
- package/dist/model-resolver-factory.d.ts +0 -31
- package/dist/observability/correlation.d.ts +0 -131
- package/dist/observability/health-checks.d.ts +0 -129
- package/dist/observability/index.d.ts +0 -92
- package/dist/observability/integration.d.ts +0 -112
- package/dist/observability/metrics.d.ts +0 -135
- package/dist/observability/tracing.d.ts +0 -112
- package/dist/optimization/bun-utilities.d.ts +0 -106
- package/dist/query-builder-integration.d.ts +0 -24
- package/dist/request/enhanced-request.d.ts +0 -143
- package/dist/request/macros.d.ts +0 -267
- package/dist/response/macros.d.ts +0 -207
- package/dist/response/response-factory.d.ts +0 -93
- package/dist/router/file-based-routing.d.ts +0 -40
- package/dist/router/file-streaming.d.ts +0 -6
- package/dist/router/fluent-router.d.ts +0 -179
- package/dist/router/fluent-routing.d.ts +0 -198
- package/dist/router/group-organization.d.ts +0 -5
- package/dist/router/handler-resolver.d.ts +0 -13
- package/dist/router/http-methods.d.ts +0 -10
- package/dist/router/index.d.ts +0 -114
- package/dist/router/middleware-integration.d.ts +0 -86
- package/dist/router/middleware.d.ts +0 -5
- package/dist/router/model-binding.d.ts +0 -7
- package/dist/router/optimized-route-matching.d.ts +0 -6
- package/dist/router/route-building.d.ts +0 -5
- package/dist/router/route-compiler.d.ts +0 -67
- package/dist/router/route-matching.d.ts +0 -5
- package/dist/router/route-trie.d.ts +0 -69
- package/dist/router/router.d.ts +0 -133
- package/dist/router/server.d.ts +0 -5
- package/dist/router/validation-integration.d.ts +0 -116
- package/dist/router/view-rendering.d.ts +0 -5
- package/dist/router/websocket.d.ts +0 -5
- package/dist/routing/route-caching.d.ts +0 -105
- package/dist/routing/route-throttling.d.ts +0 -112
- package/dist/routing/subdomain-routing.d.ts +0 -159
- package/dist/streaming/index.d.ts +0 -15
- package/dist/streaming/sse-handler.d.ts +0 -81
- package/dist/streaming/stream-handler.d.ts +0 -81
- package/dist/testing/auth-testing.d.ts +0 -107
- package/dist/testing/file-upload-testing.d.ts +0 -139
- package/dist/testing/index.d.ts +0 -10
- package/dist/testing/middleware-testing.d.ts +0 -99
- package/dist/testing/model-binding-testing.d.ts +0 -132
- package/dist/testing/performance-testing.d.ts +0 -202
- package/dist/testing/test-client.d.ts +0 -58
- package/dist/testing/test-request.d.ts +0 -43
- package/dist/testing/test-response.d.ts +0 -45
- package/dist/testing/types.d.ts +0 -206
- package/dist/testing/websocket-testing.d.ts +0 -170
- package/dist/types/controller-types.d.ts +0 -303
- package/dist/types/core.d.ts +0 -526
- package/dist/types/middleware-types.d.ts +0 -315
- package/dist/types/request-response-augmentation.d.ts +0 -373
- package/dist/types/route-inference.d.ts +0 -287
- package/dist/types.d.ts +0 -1620
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/query-preservation.d.ts +0 -31
- package/dist/utils.d.ts +0 -69
- package/dist/validation/validator.d.ts +0 -169
- package/dist/websocket/clustering.d.ts +0 -114
package/dist/index.js
CHANGED
|
@@ -4,22 +4,27 @@ import {
|
|
|
4
4
|
Cors,
|
|
5
5
|
Csrf,
|
|
6
6
|
DDoSProtection,
|
|
7
|
+
DatabaseSessionStore,
|
|
7
8
|
FileSecurity,
|
|
9
|
+
FileSessionStore,
|
|
8
10
|
FileUpload,
|
|
9
11
|
Helmet,
|
|
10
12
|
InMemoryNonceStore,
|
|
11
13
|
InputValidation,
|
|
12
14
|
JsonBody,
|
|
15
|
+
MemorySessionStore,
|
|
13
16
|
PerformanceAlerting,
|
|
14
17
|
PerformanceDashboard,
|
|
15
18
|
PerformanceMonitor,
|
|
16
19
|
RateLimit,
|
|
20
|
+
RedisSessionStore,
|
|
17
21
|
RequestId,
|
|
18
22
|
RequestSigning,
|
|
19
23
|
RequestTracer,
|
|
20
24
|
Security,
|
|
21
25
|
SecuritySuite,
|
|
22
26
|
Session,
|
|
27
|
+
SessionManager,
|
|
23
28
|
SignatureError,
|
|
24
29
|
__export,
|
|
25
30
|
__require,
|
|
@@ -30,6 +35,7 @@ import {
|
|
|
30
35
|
config,
|
|
31
36
|
contentSecurityPolicy,
|
|
32
37
|
cors,
|
|
38
|
+
createSessionStore,
|
|
33
39
|
csrf,
|
|
34
40
|
ddosProtection,
|
|
35
41
|
defaultConfig,
|
|
@@ -38,6 +44,7 @@ import {
|
|
|
38
44
|
extractBasicAuth,
|
|
39
45
|
extractBearerToken,
|
|
40
46
|
fileUpload,
|
|
47
|
+
generateSessionId,
|
|
41
48
|
getConfig,
|
|
42
49
|
imageUpload,
|
|
43
50
|
inputValidation,
|
|
@@ -59,7 +66,7 @@ import {
|
|
|
59
66
|
signRequest,
|
|
60
67
|
singleFileUpload,
|
|
61
68
|
verifySignature
|
|
62
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-cjdekj87.js";
|
|
63
70
|
|
|
64
71
|
// src/auth.ts
|
|
65
72
|
function base64UrlEncode(str) {
|
|
@@ -3337,7 +3344,7 @@ var MiddlewareFactory = {
|
|
|
3337
3344
|
};
|
|
3338
3345
|
},
|
|
3339
3346
|
cors: (options = {}) => {
|
|
3340
|
-
return async (
|
|
3347
|
+
return async (_req, next) => {
|
|
3341
3348
|
const response2 = await next();
|
|
3342
3349
|
if (response2) {
|
|
3343
3350
|
const headers = new Headers(response2.headers);
|
|
@@ -3369,9 +3376,147 @@ var MiddlewareFactory = {
|
|
|
3369
3376
|
};
|
|
3370
3377
|
var globalMiddlewarePipeline = new MiddlewarePipeline;
|
|
3371
3378
|
|
|
3379
|
+
// src/router/api-routes.ts
|
|
3380
|
+
import { existsSync, readdirSync, statSync } from "fs";
|
|
3381
|
+
import { basename, extname, join, resolve } from "path";
|
|
3382
|
+
var ROUTE_EXTENSIONS = [".ts", ".js"];
|
|
3383
|
+
var ROUTES_DIRS = ["routes", "src/routes"];
|
|
3384
|
+
var ROOT_ROUTE_FILES = ["web", "index"];
|
|
3385
|
+
function detectRoutesDirectory() {
|
|
3386
|
+
const cwd = process.cwd();
|
|
3387
|
+
for (const dir of ROUTES_DIRS) {
|
|
3388
|
+
const fullPath = resolve(cwd, dir);
|
|
3389
|
+
if (existsSync(fullPath) && statSync(fullPath).isDirectory()) {
|
|
3390
|
+
return fullPath;
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
return null;
|
|
3394
|
+
}
|
|
3395
|
+
function discoverRouteFiles(dir, baseDir) {
|
|
3396
|
+
const results = [];
|
|
3397
|
+
if (!existsSync(dir))
|
|
3398
|
+
return results;
|
|
3399
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
3400
|
+
for (const entry of entries) {
|
|
3401
|
+
if (entry.name.startsWith(".") || entry.name.startsWith("_"))
|
|
3402
|
+
continue;
|
|
3403
|
+
const fullPath = join(dir, entry.name);
|
|
3404
|
+
if (entry.isDirectory()) {
|
|
3405
|
+
results.push(...discoverRouteFiles(fullPath, baseDir));
|
|
3406
|
+
} else if (ROUTE_EXTENSIONS.includes(extname(entry.name))) {
|
|
3407
|
+
const relDir = dir === baseDir ? "" : dir.slice(baseDir.length);
|
|
3408
|
+
const name = basename(entry.name, extname(entry.name));
|
|
3409
|
+
const prefix = ROOT_ROUTE_FILES.includes(name) ? relDir || "" : `${relDir}/${name}`;
|
|
3410
|
+
results.push({ filePath: fullPath, prefix });
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
return results;
|
|
3414
|
+
}
|
|
3415
|
+
async function loadRouteFile(router, filePath, prefix, verbose) {
|
|
3416
|
+
try {
|
|
3417
|
+
const mod = await import(filePath);
|
|
3418
|
+
let count = 0;
|
|
3419
|
+
const routesBefore = router.routes?.length || 0;
|
|
3420
|
+
if (typeof mod.default === "function") {
|
|
3421
|
+
const prefixedRouter = createPrefixedProxy(router, prefix);
|
|
3422
|
+
await mod.default(prefixedRouter);
|
|
3423
|
+
count = (router.routes?.length || 0) - routesBefore;
|
|
3424
|
+
} else if (Array.isArray(mod.routes)) {
|
|
3425
|
+
for (const route of mod.routes) {
|
|
3426
|
+
const method = (route.method || "GET").toLowerCase();
|
|
3427
|
+
const path = `${prefix}${route.path}`;
|
|
3428
|
+
if (typeof router[method] === "function") {
|
|
3429
|
+
await router[method](path, route.handler);
|
|
3430
|
+
count++;
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
if (verbose && count > 0) {
|
|
3435
|
+
console.log(` ${prefix || "/"} \u2192 ${basename(filePath)} (${count} routes)`);
|
|
3436
|
+
}
|
|
3437
|
+
return count;
|
|
3438
|
+
} catch (error) {
|
|
3439
|
+
console.error(`[bun-router] Failed to load route file ${filePath}:`, error);
|
|
3440
|
+
return 0;
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3443
|
+
function createPrefixedProxy(router, prefix) {
|
|
3444
|
+
if (!prefix)
|
|
3445
|
+
return router;
|
|
3446
|
+
const methods = ["get", "post", "put", "patch", "delete", "options", "any"];
|
|
3447
|
+
return new Proxy(router, {
|
|
3448
|
+
get(target, prop) {
|
|
3449
|
+
if (methods.includes(prop)) {
|
|
3450
|
+
return async (path, ...args) => {
|
|
3451
|
+
return target[prop](`${prefix}${path}`, ...args);
|
|
3452
|
+
};
|
|
3453
|
+
}
|
|
3454
|
+
if (prop === "group") {
|
|
3455
|
+
return async (options, callback) => {
|
|
3456
|
+
const nestedPrefix = options.prefix ? `${prefix}${options.prefix}` : prefix;
|
|
3457
|
+
return target.group({ ...options, prefix: nestedPrefix }, callback);
|
|
3458
|
+
};
|
|
3459
|
+
}
|
|
3460
|
+
return target[prop];
|
|
3461
|
+
}
|
|
3462
|
+
});
|
|
3463
|
+
}
|
|
3464
|
+
function registerApiRoutes(RouterClass) {
|
|
3465
|
+
Object.defineProperties(RouterClass.prototype, {
|
|
3466
|
+
_routesDir: {
|
|
3467
|
+
value: null,
|
|
3468
|
+
writable: true,
|
|
3469
|
+
configurable: true
|
|
3470
|
+
},
|
|
3471
|
+
_apiRoutesInitialized: {
|
|
3472
|
+
value: false,
|
|
3473
|
+
writable: true,
|
|
3474
|
+
configurable: true
|
|
3475
|
+
},
|
|
3476
|
+
_initApiRoutes: {
|
|
3477
|
+
async value() {
|
|
3478
|
+
if (this._apiRoutesInitialized)
|
|
3479
|
+
return;
|
|
3480
|
+
const routesDir = this._routesDir || detectRoutesDirectory();
|
|
3481
|
+
if (!routesDir) {
|
|
3482
|
+
this._apiRoutesInitialized = true;
|
|
3483
|
+
return;
|
|
3484
|
+
}
|
|
3485
|
+
const verbose = this.config?.verbose || false;
|
|
3486
|
+
const files = discoverRouteFiles(routesDir, routesDir);
|
|
3487
|
+
if (files.length === 0) {
|
|
3488
|
+
this._apiRoutesInitialized = true;
|
|
3489
|
+
return;
|
|
3490
|
+
}
|
|
3491
|
+
if (verbose) {
|
|
3492
|
+
console.log(`[bun-router] Auto-discovering API routes from ${routesDir}:`);
|
|
3493
|
+
}
|
|
3494
|
+
let totalRoutes = 0;
|
|
3495
|
+
for (const { filePath, prefix } of files) {
|
|
3496
|
+
totalRoutes += await loadRouteFile(this, filePath, prefix, verbose);
|
|
3497
|
+
}
|
|
3498
|
+
if (totalRoutes > 0 && verbose) {
|
|
3499
|
+
console.log(`[bun-router] Registered ${totalRoutes} API routes`);
|
|
3500
|
+
}
|
|
3501
|
+
this._apiRoutesInitialized = true;
|
|
3502
|
+
},
|
|
3503
|
+
writable: true,
|
|
3504
|
+
configurable: true
|
|
3505
|
+
},
|
|
3506
|
+
routesFrom: {
|
|
3507
|
+
value(dir) {
|
|
3508
|
+
this._routesDir = resolve(dir);
|
|
3509
|
+
return this;
|
|
3510
|
+
},
|
|
3511
|
+
writable: true,
|
|
3512
|
+
configurable: true
|
|
3513
|
+
}
|
|
3514
|
+
});
|
|
3515
|
+
}
|
|
3516
|
+
|
|
3372
3517
|
// src/router/file-based-routing.ts
|
|
3373
|
-
import { join, relative, resolve, dirname } from "path";
|
|
3374
|
-
import { readdirSync, statSync, existsSync } from "fs";
|
|
3518
|
+
import { join as join2, relative, resolve as resolve2, dirname } from "path";
|
|
3519
|
+
import { readdirSync as readdirSync2, statSync as statSync2, existsSync as existsSync2 } from "fs";
|
|
3375
3520
|
|
|
3376
3521
|
// src/utils/query-preservation.ts
|
|
3377
3522
|
var defaultQueryPreservationConfig = {
|
|
@@ -3403,11 +3548,13 @@ function generateQueryPreservationScript(config2) {
|
|
|
3403
3548
|
if (pattern.endsWith('*')) {
|
|
3404
3549
|
return path.startsWith(pattern.slice(0, -1));
|
|
3405
3550
|
}
|
|
3551
|
+
// eslint-disable-next-line prefer-template
|
|
3406
3552
|
return path === pattern || path.startsWith(pattern + '/');
|
|
3407
3553
|
});
|
|
3408
3554
|
}
|
|
3409
3555
|
return true;
|
|
3410
|
-
}
|
|
3556
|
+
}
|
|
3557
|
+
catch (e) { return false; }
|
|
3411
3558
|
}
|
|
3412
3559
|
|
|
3413
3560
|
function getPreservedParams() {
|
|
@@ -3518,18 +3665,18 @@ var DEFAULT_EXCLUDES = [
|
|
|
3518
3665
|
var DEFAULT_EXTENSIONS = [".stx", ".html"];
|
|
3519
3666
|
function detectViewsDirectory(cwd = process.cwd()) {
|
|
3520
3667
|
for (const dir of DEFAULT_VIEW_DIRECTORIES) {
|
|
3521
|
-
const fullPath =
|
|
3522
|
-
if (
|
|
3668
|
+
const fullPath = resolve2(cwd, dir);
|
|
3669
|
+
if (existsSync2(fullPath) && statSync2(fullPath).isDirectory()) {
|
|
3523
3670
|
return fullPath;
|
|
3524
3671
|
}
|
|
3525
3672
|
}
|
|
3526
3673
|
return null;
|
|
3527
3674
|
}
|
|
3528
3675
|
function hasRoutableFiles(dir, extensions, exclude) {
|
|
3529
|
-
if (!
|
|
3676
|
+
if (!existsSync2(dir))
|
|
3530
3677
|
return false;
|
|
3531
3678
|
try {
|
|
3532
|
-
const entries =
|
|
3679
|
+
const entries = readdirSync2(dir, { withFileTypes: true });
|
|
3533
3680
|
for (const entry of entries) {
|
|
3534
3681
|
if (exclude.some((pattern) => entry.name.startsWith(pattern) || entry.name === pattern)) {
|
|
3535
3682
|
continue;
|
|
@@ -3538,7 +3685,7 @@ function hasRoutableFiles(dir, extensions, exclude) {
|
|
|
3538
3685
|
return true;
|
|
3539
3686
|
}
|
|
3540
3687
|
if (entry.isDirectory()) {
|
|
3541
|
-
const subDir =
|
|
3688
|
+
const subDir = join2(dir, entry.name);
|
|
3542
3689
|
if (hasRoutableFiles(subDir, extensions, exclude)) {
|
|
3543
3690
|
return true;
|
|
3544
3691
|
}
|
|
@@ -3569,7 +3716,7 @@ function filePathToRoutePath(filePath, viewsDir, extensions) {
|
|
|
3569
3716
|
return `{${param}}`;
|
|
3570
3717
|
});
|
|
3571
3718
|
if (!routePath.startsWith("/")) {
|
|
3572
|
-
routePath =
|
|
3719
|
+
routePath = `/${routePath}`;
|
|
3573
3720
|
}
|
|
3574
3721
|
if (routePath === "/") {
|
|
3575
3722
|
return { routePath: "/", params };
|
|
@@ -3578,12 +3725,12 @@ function filePathToRoutePath(filePath, viewsDir, extensions) {
|
|
|
3578
3725
|
}
|
|
3579
3726
|
function discoverRoutes(dir, viewsDir, extensions, exclude) {
|
|
3580
3727
|
const routes = [];
|
|
3581
|
-
if (!
|
|
3728
|
+
if (!existsSync2(dir)) {
|
|
3582
3729
|
return routes;
|
|
3583
3730
|
}
|
|
3584
|
-
const entries =
|
|
3731
|
+
const entries = readdirSync2(dir, { withFileTypes: true });
|
|
3585
3732
|
for (const entry of entries) {
|
|
3586
|
-
const fullPath =
|
|
3733
|
+
const fullPath = join2(dir, entry.name);
|
|
3587
3734
|
if (exclude.some((pattern) => entry.name.startsWith(pattern) || entry.name === pattern)) {
|
|
3588
3735
|
continue;
|
|
3589
3736
|
}
|
|
@@ -3631,18 +3778,18 @@ function discoverRoutes(dir, viewsDir, extensions, exclude) {
|
|
|
3631
3778
|
function findPrebuiltView(stxFilePath, viewsDir) {
|
|
3632
3779
|
const relativePath = relative(viewsDir, stxFilePath);
|
|
3633
3780
|
const prebuiltLocations = [
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3781
|
+
resolve2(process.cwd(), "dist/views", relativePath.replace(/\.stx$/, ".html")),
|
|
3782
|
+
resolve2(process.cwd(), "views", relativePath.replace(/\.stx$/, ".html")),
|
|
3783
|
+
resolve2("/var/task/views", relativePath.replace(/\.stx$/, ".html"))
|
|
3637
3784
|
];
|
|
3638
3785
|
for (const location of prebuiltLocations) {
|
|
3639
|
-
if (
|
|
3786
|
+
if (existsSync2(location)) {
|
|
3640
3787
|
return location;
|
|
3641
3788
|
}
|
|
3642
3789
|
}
|
|
3643
3790
|
return null;
|
|
3644
3791
|
}
|
|
3645
|
-
async function renderStxFile(filePath, viewsDir, data) {
|
|
3792
|
+
async function renderStxFile(filePath, viewsDir, data, routingConfig) {
|
|
3646
3793
|
const stxModule = "@stacksjs/stx";
|
|
3647
3794
|
const stx = await import(stxModule);
|
|
3648
3795
|
if (!stx.processDirectives || !stx.extractVariables) {
|
|
@@ -3662,15 +3809,18 @@ async function renderStxFile(filePath, viewsDir, data) {
|
|
|
3662
3809
|
if (scriptContent) {
|
|
3663
3810
|
await stx.extractVariables(scriptContent, context, filePath);
|
|
3664
3811
|
}
|
|
3812
|
+
const resolvedComponentsDir = routingConfig?.componentsDir ? resolve2(routingConfig.componentsDir) : join2(viewsDir, "components");
|
|
3813
|
+
const resolvedLayoutsDir = routingConfig?.layoutsDir ? resolve2(routingConfig.layoutsDir) : join2(viewsDir, "layouts");
|
|
3814
|
+
const resolvedPartialsDir = routingConfig?.partialsDir ? resolve2(routingConfig.partialsDir) : join2(viewsDir, "partials");
|
|
3665
3815
|
const config2 = {
|
|
3666
3816
|
...stx.defaultConfig,
|
|
3667
|
-
componentsDir:
|
|
3668
|
-
layoutsDir:
|
|
3669
|
-
partialsDir:
|
|
3817
|
+
componentsDir: resolvedComponentsDir,
|
|
3818
|
+
layoutsDir: resolvedLayoutsDir,
|
|
3819
|
+
partialsDir: resolvedPartialsDir
|
|
3670
3820
|
};
|
|
3671
3821
|
return stx.processDirectives(templateContent, context, filePath, config2, new Set);
|
|
3672
3822
|
}
|
|
3673
|
-
function createViewHandler(filePath, viewsDir,
|
|
3823
|
+
function createViewHandler(filePath, viewsDir, config2, queryPreservationConfig) {
|
|
3674
3824
|
return async (req) => {
|
|
3675
3825
|
const url = new URL(req.url);
|
|
3676
3826
|
const data = {
|
|
@@ -3698,7 +3848,7 @@ function createViewHandler(filePath, viewsDir, _config, queryPreservationConfig)
|
|
|
3698
3848
|
});
|
|
3699
3849
|
}
|
|
3700
3850
|
if (filePath.endsWith(".stx")) {
|
|
3701
|
-
let html = await renderStxFile(filePath, viewsDir, data);
|
|
3851
|
+
let html = await renderStxFile(filePath, viewsDir, data, config2);
|
|
3702
3852
|
html = applyQueryPreservation(html);
|
|
3703
3853
|
return new Response(html, {
|
|
3704
3854
|
status: 200,
|
|
@@ -3767,7 +3917,7 @@ function registerFileBasedRouting(RouterClass) {
|
|
|
3767
3917
|
const handler = createViewHandler(route.filePath, viewsDir, config2, this.config.queryPreservation);
|
|
3768
3918
|
const existingRoute = this.routes.find((r) => r.path === route.routePath && r.method === "GET");
|
|
3769
3919
|
if (!existingRoute) {
|
|
3770
|
-
|
|
3920
|
+
this.get(route.routePath, handler, "web");
|
|
3771
3921
|
this._fileBasedRoutes.push(route);
|
|
3772
3922
|
}
|
|
3773
3923
|
}
|
|
@@ -3779,11 +3929,11 @@ function registerFileBasedRouting(RouterClass) {
|
|
|
3779
3929
|
views: {
|
|
3780
3930
|
value(config2) {
|
|
3781
3931
|
if (typeof config2 === "string") {
|
|
3782
|
-
this._viewsDir =
|
|
3932
|
+
this._viewsDir = resolve2(config2);
|
|
3783
3933
|
this._fileRoutingConfig = {};
|
|
3784
3934
|
} else {
|
|
3785
3935
|
if (config2.viewsPath) {
|
|
3786
|
-
this._viewsDir =
|
|
3936
|
+
this._viewsDir = resolve2(config2.viewsPath);
|
|
3787
3937
|
}
|
|
3788
3938
|
this._fileRoutingConfig = config2;
|
|
3789
3939
|
}
|
|
@@ -3810,7 +3960,7 @@ function registerFileBasedRouting(RouterClass) {
|
|
|
3810
3960
|
fileRoutes: {
|
|
3811
3961
|
async value(viewsPath, options) {
|
|
3812
3962
|
if (viewsPath) {
|
|
3813
|
-
this._viewsDir =
|
|
3963
|
+
this._viewsDir = resolve2(viewsPath);
|
|
3814
3964
|
}
|
|
3815
3965
|
if (options) {
|
|
3816
3966
|
this._fileRoutingConfig = { ...this._fileRoutingConfig, ...options };
|
|
@@ -4136,10 +4286,10 @@ function registerFileStreaming(RouterClass) {
|
|
|
4136
4286
|
configurable: true
|
|
4137
4287
|
},
|
|
4138
4288
|
health: {
|
|
4139
|
-
|
|
4289
|
+
value() {
|
|
4140
4290
|
const path = "/health";
|
|
4141
4291
|
const fullPath = this.config.apiPrefix ? `${this.config.apiPrefix}${path}` : path;
|
|
4142
|
-
|
|
4292
|
+
this.get(fullPath, () => {
|
|
4143
4293
|
return new Response("OK", {
|
|
4144
4294
|
headers: {
|
|
4145
4295
|
"Content-Type": "text/plain"
|
|
@@ -4395,7 +4545,7 @@ class ModelBindingRegistry {
|
|
|
4395
4545
|
}
|
|
4396
4546
|
}
|
|
4397
4547
|
var modelRegistry = new ModelBindingRegistry;
|
|
4398
|
-
async function resolveModel(
|
|
4548
|
+
async function resolveModel(_paramName, value, modelWrapper, customKey, _context = {}) {
|
|
4399
4549
|
if (customKey) {
|
|
4400
4550
|
return await modelWrapper.resolveRouteBinding(value, customKey);
|
|
4401
4551
|
}
|
|
@@ -5917,7 +6067,7 @@ var RouterUtils = {
|
|
|
5917
6067
|
var router = new FluentRouter;
|
|
5918
6068
|
|
|
5919
6069
|
// src/utils.ts
|
|
5920
|
-
import { join as
|
|
6070
|
+
import { join as join3 } from "path";
|
|
5921
6071
|
function normalizePath(path) {
|
|
5922
6072
|
let normalizedPath = path.replace(/\/+/g, "/");
|
|
5923
6073
|
if (!normalizedPath.startsWith("/")) {
|
|
@@ -6031,14 +6181,14 @@ async function fileExists(path) {
|
|
|
6031
6181
|
}
|
|
6032
6182
|
async function resolveViewPath(viewName, viewsPath, extensions) {
|
|
6033
6183
|
if (extensions.some((ext) => viewName.endsWith(ext))) {
|
|
6034
|
-
const fullPath = normalizePath(
|
|
6184
|
+
const fullPath = normalizePath(join3(viewsPath, viewName));
|
|
6035
6185
|
if (await fileExists(fullPath)) {
|
|
6036
6186
|
return fullPath;
|
|
6037
6187
|
}
|
|
6038
6188
|
return null;
|
|
6039
6189
|
}
|
|
6040
6190
|
for (const ext of extensions) {
|
|
6041
|
-
const fullPath = normalizePath(
|
|
6191
|
+
const fullPath = normalizePath(join3(viewsPath, `${viewName}${ext}`));
|
|
6042
6192
|
if (await fileExists(fullPath)) {
|
|
6043
6193
|
return fullPath;
|
|
6044
6194
|
}
|
|
@@ -6056,19 +6206,19 @@ function processHtmlTemplate(template, data) {
|
|
|
6056
6206
|
return result;
|
|
6057
6207
|
}
|
|
6058
6208
|
function processConditionals(template, data) {
|
|
6059
|
-
return template.replace(/\{\{#if ([^}]+)\}\}([\s\S]*?)(?:\{\{else\}\}([\s\S]*?))?\{\{\/if\}\}/g, (
|
|
6209
|
+
return template.replace(/\{\{#if ([^}]+)\}\}([\s\S]*?)(?:\{\{else\}\}([\s\S]*?))?\{\{\/if\}\}/g, (_match, condition, content, alternative = "") => {
|
|
6060
6210
|
const conditionTrimmed = condition.trim();
|
|
6061
6211
|
const value = getNestedValue(data, conditionTrimmed);
|
|
6062
6212
|
return value ? content : alternative;
|
|
6063
6213
|
});
|
|
6064
6214
|
}
|
|
6065
6215
|
function processLoops(template, data) {
|
|
6066
|
-
return template.replace(/\{\{#each ([^}]+)\}\}([\s\S]*?)\{\{\/each\}\}/g, (
|
|
6216
|
+
return template.replace(/\{\{#each ([^}]+)\}\}([\s\S]*?)\{\{\/each\}\}/g, (_match, arrayKey, content) => {
|
|
6067
6217
|
const array = getNestedValue(data, arrayKey.trim());
|
|
6068
6218
|
if (!Array.isArray(array))
|
|
6069
6219
|
return "";
|
|
6070
6220
|
return array.map((item) => {
|
|
6071
|
-
return content.replace(/\{\{@index\}\}/g, String(array.indexOf(item))).replace(/\{\{this\}\}/g, String(item)).replace(/\{\{this\.([^}]+)\}\}/g, (
|
|
6221
|
+
return content.replace(/\{\{@index\}\}/g, String(array.indexOf(item))).replace(/\{\{this\}\}/g, String(item)).replace(/\{\{this\.([^}]+)\}\}/g, (_matchStr, prop) => {
|
|
6072
6222
|
const value = item[prop.trim()];
|
|
6073
6223
|
return value !== undefined ? String(value) : "";
|
|
6074
6224
|
});
|
|
@@ -6085,7 +6235,7 @@ function getNestedValue(obj, path) {
|
|
|
6085
6235
|
function registerGroupOrganization(RouterClass) {
|
|
6086
6236
|
Object.defineProperties(RouterClass.prototype, {
|
|
6087
6237
|
group: {
|
|
6088
|
-
|
|
6238
|
+
value(options, callback) {
|
|
6089
6239
|
const previousGroup = this.currentGroup;
|
|
6090
6240
|
const newGroup = { ...previousGroup };
|
|
6091
6241
|
if (options.prefix && previousGroup?.prefix) {
|
|
@@ -6108,7 +6258,7 @@ function registerGroupOrganization(RouterClass) {
|
|
|
6108
6258
|
configurable: true
|
|
6109
6259
|
},
|
|
6110
6260
|
name: {
|
|
6111
|
-
|
|
6261
|
+
value(prefix, callback) {
|
|
6112
6262
|
const previousGroup = this.currentGroup || {};
|
|
6113
6263
|
const newGroup = { ...previousGroup };
|
|
6114
6264
|
this.currentGroup = newGroup;
|
|
@@ -6127,7 +6277,7 @@ function registerGroupOrganization(RouterClass) {
|
|
|
6127
6277
|
configurable: true
|
|
6128
6278
|
},
|
|
6129
6279
|
controller: {
|
|
6130
|
-
|
|
6280
|
+
value(controller, callback) {
|
|
6131
6281
|
const previousGroup = this.currentGroup || {};
|
|
6132
6282
|
const newGroup = { ...previousGroup, controller };
|
|
6133
6283
|
this.currentGroup = newGroup;
|
|
@@ -6139,7 +6289,7 @@ function registerGroupOrganization(RouterClass) {
|
|
|
6139
6289
|
configurable: true
|
|
6140
6290
|
},
|
|
6141
6291
|
domain: {
|
|
6142
|
-
|
|
6292
|
+
value(domain, callback) {
|
|
6143
6293
|
const previousDomain = this.currentDomain;
|
|
6144
6294
|
this.currentDomain = domain;
|
|
6145
6295
|
callback();
|
|
@@ -6150,14 +6300,14 @@ function registerGroupOrganization(RouterClass) {
|
|
|
6150
6300
|
configurable: true
|
|
6151
6301
|
},
|
|
6152
6302
|
prefix: {
|
|
6153
|
-
|
|
6303
|
+
value(prefix, callback) {
|
|
6154
6304
|
return this.group({ prefix }, callback);
|
|
6155
6305
|
},
|
|
6156
6306
|
writable: true,
|
|
6157
6307
|
configurable: true
|
|
6158
6308
|
},
|
|
6159
6309
|
resource: {
|
|
6160
|
-
|
|
6310
|
+
value(name, handler, type = "api") {
|
|
6161
6311
|
const pluralName = name.endsWith("s") ? name : `${name}s`;
|
|
6162
6312
|
const singularName = name.endsWith("s") ? name.slice(0, -1) : name;
|
|
6163
6313
|
const routes = [
|
|
@@ -6169,7 +6319,7 @@ function registerGroupOrganization(RouterClass) {
|
|
|
6169
6319
|
{ name: "update", method: "PUT", path: `/${pluralName}/{id}`, action: "update" },
|
|
6170
6320
|
{ name: "destroy", method: "DELETE", path: `/${pluralName}/{id}`, action: "destroy" }
|
|
6171
6321
|
];
|
|
6172
|
-
|
|
6322
|
+
this.name(singularName, () => {
|
|
6173
6323
|
for (const route of routes) {
|
|
6174
6324
|
let routeHandler;
|
|
6175
6325
|
if (typeof handler === "string") {
|
|
@@ -6183,16 +6333,16 @@ function registerGroupOrganization(RouterClass) {
|
|
|
6183
6333
|
}
|
|
6184
6334
|
switch (route.method) {
|
|
6185
6335
|
case "GET":
|
|
6186
|
-
|
|
6336
|
+
this.get(route.path, routeHandler, type, route.name);
|
|
6187
6337
|
break;
|
|
6188
6338
|
case "POST":
|
|
6189
|
-
|
|
6339
|
+
this.post(route.path, routeHandler, type, route.name);
|
|
6190
6340
|
break;
|
|
6191
6341
|
case "PUT":
|
|
6192
|
-
|
|
6342
|
+
this.put(route.path, routeHandler, type, route.name);
|
|
6193
6343
|
break;
|
|
6194
6344
|
case "DELETE":
|
|
6195
|
-
|
|
6345
|
+
this.delete(route.path, routeHandler, type, route.name);
|
|
6196
6346
|
break;
|
|
6197
6347
|
}
|
|
6198
6348
|
}
|
|
@@ -6209,7 +6359,7 @@ function registerGroupOrganization(RouterClass) {
|
|
|
6209
6359
|
function registerHttpMethods(RouterClass) {
|
|
6210
6360
|
Object.defineProperties(RouterClass.prototype, {
|
|
6211
6361
|
addRoute: {
|
|
6212
|
-
|
|
6362
|
+
value(method, path, handler, type, name, middleware2) {
|
|
6213
6363
|
let routePath = path;
|
|
6214
6364
|
let routeMiddleware = [];
|
|
6215
6365
|
const routeType = type || "web";
|
|
@@ -6223,7 +6373,7 @@ function registerHttpMethods(RouterClass) {
|
|
|
6223
6373
|
}
|
|
6224
6374
|
if (middleware2 && middleware2.length > 0) {
|
|
6225
6375
|
for (const middlewareItem of middleware2) {
|
|
6226
|
-
const resolved =
|
|
6376
|
+
const resolved = this.resolveMiddleware(middlewareItem);
|
|
6227
6377
|
if (resolved) {
|
|
6228
6378
|
routeMiddleware.push(resolved);
|
|
6229
6379
|
}
|
|
@@ -6272,6 +6422,9 @@ function registerHttpMethods(RouterClass) {
|
|
|
6272
6422
|
};
|
|
6273
6423
|
}
|
|
6274
6424
|
};
|
|
6425
|
+
if (handler instanceof Response) {
|
|
6426
|
+
this.staticResponses.set(routePath, handler);
|
|
6427
|
+
}
|
|
6275
6428
|
if (domain) {
|
|
6276
6429
|
if (!this.domains[domain]) {
|
|
6277
6430
|
this.domains[domain] = [];
|
|
@@ -6284,7 +6437,10 @@ function registerHttpMethods(RouterClass) {
|
|
|
6284
6437
|
if (!this.staticRoutes.has(method.toUpperCase())) {
|
|
6285
6438
|
this.staticRoutes.set(method.toUpperCase(), new Map);
|
|
6286
6439
|
}
|
|
6287
|
-
this.staticRoutes.get(method.toUpperCase())
|
|
6440
|
+
const methodMap = this.staticRoutes.get(method.toUpperCase());
|
|
6441
|
+
if (!methodMap.has(routePath)) {
|
|
6442
|
+
methodMap.set(routePath, route);
|
|
6443
|
+
}
|
|
6288
6444
|
}
|
|
6289
6445
|
if (name) {
|
|
6290
6446
|
route.name = name;
|
|
@@ -6300,51 +6456,51 @@ function registerHttpMethods(RouterClass) {
|
|
|
6300
6456
|
configurable: true
|
|
6301
6457
|
},
|
|
6302
6458
|
get: {
|
|
6303
|
-
|
|
6459
|
+
value(path, handler, type, name, middleware2) {
|
|
6304
6460
|
return this.addRoute("GET", path, handler, type, name, middleware2);
|
|
6305
6461
|
},
|
|
6306
6462
|
writable: true,
|
|
6307
6463
|
configurable: true
|
|
6308
6464
|
},
|
|
6309
6465
|
post: {
|
|
6310
|
-
|
|
6466
|
+
value(path, handler, type, name, middleware2) {
|
|
6311
6467
|
return this.addRoute("POST", path, handler, type, name, middleware2);
|
|
6312
6468
|
},
|
|
6313
6469
|
writable: true,
|
|
6314
6470
|
configurable: true
|
|
6315
6471
|
},
|
|
6316
6472
|
put: {
|
|
6317
|
-
|
|
6473
|
+
value(path, handler, type, name, middleware2) {
|
|
6318
6474
|
return this.addRoute("PUT", path, handler, type, name, middleware2);
|
|
6319
6475
|
},
|
|
6320
6476
|
writable: true,
|
|
6321
6477
|
configurable: true
|
|
6322
6478
|
},
|
|
6323
6479
|
patch: {
|
|
6324
|
-
|
|
6480
|
+
value(path, handler, type, name, middleware2) {
|
|
6325
6481
|
return this.addRoute("PATCH", path, handler, type, name, middleware2);
|
|
6326
6482
|
},
|
|
6327
6483
|
writable: true,
|
|
6328
6484
|
configurable: true
|
|
6329
6485
|
},
|
|
6330
6486
|
delete: {
|
|
6331
|
-
|
|
6487
|
+
value(path, handler, type, name, middleware2) {
|
|
6332
6488
|
return this.addRoute("DELETE", path, handler, type, name, middleware2);
|
|
6333
6489
|
},
|
|
6334
6490
|
writable: true,
|
|
6335
6491
|
configurable: true
|
|
6336
6492
|
},
|
|
6337
6493
|
options: {
|
|
6338
|
-
|
|
6494
|
+
value(path, handler, type, name, middleware2) {
|
|
6339
6495
|
return this.addRoute("OPTIONS", path, handler, type, name, middleware2);
|
|
6340
6496
|
},
|
|
6341
6497
|
writable: true,
|
|
6342
6498
|
configurable: true
|
|
6343
6499
|
},
|
|
6344
6500
|
match: {
|
|
6345
|
-
|
|
6501
|
+
value(methods, path, handler, type, name, middleware2) {
|
|
6346
6502
|
for (const method of methods) {
|
|
6347
|
-
|
|
6503
|
+
this.addRoute(method, path, handler, type, name, middleware2);
|
|
6348
6504
|
}
|
|
6349
6505
|
return this;
|
|
6350
6506
|
},
|
|
@@ -6352,7 +6508,7 @@ function registerHttpMethods(RouterClass) {
|
|
|
6352
6508
|
configurable: true
|
|
6353
6509
|
},
|
|
6354
6510
|
any: {
|
|
6355
|
-
|
|
6511
|
+
value(path, handler, type, name, middleware2) {
|
|
6356
6512
|
const methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"];
|
|
6357
6513
|
return this.match(methods, path, handler, type, name, middleware2);
|
|
6358
6514
|
},
|
|
@@ -6415,8 +6571,8 @@ function registerRedirectMethods(RouterClass) {
|
|
|
6415
6571
|
configurable: true
|
|
6416
6572
|
},
|
|
6417
6573
|
redirectRoute: {
|
|
6418
|
-
|
|
6419
|
-
|
|
6574
|
+
value(from, to, status = 302) {
|
|
6575
|
+
this.get(from, (_req) => {
|
|
6420
6576
|
return this.redirect(to, status);
|
|
6421
6577
|
});
|
|
6422
6578
|
return this;
|
|
@@ -6425,7 +6581,7 @@ function registerRedirectMethods(RouterClass) {
|
|
|
6425
6581
|
configurable: true
|
|
6426
6582
|
},
|
|
6427
6583
|
permanentRedirectRoute: {
|
|
6428
|
-
|
|
6584
|
+
value(from, to) {
|
|
6429
6585
|
return this.redirectRoute(from, to, 301);
|
|
6430
6586
|
},
|
|
6431
6587
|
writable: true,
|
|
@@ -6501,6 +6657,9 @@ function isCallableHandler(handler) {
|
|
|
6501
6657
|
return typeof handler === "function" && !handler.prototype?.handle;
|
|
6502
6658
|
}
|
|
6503
6659
|
async function resolveHandler(handler, req, config2) {
|
|
6660
|
+
if (handler instanceof Response) {
|
|
6661
|
+
return handler.clone();
|
|
6662
|
+
}
|
|
6504
6663
|
if (isCallableHandler(handler)) {
|
|
6505
6664
|
const result = await handler(req);
|
|
6506
6665
|
return wrapResponse(result);
|
|
@@ -6590,9 +6749,9 @@ function createHandlerResolver(config2) {
|
|
|
6590
6749
|
function registerMiddlewareHandling(RouterClass) {
|
|
6591
6750
|
Object.defineProperties(RouterClass.prototype, {
|
|
6592
6751
|
use: {
|
|
6593
|
-
|
|
6752
|
+
value(...middleware2) {
|
|
6594
6753
|
for (const mw of middleware2) {
|
|
6595
|
-
const resolvedMiddleware =
|
|
6754
|
+
const resolvedMiddleware = this.resolveMiddleware(mw);
|
|
6596
6755
|
if (resolvedMiddleware) {
|
|
6597
6756
|
this.globalMiddleware.push(resolvedMiddleware);
|
|
6598
6757
|
}
|
|
@@ -6603,24 +6762,41 @@ function registerMiddlewareHandling(RouterClass) {
|
|
|
6603
6762
|
configurable: true
|
|
6604
6763
|
},
|
|
6605
6764
|
resolveMiddleware: {
|
|
6606
|
-
|
|
6765
|
+
value(middleware2) {
|
|
6607
6766
|
if (typeof middleware2 === "function") {
|
|
6608
6767
|
return middleware2;
|
|
6609
6768
|
}
|
|
6769
|
+
if (typeof middleware2 === "object" && middleware2 !== null && "handle" in middleware2 && typeof middleware2.handle === "function") {
|
|
6770
|
+
return (req, next) => {
|
|
6771
|
+
return middleware2.handle(req, next);
|
|
6772
|
+
};
|
|
6773
|
+
}
|
|
6610
6774
|
if (typeof middleware2 === "string") {
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6775
|
+
const [name, params] = middleware2.split(":");
|
|
6776
|
+
const factory = this.namedMiddleware?.get(name);
|
|
6777
|
+
if (factory) {
|
|
6778
|
+
return factory(params);
|
|
6779
|
+
}
|
|
6780
|
+
let cached = null;
|
|
6781
|
+
const middlewareName = middleware2;
|
|
6782
|
+
return async (req, next) => {
|
|
6783
|
+
if (!cached) {
|
|
6784
|
+
try {
|
|
6785
|
+
const importedMiddleware = await import(`../middleware/${middlewareName}.ts`);
|
|
6786
|
+
if (importedMiddleware.default && typeof importedMiddleware.default === "function") {
|
|
6787
|
+
cached = importedMiddleware.default;
|
|
6788
|
+
} else if (importedMiddleware.default && typeof importedMiddleware.default.handle === "function") {
|
|
6789
|
+
cached = (r, n) => importedMiddleware.default.handle(r, n);
|
|
6790
|
+
}
|
|
6791
|
+
} catch (error) {
|
|
6792
|
+
console.error(`Failed to load middleware "${middlewareName}":`, error);
|
|
6793
|
+
}
|
|
6615
6794
|
}
|
|
6616
|
-
if (
|
|
6617
|
-
return (req, next)
|
|
6618
|
-
return importedMiddleware.default.handle(req, next);
|
|
6619
|
-
};
|
|
6795
|
+
if (cached) {
|
|
6796
|
+
return cached(req, next);
|
|
6620
6797
|
}
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
}
|
|
6798
|
+
return next();
|
|
6799
|
+
};
|
|
6624
6800
|
}
|
|
6625
6801
|
return null;
|
|
6626
6802
|
},
|
|
@@ -6694,9 +6870,9 @@ function registerMiddlewareHandling(RouterClass) {
|
|
|
6694
6870
|
configurable: true
|
|
6695
6871
|
},
|
|
6696
6872
|
applyMiddlewareToRoute: {
|
|
6697
|
-
|
|
6873
|
+
value(route, middleware2) {
|
|
6698
6874
|
for (const mw of middleware2) {
|
|
6699
|
-
const resolvedMiddleware =
|
|
6875
|
+
const resolvedMiddleware = this.resolveMiddleware(mw);
|
|
6700
6876
|
if (resolvedMiddleware) {
|
|
6701
6877
|
route.middleware.push(resolvedMiddleware);
|
|
6702
6878
|
}
|
|
@@ -6718,7 +6894,7 @@ function registerMiddlewareHandling(RouterClass) {
|
|
|
6718
6894
|
configurable: true
|
|
6719
6895
|
},
|
|
6720
6896
|
onError: {
|
|
6721
|
-
|
|
6897
|
+
value(handler) {
|
|
6722
6898
|
this.errorHandler = handler;
|
|
6723
6899
|
return this;
|
|
6724
6900
|
},
|
|
@@ -7124,7 +7300,7 @@ class RouteTrie {
|
|
|
7124
7300
|
optional: paramPart.endsWith("?")
|
|
7125
7301
|
});
|
|
7126
7302
|
} else if (part.includes("{")) {
|
|
7127
|
-
const regex = part.replace(/\{([^}:]+)(?::([^}]+))?\}/g, (
|
|
7303
|
+
const regex = part.replace(/\{([^}:]+)(?::([^}]+))?\}/g, (_match, _name, pattern) => {
|
|
7128
7304
|
return pattern ? `(${pattern})` : "([^/]+)";
|
|
7129
7305
|
});
|
|
7130
7306
|
const paramNames = Array.from(part.matchAll(/\{([^}:]+)(?::([^}]+))?\}/g)).map((match) => match[1].replace("?", ""));
|
|
@@ -7401,7 +7577,8 @@ class RouteCompiler {
|
|
|
7401
7577
|
}
|
|
7402
7578
|
}
|
|
7403
7579
|
convertToURLPattern(path, constraints) {
|
|
7404
|
-
let regexPattern = path.replace(/\{([^}:]+)(?::([^}]+))?\}/g, (
|
|
7580
|
+
let regexPattern = path.replace(/\{([^}:]+)(?::([^}]+))?\}/g, (_match, name, ..._args) => {
|
|
7581
|
+
const pattern = _args[0];
|
|
7405
7582
|
if (constraints && constraints[name]) {
|
|
7406
7583
|
return `(?<${name}>${constraints[name]})`;
|
|
7407
7584
|
} else if (pattern) {
|
|
@@ -7947,7 +8124,7 @@ function registerRouteBuilding(RouterClass) {
|
|
|
7947
8124
|
const apiRoutes = await import(this.config.apiRoutesPath);
|
|
7948
8125
|
if (apiRoutes.default && Array.isArray(apiRoutes.default)) {
|
|
7949
8126
|
for (const route of apiRoutes.default) {
|
|
7950
|
-
|
|
8127
|
+
this.registerRoute(route, "api");
|
|
7951
8128
|
}
|
|
7952
8129
|
}
|
|
7953
8130
|
} catch (error) {
|
|
@@ -7961,7 +8138,7 @@ function registerRouteBuilding(RouterClass) {
|
|
|
7961
8138
|
const webRoutes = await import(this.config.webRoutesPath);
|
|
7962
8139
|
if (webRoutes.default && Array.isArray(webRoutes.default)) {
|
|
7963
8140
|
for (const route of webRoutes.default) {
|
|
7964
|
-
|
|
8141
|
+
this.registerRoute(route, "web");
|
|
7965
8142
|
}
|
|
7966
8143
|
}
|
|
7967
8144
|
} catch (error) {
|
|
@@ -7978,26 +8155,26 @@ function registerRouteBuilding(RouterClass) {
|
|
|
7978
8155
|
configurable: true
|
|
7979
8156
|
},
|
|
7980
8157
|
registerRoute: {
|
|
7981
|
-
|
|
8158
|
+
value(route, type) {
|
|
7982
8159
|
const { path, method, handler, middleware: middleware2 = [], name } = route;
|
|
7983
8160
|
switch (method) {
|
|
7984
8161
|
case "GET":
|
|
7985
|
-
|
|
8162
|
+
this.get(path, handler, type, name, middleware2);
|
|
7986
8163
|
break;
|
|
7987
8164
|
case "POST":
|
|
7988
|
-
|
|
8165
|
+
this.post(path, handler, type, name, middleware2);
|
|
7989
8166
|
break;
|
|
7990
8167
|
case "PUT":
|
|
7991
|
-
|
|
8168
|
+
this.put(path, handler, type, name, middleware2);
|
|
7992
8169
|
break;
|
|
7993
8170
|
case "DELETE":
|
|
7994
|
-
|
|
8171
|
+
this.delete(path, handler, type, name, middleware2);
|
|
7995
8172
|
break;
|
|
7996
8173
|
case "PATCH":
|
|
7997
|
-
|
|
8174
|
+
this.patch(path, handler, type, name, middleware2);
|
|
7998
8175
|
break;
|
|
7999
8176
|
case "OPTIONS":
|
|
8000
|
-
|
|
8177
|
+
this.options(path, handler, type, name, middleware2);
|
|
8001
8178
|
break;
|
|
8002
8179
|
default:
|
|
8003
8180
|
console.warn(`Unsupported HTTP method: ${method}`);
|
|
@@ -8260,6 +8437,7 @@ class Router {
|
|
|
8260
8437
|
templateCache = new Map;
|
|
8261
8438
|
routeCache = new Map;
|
|
8262
8439
|
staticRoutes = new Map;
|
|
8440
|
+
staticResponses = new Map;
|
|
8263
8441
|
precompiledPatterns = new Map;
|
|
8264
8442
|
domainPatternCache = new Map;
|
|
8265
8443
|
routeCompiler = null;
|
|
@@ -8351,10 +8529,24 @@ class Router {
|
|
|
8351
8529
|
}
|
|
8352
8530
|
return this;
|
|
8353
8531
|
}
|
|
8532
|
+
async register(routePath, options) {
|
|
8533
|
+
const callback = async () => {
|
|
8534
|
+
await import(routePath);
|
|
8535
|
+
};
|
|
8536
|
+
if (options?.prefix || options?.middleware && options.middleware.length > 0) {
|
|
8537
|
+
await this.group({
|
|
8538
|
+
prefix: options.prefix,
|
|
8539
|
+
middleware: options.middleware
|
|
8540
|
+
}, callback);
|
|
8541
|
+
} else {
|
|
8542
|
+
await callback();
|
|
8543
|
+
}
|
|
8544
|
+
return this;
|
|
8545
|
+
}
|
|
8354
8546
|
invalidateCache() {
|
|
8355
8547
|
this.routeCache.clear();
|
|
8356
8548
|
}
|
|
8357
|
-
|
|
8549
|
+
registerRoute(method, path, handler, type, name, middleware2) {
|
|
8358
8550
|
let routePath = path;
|
|
8359
8551
|
let routeMiddleware = [];
|
|
8360
8552
|
const routeType = type || "web";
|
|
@@ -8368,7 +8560,7 @@ class Router {
|
|
|
8368
8560
|
}
|
|
8369
8561
|
if (middleware2 && middleware2.length > 0) {
|
|
8370
8562
|
for (const middlewareItem of middleware2) {
|
|
8371
|
-
const resolved =
|
|
8563
|
+
const resolved = this.resolveMiddleware(middlewareItem);
|
|
8372
8564
|
if (resolved) {
|
|
8373
8565
|
routeMiddleware.push(resolved);
|
|
8374
8566
|
}
|
|
@@ -8438,7 +8630,7 @@ class Router {
|
|
|
8438
8630
|
this.routeCache.clear();
|
|
8439
8631
|
return this;
|
|
8440
8632
|
}
|
|
8441
|
-
|
|
8633
|
+
resolveMiddleware(middleware2) {
|
|
8442
8634
|
if (typeof middleware2 === "function") {
|
|
8443
8635
|
return middleware2;
|
|
8444
8636
|
}
|
|
@@ -8449,31 +8641,31 @@ class Router {
|
|
|
8449
8641
|
}
|
|
8450
8642
|
return null;
|
|
8451
8643
|
}
|
|
8452
|
-
|
|
8644
|
+
get(path, handler, type, name, middleware2) {
|
|
8453
8645
|
return this.registerRoute("GET", path, handler, type, name, middleware2);
|
|
8454
8646
|
}
|
|
8455
|
-
|
|
8647
|
+
post(path, handler, type, name, middleware2) {
|
|
8456
8648
|
return this.registerRoute("POST", path, handler, type, name, middleware2);
|
|
8457
8649
|
}
|
|
8458
|
-
|
|
8650
|
+
put(path, handler, type, name, middleware2) {
|
|
8459
8651
|
return this.registerRoute("PUT", path, handler, type, name, middleware2);
|
|
8460
8652
|
}
|
|
8461
|
-
|
|
8653
|
+
patch(path, handler, type, name, middleware2) {
|
|
8462
8654
|
return this.registerRoute("PATCH", path, handler, type, name, middleware2);
|
|
8463
8655
|
}
|
|
8464
|
-
|
|
8656
|
+
delete(path, handler, type, name, middleware2) {
|
|
8465
8657
|
return this.registerRoute("DELETE", path, handler, type, name, middleware2);
|
|
8466
8658
|
}
|
|
8467
|
-
|
|
8659
|
+
options(path, handler, type, name, middleware2) {
|
|
8468
8660
|
return this.registerRoute("OPTIONS", path, handler, type, name, middleware2);
|
|
8469
8661
|
}
|
|
8470
|
-
|
|
8662
|
+
match(methods, path, handler, type, name, middleware2) {
|
|
8471
8663
|
for (const method of methods) {
|
|
8472
|
-
|
|
8664
|
+
this.registerRoute(method, path, handler, type, name, middleware2);
|
|
8473
8665
|
}
|
|
8474
8666
|
return this;
|
|
8475
8667
|
}
|
|
8476
|
-
|
|
8668
|
+
any(path, handler, type, name, middleware2) {
|
|
8477
8669
|
const methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"];
|
|
8478
8670
|
return this.match(methods, path, handler, type, name, middleware2);
|
|
8479
8671
|
}
|
|
@@ -8508,8 +8700,8 @@ class Router {
|
|
|
8508
8700
|
permanentRedirect(url) {
|
|
8509
8701
|
return this.redirect(url, 301);
|
|
8510
8702
|
}
|
|
8511
|
-
|
|
8512
|
-
|
|
8703
|
+
redirectRoute(from, to, status = 302) {
|
|
8704
|
+
this.get(from, (_req) => {
|
|
8513
8705
|
return this.redirect(to, status);
|
|
8514
8706
|
});
|
|
8515
8707
|
return this;
|
|
@@ -9082,9 +9274,9 @@ class Router {
|
|
|
9082
9274
|
}
|
|
9083
9275
|
throw new Error(`Invalid action handler: ${typeof handler}`);
|
|
9084
9276
|
}
|
|
9085
|
-
|
|
9277
|
+
use(...middleware2) {
|
|
9086
9278
|
for (const mw of middleware2) {
|
|
9087
|
-
const resolvedMiddleware =
|
|
9279
|
+
const resolvedMiddleware = this.resolveMiddleware(mw);
|
|
9088
9280
|
if (resolvedMiddleware) {
|
|
9089
9281
|
this.globalMiddleware.push(resolvedMiddleware);
|
|
9090
9282
|
}
|
|
@@ -9238,12 +9430,30 @@ function registerServerHandling(RouterClass) {
|
|
|
9238
9430
|
if (this._initFileRoutes) {
|
|
9239
9431
|
await this._initFileRoutes();
|
|
9240
9432
|
}
|
|
9433
|
+
if (this._initApiRoutes) {
|
|
9434
|
+
await this._initApiRoutes();
|
|
9435
|
+
}
|
|
9241
9436
|
this.invalidateCache();
|
|
9242
9437
|
const serverOptions = {
|
|
9243
9438
|
idleTimeout: 255,
|
|
9244
9439
|
...options,
|
|
9245
9440
|
fetch: this.handleRequest.bind(this)
|
|
9246
9441
|
};
|
|
9442
|
+
const staticRouteMap = {};
|
|
9443
|
+
if (this.staticResponses && this.staticResponses.size > 0) {
|
|
9444
|
+
for (const [path, response2] of this.staticResponses) {
|
|
9445
|
+
staticRouteMap[path] = response2;
|
|
9446
|
+
}
|
|
9447
|
+
}
|
|
9448
|
+
if (options.static) {
|
|
9449
|
+
Object.assign(staticRouteMap, options.static);
|
|
9450
|
+
}
|
|
9451
|
+
if (Object.keys(staticRouteMap).length > 0) {
|
|
9452
|
+
serverOptions.static = staticRouteMap;
|
|
9453
|
+
}
|
|
9454
|
+
if (options.development !== undefined) {
|
|
9455
|
+
serverOptions.development = options.development;
|
|
9456
|
+
}
|
|
9247
9457
|
if (this.wsConfig) {
|
|
9248
9458
|
serverOptions.websocket = this.wsConfig;
|
|
9249
9459
|
}
|
|
@@ -9483,7 +9693,7 @@ function registerServerHandling(RouterClass) {
|
|
|
9483
9693
|
}
|
|
9484
9694
|
|
|
9485
9695
|
// src/router/view-rendering.ts
|
|
9486
|
-
import { join as
|
|
9696
|
+
import { join as join4 } from "path";
|
|
9487
9697
|
function registerViewRendering(RouterClass) {
|
|
9488
9698
|
Object.defineProperties(RouterClass.prototype, {
|
|
9489
9699
|
renderView: {
|
|
@@ -9505,7 +9715,7 @@ function registerViewRendering(RouterClass) {
|
|
|
9505
9715
|
let viewContent = await Bun.file(viewPath).text();
|
|
9506
9716
|
const layoutName = options.layout || viewsConfig.defaultLayout;
|
|
9507
9717
|
if (layoutName) {
|
|
9508
|
-
const layoutPath = await resolveViewPath(
|
|
9718
|
+
const layoutPath = await resolveViewPath(join4("layouts", layoutName), viewsConfig.viewsPath, viewsConfig.extensions);
|
|
9509
9719
|
if (!layoutPath) {
|
|
9510
9720
|
throw new Error(`Layout '${layoutName}' not found`);
|
|
9511
9721
|
}
|
|
@@ -9546,7 +9756,7 @@ function registerViewRendering(RouterClass) {
|
|
|
9546
9756
|
configurable: true
|
|
9547
9757
|
},
|
|
9548
9758
|
view: {
|
|
9549
|
-
|
|
9759
|
+
value(path, viewOrData, dataOrOptions = {}, optionsOrType = {}, typeOrName = "web", name) {
|
|
9550
9760
|
let view;
|
|
9551
9761
|
let data = {};
|
|
9552
9762
|
let options = {};
|
|
@@ -9614,7 +9824,7 @@ function registerViewRendering(RouterClass) {
|
|
|
9614
9824
|
headers
|
|
9615
9825
|
});
|
|
9616
9826
|
};
|
|
9617
|
-
|
|
9827
|
+
this.get(path, handler, type, routeName);
|
|
9618
9828
|
return this;
|
|
9619
9829
|
},
|
|
9620
9830
|
writable: true,
|
|
@@ -10790,6 +11000,120 @@ registerServerHandling(Router);
|
|
|
10790
11000
|
registerRouteBuilding(Router);
|
|
10791
11001
|
registerModelBinding(Router);
|
|
10792
11002
|
registerFileBasedRouting(Router);
|
|
11003
|
+
registerApiRoutes(Router);
|
|
11004
|
+
// src/router/middleware-groups.ts
|
|
11005
|
+
class MiddlewareGroupRegistry {
|
|
11006
|
+
groups = new Map;
|
|
11007
|
+
globalMiddleware = [];
|
|
11008
|
+
middlewarePriority = new Map;
|
|
11009
|
+
define(name, middleware2) {
|
|
11010
|
+
this.groups.set(name, [...middleware2]);
|
|
11011
|
+
return this;
|
|
11012
|
+
}
|
|
11013
|
+
extend(name, middleware2) {
|
|
11014
|
+
const existing = this.groups.get(name) || [];
|
|
11015
|
+
this.groups.set(name, [...existing, ...middleware2]);
|
|
11016
|
+
return this;
|
|
11017
|
+
}
|
|
11018
|
+
prepend(name, middleware2) {
|
|
11019
|
+
const existing = this.groups.get(name) || [];
|
|
11020
|
+
this.groups.set(name, [...middleware2, ...existing]);
|
|
11021
|
+
return this;
|
|
11022
|
+
}
|
|
11023
|
+
get(name) {
|
|
11024
|
+
return this.groups.get(name) || [];
|
|
11025
|
+
}
|
|
11026
|
+
has(name) {
|
|
11027
|
+
return this.groups.has(name);
|
|
11028
|
+
}
|
|
11029
|
+
remove(name) {
|
|
11030
|
+
this.groups.delete(name);
|
|
11031
|
+
return this;
|
|
11032
|
+
}
|
|
11033
|
+
resolve(middleware2) {
|
|
11034
|
+
if (typeof middleware2 === "function") {
|
|
11035
|
+
return [middleware2];
|
|
11036
|
+
}
|
|
11037
|
+
if (this.groups.has(middleware2)) {
|
|
11038
|
+
return this.get(middleware2);
|
|
11039
|
+
}
|
|
11040
|
+
return [middleware2];
|
|
11041
|
+
}
|
|
11042
|
+
resolveAll(middleware2) {
|
|
11043
|
+
const resolved = [];
|
|
11044
|
+
for (const mw of middleware2) {
|
|
11045
|
+
resolved.push(...this.resolve(mw));
|
|
11046
|
+
}
|
|
11047
|
+
return resolved;
|
|
11048
|
+
}
|
|
11049
|
+
pushGlobal(...middleware2) {
|
|
11050
|
+
this.globalMiddleware.push(...middleware2);
|
|
11051
|
+
return this;
|
|
11052
|
+
}
|
|
11053
|
+
prependGlobal(...middleware2) {
|
|
11054
|
+
this.globalMiddleware.unshift(...middleware2);
|
|
11055
|
+
return this;
|
|
11056
|
+
}
|
|
11057
|
+
removeGlobal(middleware2) {
|
|
11058
|
+
this.globalMiddleware = this.globalMiddleware.filter((mw) => typeof mw === "string" ? mw !== middleware2 : true);
|
|
11059
|
+
return this;
|
|
11060
|
+
}
|
|
11061
|
+
getGlobal() {
|
|
11062
|
+
return [...this.globalMiddleware];
|
|
11063
|
+
}
|
|
11064
|
+
setPriority(name, priority) {
|
|
11065
|
+
this.middlewarePriority.set(name, priority);
|
|
11066
|
+
return this;
|
|
11067
|
+
}
|
|
11068
|
+
sortByPriority(middleware2) {
|
|
11069
|
+
return [...middleware2].sort((a, b) => {
|
|
11070
|
+
const nameA = typeof a === "string" ? a.split(":")[0] : "";
|
|
11071
|
+
const nameB = typeof b === "string" ? b.split(":")[0] : "";
|
|
11072
|
+
const priorityA = this.middlewarePriority.get(nameA) ?? 100;
|
|
11073
|
+
const priorityB = this.middlewarePriority.get(nameB) ?? 100;
|
|
11074
|
+
return priorityA - priorityB;
|
|
11075
|
+
});
|
|
11076
|
+
}
|
|
11077
|
+
filter(middleware2, options) {
|
|
11078
|
+
if (options.only && options.only.length > 0) {
|
|
11079
|
+
return middleware2.filter((mw) => {
|
|
11080
|
+
if (typeof mw === "string") {
|
|
11081
|
+
const name = mw.split(":")[0];
|
|
11082
|
+
return options.only.includes(name);
|
|
11083
|
+
}
|
|
11084
|
+
return false;
|
|
11085
|
+
});
|
|
11086
|
+
}
|
|
11087
|
+
if (options.except && options.except.length > 0) {
|
|
11088
|
+
return middleware2.filter((mw) => {
|
|
11089
|
+
if (typeof mw === "string") {
|
|
11090
|
+
const name = mw.split(":")[0];
|
|
11091
|
+
return !options.except.includes(name);
|
|
11092
|
+
}
|
|
11093
|
+
return true;
|
|
11094
|
+
});
|
|
11095
|
+
}
|
|
11096
|
+
return middleware2;
|
|
11097
|
+
}
|
|
11098
|
+
flush() {
|
|
11099
|
+
this.groups.clear();
|
|
11100
|
+
this.globalMiddleware = [];
|
|
11101
|
+
this.middlewarePriority.clear();
|
|
11102
|
+
}
|
|
11103
|
+
}
|
|
11104
|
+
var middlewareGroups = new MiddlewareGroupRegistry;
|
|
11105
|
+
middlewareGroups.define("web", ["session", "csrf", "cors"]);
|
|
11106
|
+
middlewareGroups.define("api", ["throttle:60,1", "cors"]);
|
|
11107
|
+
middlewareGroups.setPriority("session", 10);
|
|
11108
|
+
middlewareGroups.setPriority("cors", 20);
|
|
11109
|
+
middlewareGroups.setPriority("csrf", 30);
|
|
11110
|
+
middlewareGroups.setPriority("auth", 40);
|
|
11111
|
+
middlewareGroups.setPriority("throttle", 50);
|
|
11112
|
+
middlewareGroups.setPriority("role", 60);
|
|
11113
|
+
middlewareGroups.setPriority("permission", 60);
|
|
11114
|
+
middlewareGroups.setPriority("can", 70);
|
|
11115
|
+
middlewareGroups.setPriority("abilities", 70);
|
|
11116
|
+
middlewareGroups.setPriority("verified", 80);
|
|
10793
11117
|
// src/testing/auth-testing.ts
|
|
10794
11118
|
import { mock } from "bun:test";
|
|
10795
11119
|
|
|
@@ -11029,14 +11353,16 @@ class AuthTester {
|
|
|
11029
11353
|
return this;
|
|
11030
11354
|
}
|
|
11031
11355
|
withApiKey(apiKey, headerName = "X-API-Key") {
|
|
11032
|
-
|
|
11033
|
-
|
|
11356
|
+
const headers = new Headers(this.request.headers);
|
|
11357
|
+
headers.set(headerName, apiKey);
|
|
11358
|
+
this.request = { ...this.request, headers };
|
|
11034
11359
|
return this;
|
|
11035
11360
|
}
|
|
11036
11361
|
withBasicAuth(username, password) {
|
|
11037
11362
|
const credentials = btoa(`${username}:${password}`);
|
|
11038
|
-
|
|
11039
|
-
|
|
11363
|
+
const headers = new Headers(this.request.headers);
|
|
11364
|
+
headers.set("Authorization", `Basic ${credentials}`);
|
|
11365
|
+
this.request = { ...this.request, headers };
|
|
11040
11366
|
return this;
|
|
11041
11367
|
}
|
|
11042
11368
|
withAuthCookies(cookies) {
|
|
@@ -11667,13 +11993,13 @@ var mockMiddleware = {
|
|
|
11667
11993
|
return new Response("Unauthorized", { status: 401 });
|
|
11668
11994
|
}
|
|
11669
11995
|
}),
|
|
11670
|
-
rateLimit: (shouldLimit = false) => mock3(async (
|
|
11996
|
+
rateLimit: (shouldLimit = false) => mock3(async (_req, next) => {
|
|
11671
11997
|
if (shouldLimit) {
|
|
11672
11998
|
return new Response("Too Many Requests", { status: 429 });
|
|
11673
11999
|
}
|
|
11674
12000
|
return await next();
|
|
11675
12001
|
}),
|
|
11676
|
-
cors: (origin = "*") => mock3(async (
|
|
12002
|
+
cors: (origin = "*") => mock3(async (_req, next) => {
|
|
11677
12003
|
const response2 = await next();
|
|
11678
12004
|
if (response2) {
|
|
11679
12005
|
response2.headers.set("Access-Control-Allow-Origin", origin);
|
|
@@ -11722,7 +12048,7 @@ function spyOnMiddleware(middleware2) {
|
|
|
11722
12048
|
return spyOn(middleware2, "call");
|
|
11723
12049
|
}
|
|
11724
12050
|
function createMiddlewareSpy() {
|
|
11725
|
-
const spy = mock3(async (
|
|
12051
|
+
const spy = mock3(async (_req, next) => {
|
|
11726
12052
|
return await next();
|
|
11727
12053
|
});
|
|
11728
12054
|
return {
|
|
@@ -12218,7 +12544,7 @@ class LoadTester {
|
|
|
12218
12544
|
requestPromises.push(requestPromise);
|
|
12219
12545
|
if (this.config.requestsPerSecond) {
|
|
12220
12546
|
const delay = 1000 / this.config.requestsPerSecond;
|
|
12221
|
-
await new Promise((
|
|
12547
|
+
await new Promise((resolve3) => setTimeout(resolve3, delay));
|
|
12222
12548
|
}
|
|
12223
12549
|
if (requestPromises.length >= this.config.concurrency) {
|
|
12224
12550
|
await Promise.race(requestPromises);
|
|
@@ -13276,6 +13602,7 @@ export {
|
|
|
13276
13602
|
multipleFileUpload,
|
|
13277
13603
|
modelMocks,
|
|
13278
13604
|
mockMiddleware,
|
|
13605
|
+
middlewareGroups,
|
|
13279
13606
|
middleware,
|
|
13280
13607
|
memoryTests,
|
|
13281
13608
|
matchPath,
|
|
@@ -13289,6 +13616,7 @@ export {
|
|
|
13289
13616
|
imageUpload,
|
|
13290
13617
|
globalMiddlewarePipeline,
|
|
13291
13618
|
getConfig,
|
|
13619
|
+
generateSessionId,
|
|
13292
13620
|
generateQueryPreservationScript,
|
|
13293
13621
|
fileUploadScenarios,
|
|
13294
13622
|
fileUploadMocks,
|
|
@@ -13309,6 +13637,7 @@ export {
|
|
|
13309
13637
|
createTestClient,
|
|
13310
13638
|
createSubdomainMiddleware,
|
|
13311
13639
|
createSessionTester,
|
|
13640
|
+
createSessionStore,
|
|
13312
13641
|
createRouteCacheMiddleware,
|
|
13313
13642
|
createRateLimitMiddleware,
|
|
13314
13643
|
createPerformanceTester,
|
|
@@ -13351,6 +13680,7 @@ export {
|
|
|
13351
13680
|
SkipConditions,
|
|
13352
13681
|
SignatureError,
|
|
13353
13682
|
SessionTester,
|
|
13683
|
+
SessionManager,
|
|
13354
13684
|
Session,
|
|
13355
13685
|
SecuritySuite,
|
|
13356
13686
|
Security,
|
|
@@ -13367,6 +13697,7 @@ export {
|
|
|
13367
13697
|
RequestTracer,
|
|
13368
13698
|
RequestSigning,
|
|
13369
13699
|
RequestId,
|
|
13700
|
+
RedisSessionStore,
|
|
13370
13701
|
RateLimiter,
|
|
13371
13702
|
RateLimitUtils,
|
|
13372
13703
|
RateLimitRegistry,
|
|
@@ -13384,8 +13715,10 @@ export {
|
|
|
13384
13715
|
MiddlewareTester,
|
|
13385
13716
|
MiddlewarePipeline,
|
|
13386
13717
|
MiddlewareHelpers,
|
|
13718
|
+
MiddlewareGroupRegistry,
|
|
13387
13719
|
MiddlewareFactory,
|
|
13388
13720
|
MiddlewareChainTester,
|
|
13721
|
+
MemorySessionStore,
|
|
13389
13722
|
LoadTester,
|
|
13390
13723
|
JsonBody,
|
|
13391
13724
|
JWTTester,
|
|
@@ -13399,6 +13732,7 @@ export {
|
|
|
13399
13732
|
FileValidationTester,
|
|
13400
13733
|
FileUploadTester,
|
|
13401
13734
|
FileUpload,
|
|
13735
|
+
FileSessionStore,
|
|
13402
13736
|
FileSecurity,
|
|
13403
13737
|
exports_errors as Errors,
|
|
13404
13738
|
EnhancementPresets,
|
|
@@ -13406,6 +13740,7 @@ export {
|
|
|
13406
13740
|
DomainGroupBuilder,
|
|
13407
13741
|
DomainGroup,
|
|
13408
13742
|
Dependencies,
|
|
13743
|
+
DatabaseSessionStore,
|
|
13409
13744
|
DDoSProtection,
|
|
13410
13745
|
Csrf,
|
|
13411
13746
|
Cors,
|