@getstrata/bootstrap 0.2.13 → 0.2.17
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/bootstrap/http/securedRouteModelBinding.d.ts +2 -11
- package/dist/bootstrap/membershipService.d.ts +1 -3
- package/dist/core/auth/membershipService.d.ts +1 -1
- package/dist/core/auth/resolveMembershipService.d.ts +3 -0
- package/dist/core/http/securedRouteModelBinding.d.ts +11 -2
- package/dist/core/queue/createAppQueue.d.ts +0 -1
- package/dist/core/queue/jobRegistry.d.ts +0 -1
- package/dist/entries/cache/modelCacheTags.js +22 -0
- package/dist/entries/context.js +128 -119
- package/dist/entries/http/securedRouteModelBinding.js +100 -99
- package/dist/entries/membershipService.js +100 -99
- package/dist/entries/providers.js +214 -205
- package/dist/entries/queue/defaultJobs.js +12 -2
- package/dist/entries/web/forms.js +53 -0
- package/dist/entries/web/routing.js +624 -0
- package/dist/entries/web/server.js +57 -0
- package/dist/entries/web/session.js +99 -0
- package/dist/entries/web/slug.js +8 -0
- package/dist/framework/public-api.d.ts +0 -1
- package/dist/index.js +82 -73
- package/package.json +33 -3
- package/dist/core/cache/modelCacheTags.d.ts +0 -1
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
interface RouteModelAuthorization {
|
|
4
|
-
resource: string;
|
|
5
|
-
action: keyof Policy;
|
|
6
|
-
requireIfMatch?: boolean;
|
|
7
|
-
}
|
|
8
|
-
declare function securedBindRouteModel<TParams extends Record<string, string>, TModel, TParam extends keyof TParams & string>(param: TParam, resolver: (id: number, request: RouteRequest<TParams>) => Promise<TModel>, authorization: RouteModelAuthorization, handler: (request: RouteRequest<TParams>, model: TModel) => Response | Promise<Response>): (request: RouteRequest<TParams>) => Promise<Response>;
|
|
9
|
-
declare function securedBindRouteModelByKey<TParams extends Record<string, string>, TModel, TParam extends keyof TParams & string>(param: TParam, resolver: (key: string, request: RouteRequest<TParams>) => Promise<TModel>, authorization: RouteModelAuthorization, handler: (request: RouteRequest<TParams>, model: TModel) => Response | Promise<Response>): (request: RouteRequest<TParams>) => Promise<Response>;
|
|
10
|
-
export type { RouteModelAuthorization };
|
|
11
|
-
export { securedBindRouteModel, securedBindRouteModelByKey };
|
|
1
|
+
export type { RouteModelAuthorization } from "../../core/http/securedRouteModelBinding.ts";
|
|
2
|
+
export { securedBindRouteModel, securedBindRouteModelByKey, } from "../../core/http/securedRouteModelBinding.ts";
|
|
@@ -20,4 +20,4 @@ declare class MembershipService {
|
|
|
20
20
|
}
|
|
21
21
|
export type { MembershipRepositoryLike };
|
|
22
22
|
export default MembershipService;
|
|
23
|
-
export { resolveMembershipService } from "
|
|
23
|
+
export { resolveMembershipService } from "./resolveMembershipService.ts";
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import type { Policy } from "../auth/policy";
|
|
2
|
+
import type { RouteRequest } from "./route";
|
|
3
|
+
interface RouteModelAuthorization {
|
|
4
|
+
resource: string;
|
|
5
|
+
action: keyof Policy;
|
|
6
|
+
requireIfMatch?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare function securedBindRouteModel<TParams extends Record<string, string>, TModel, TParam extends keyof TParams & string>(param: TParam, resolver: (id: number, request: RouteRequest<TParams>) => Promise<TModel>, authorization: RouteModelAuthorization, handler: (request: RouteRequest<TParams>, model: TModel) => Response | Promise<Response>): (request: RouteRequest<TParams>) => Promise<Response>;
|
|
9
|
+
declare function securedBindRouteModelByKey<TParams extends Record<string, string>, TModel, TParam extends keyof TParams & string>(param: TParam, resolver: (key: string, request: RouteRequest<TParams>) => Promise<TModel>, authorization: RouteModelAuthorization, handler: (request: RouteRequest<TParams>, model: TModel) => Response | Promise<Response>): (request: RouteRequest<TParams>) => Promise<Response>;
|
|
10
|
+
export type { RouteModelAuthorization };
|
|
11
|
+
export { securedBindRouteModel, securedBindRouteModelByKey };
|
|
@@ -2,5 +2,4 @@ import type { Queue } from "./index";
|
|
|
2
2
|
import { createFailedJobService, createQueueWorker, createTrackedJob, type FailedJobService } from "./publicQueue";
|
|
3
3
|
declare const FAILED_JOB_SERVICE_TOKEN = "core.failedJobs";
|
|
4
4
|
declare function createAppQueue(driver: "sync" | "async" | "redis", redisUrl?: string, failedJobs?: FailedJobService, registerJobs?: () => void): Queue;
|
|
5
|
-
export { registerDefaultJobs } from "../../bootstrap/queue/defaultJobs.ts";
|
|
6
5
|
export { createAppQueue, createFailedJobService, createQueueWorker, createTrackedJob, FAILED_JOB_SERVICE_TOKEN, };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// ../../src/bootstrap/discoverModules.ts
|
|
3
|
+
var appModules = [];
|
|
4
|
+
function discoverModules() {
|
|
5
|
+
return appModules;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// ../../src/bootstrap/cache/modelCacheTags.ts
|
|
9
|
+
function cacheTagsForModelWrite(tableName, action) {
|
|
10
|
+
const module = discoverModules().find((entry) => entry.tableName === tableName);
|
|
11
|
+
const baseTags = module?.cacheTags ?? [`${tableName}s`];
|
|
12
|
+
const isDelete = action === "deleted" || action === "force-deleted";
|
|
13
|
+
const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
|
|
14
|
+
return [...new Set([...baseTags, ...extraTags])];
|
|
15
|
+
}
|
|
16
|
+
function discoverModelTableNames() {
|
|
17
|
+
return discoverModules().map((module) => module.tableName).filter((tableName) => tableName !== undefined);
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
discoverModelTableNames,
|
|
21
|
+
cacheTagsForModelWrite
|
|
22
|
+
};
|
package/dist/entries/context.js
CHANGED
|
@@ -3265,7 +3265,6 @@ var failedJobService_default = FailedJobService;
|
|
|
3265
3265
|
|
|
3266
3266
|
// ../../src/core/queue/jobRegistry.ts
|
|
3267
3267
|
class JobRegistry {
|
|
3268
|
-
constructor() {}
|
|
3269
3268
|
factories = new Map;
|
|
3270
3269
|
instances = new WeakMap;
|
|
3271
3270
|
register(name, factory) {
|
|
@@ -3289,7 +3288,17 @@ class JobRegistry {
|
|
|
3289
3288
|
return [...this.factories.keys()];
|
|
3290
3289
|
}
|
|
3291
3290
|
}
|
|
3292
|
-
var
|
|
3291
|
+
var JOB_REGISTRY_KEY = Symbol.for("@getstrata/jobRegistry");
|
|
3292
|
+
function readSharedJobRegistry() {
|
|
3293
|
+
const globalRegistry = globalThis[JOB_REGISTRY_KEY];
|
|
3294
|
+
if (globalRegistry) {
|
|
3295
|
+
return globalRegistry;
|
|
3296
|
+
}
|
|
3297
|
+
const registry = new JobRegistry;
|
|
3298
|
+
globalThis[JOB_REGISTRY_KEY] = registry;
|
|
3299
|
+
return registry;
|
|
3300
|
+
}
|
|
3301
|
+
var jobRegistry = readSharedJobRegistry();
|
|
3293
3302
|
|
|
3294
3303
|
// ../../src/core/queue/jobRunner.ts
|
|
3295
3304
|
async function runQueueJob(envelope, failedJobs) {
|
|
@@ -3405,6 +3414,123 @@ function createProductionQueue(driver, options = {}) {
|
|
|
3405
3414
|
return new ResilientQueue(failedJobs, driver === "async");
|
|
3406
3415
|
}
|
|
3407
3416
|
|
|
3417
|
+
// ../../src/core/queue/createAppQueue.ts
|
|
3418
|
+
var FAILED_JOB_SERVICE_TOKEN = "core.failedJobs";
|
|
3419
|
+
function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(), registerJobs) {
|
|
3420
|
+
return createProductionQueue(driver, {
|
|
3421
|
+
redisUrl,
|
|
3422
|
+
failedJobs,
|
|
3423
|
+
registerJobs
|
|
3424
|
+
});
|
|
3425
|
+
}
|
|
3426
|
+
|
|
3427
|
+
// ../../src/bootstrap/cache/modelCacheTags.ts
|
|
3428
|
+
function cacheTagsForModelWrite(tableName, action) {
|
|
3429
|
+
const module = discoverModules().find((entry) => entry.tableName === tableName);
|
|
3430
|
+
const baseTags = module?.cacheTags ?? [`${tableName}s`];
|
|
3431
|
+
const isDelete = action === "deleted" || action === "force-deleted";
|
|
3432
|
+
const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
|
|
3433
|
+
return [...new Set([...baseTags, ...extraTags])];
|
|
3434
|
+
}
|
|
3435
|
+
function discoverModelTableNames() {
|
|
3436
|
+
return discoverModules().map((module) => module.tableName).filter((tableName) => tableName !== undefined);
|
|
3437
|
+
}
|
|
3438
|
+
|
|
3439
|
+
// ../../src/bootstrap/listeners/invalidateCacheOnModelWrite.ts
|
|
3440
|
+
var MODEL_WRITE_ACTIONS = ["created", "updated", "deleted", "restored", "force-deleted"];
|
|
3441
|
+
function registerInvalidateCacheOnModelWriteListeners(bus = eventBus) {
|
|
3442
|
+
for (const tableName of discoverModelTableNames()) {
|
|
3443
|
+
for (const action of MODEL_WRITE_ACTIONS) {
|
|
3444
|
+
bus.listen(modelEventName(tableName, action), async () => {
|
|
3445
|
+
const tags = cacheTagsForModelWrite(tableName, action);
|
|
3446
|
+
if (tags.length === 0) {
|
|
3447
|
+
return;
|
|
3448
|
+
}
|
|
3449
|
+
let cache;
|
|
3450
|
+
let queue;
|
|
3451
|
+
try {
|
|
3452
|
+
cache = resolveApplicationCache();
|
|
3453
|
+
queue = resolveApplicationQueue();
|
|
3454
|
+
} catch {
|
|
3455
|
+
return;
|
|
3456
|
+
}
|
|
3457
|
+
const job = createTrackedJob("cache.invalidate-tags", new invalidateCacheTagsJob_default(cache));
|
|
3458
|
+
await queue.dispatch(job, { tags });
|
|
3459
|
+
});
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3464
|
+
// ../../src/bootstrap/providers/listeners.ts
|
|
3465
|
+
var registeredListenerGroups = new Set;
|
|
3466
|
+
function registerListenerGroup(name, register) {
|
|
3467
|
+
if (registeredListenerGroups.has(name)) {
|
|
3468
|
+
return;
|
|
3469
|
+
}
|
|
3470
|
+
registeredListenerGroups.add(name);
|
|
3471
|
+
register();
|
|
3472
|
+
}
|
|
3473
|
+
var listenersProvider = {
|
|
3474
|
+
name: "core.listeners",
|
|
3475
|
+
boot() {
|
|
3476
|
+
registerListenerGroup("cache.invalidate-on-model-write", () => {
|
|
3477
|
+
registerInvalidateCacheOnModelWriteListeners();
|
|
3478
|
+
});
|
|
3479
|
+
for (const [index, registerListener] of discoverListeners().entries()) {
|
|
3480
|
+
registerListenerGroup(`app.listener.${index}`, registerListener);
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
};
|
|
3484
|
+
var listeners_default = listenersProvider;
|
|
3485
|
+
|
|
3486
|
+
// ../../src/core/auth/policy.ts
|
|
3487
|
+
var BLOCKED_POLICY_ACTIONS = new Set([
|
|
3488
|
+
"constructor",
|
|
3489
|
+
"toString",
|
|
3490
|
+
"valueOf",
|
|
3491
|
+
"hasOwnProperty",
|
|
3492
|
+
"isPrototypeOf",
|
|
3493
|
+
"propertyIsEnumerable",
|
|
3494
|
+
"__proto__"
|
|
3495
|
+
]);
|
|
3496
|
+
|
|
3497
|
+
class PolicyGate {
|
|
3498
|
+
constructor() {}
|
|
3499
|
+
policies = new Map;
|
|
3500
|
+
register(resource, policy) {
|
|
3501
|
+
this.policies.set(resource, policy);
|
|
3502
|
+
}
|
|
3503
|
+
allows(resource, action, user, model) {
|
|
3504
|
+
const policy = this.policies.get(resource);
|
|
3505
|
+
if (!policy) {
|
|
3506
|
+
return false;
|
|
3507
|
+
}
|
|
3508
|
+
if (BLOCKED_POLICY_ACTIONS.has(action) || !(action in policy)) {
|
|
3509
|
+
return false;
|
|
3510
|
+
}
|
|
3511
|
+
const handler = policy[action];
|
|
3512
|
+
if (typeof handler !== "function") {
|
|
3513
|
+
return false;
|
|
3514
|
+
}
|
|
3515
|
+
const resolvedUser = user === undefined ? currentAuthUser() : user;
|
|
3516
|
+
return model === undefined ? handler.call(policy, resolvedUser) : handler.call(policy, resolvedUser, model);
|
|
3517
|
+
}
|
|
3518
|
+
authorize(resource, action, user, model) {
|
|
3519
|
+
if (!this.allows(resource, action, user, model)) {
|
|
3520
|
+
throw new ForbiddenError2;
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
// ../../src/bootstrap/providers/policy.ts
|
|
3526
|
+
var policyProvider = {
|
|
3527
|
+
name: "core.policy",
|
|
3528
|
+
register({ container }) {
|
|
3529
|
+
container.set(CORE_POLICY_GATE_TOKEN, new PolicyGate);
|
|
3530
|
+
}
|
|
3531
|
+
};
|
|
3532
|
+
var policy_default = policyProvider;
|
|
3533
|
+
|
|
3408
3534
|
// ../../src/core/jobs/dispatchWebhookJob.ts
|
|
3409
3535
|
import { createHmac as createHmac2 } from "crypto";
|
|
3410
3536
|
|
|
@@ -3600,123 +3726,6 @@ function registerDefaultJobs() {
|
|
|
3600
3726
|
jobRegistry.register("webhook.dispatch", () => new dispatchWebhookJob_default);
|
|
3601
3727
|
}
|
|
3602
3728
|
|
|
3603
|
-
// ../../src/core/queue/createAppQueue.ts
|
|
3604
|
-
var FAILED_JOB_SERVICE_TOKEN = "core.failedJobs";
|
|
3605
|
-
function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(), registerJobs) {
|
|
3606
|
-
return createProductionQueue(driver, {
|
|
3607
|
-
redisUrl,
|
|
3608
|
-
failedJobs,
|
|
3609
|
-
registerJobs
|
|
3610
|
-
});
|
|
3611
|
-
}
|
|
3612
|
-
|
|
3613
|
-
// ../../src/bootstrap/cache/modelCacheTags.ts
|
|
3614
|
-
function cacheTagsForModelWrite(tableName, action) {
|
|
3615
|
-
const module = discoverModules().find((entry) => entry.tableName === tableName);
|
|
3616
|
-
const baseTags = module?.cacheTags ?? [`${tableName}s`];
|
|
3617
|
-
const isDelete = action === "deleted" || action === "force-deleted";
|
|
3618
|
-
const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
|
|
3619
|
-
return [...new Set([...baseTags, ...extraTags])];
|
|
3620
|
-
}
|
|
3621
|
-
function discoverModelTableNames() {
|
|
3622
|
-
return discoverModules().map((module) => module.tableName).filter((tableName) => tableName !== undefined);
|
|
3623
|
-
}
|
|
3624
|
-
|
|
3625
|
-
// ../../src/bootstrap/listeners/invalidateCacheOnModelWrite.ts
|
|
3626
|
-
var MODEL_WRITE_ACTIONS = ["created", "updated", "deleted", "restored", "force-deleted"];
|
|
3627
|
-
function registerInvalidateCacheOnModelWriteListeners(bus = eventBus) {
|
|
3628
|
-
for (const tableName of discoverModelTableNames()) {
|
|
3629
|
-
for (const action of MODEL_WRITE_ACTIONS) {
|
|
3630
|
-
bus.listen(modelEventName(tableName, action), async () => {
|
|
3631
|
-
const tags = cacheTagsForModelWrite(tableName, action);
|
|
3632
|
-
if (tags.length === 0) {
|
|
3633
|
-
return;
|
|
3634
|
-
}
|
|
3635
|
-
let cache;
|
|
3636
|
-
let queue;
|
|
3637
|
-
try {
|
|
3638
|
-
cache = resolveApplicationCache();
|
|
3639
|
-
queue = resolveApplicationQueue();
|
|
3640
|
-
} catch {
|
|
3641
|
-
return;
|
|
3642
|
-
}
|
|
3643
|
-
const job = createTrackedJob("cache.invalidate-tags", new invalidateCacheTagsJob_default(cache));
|
|
3644
|
-
await queue.dispatch(job, { tags });
|
|
3645
|
-
});
|
|
3646
|
-
}
|
|
3647
|
-
}
|
|
3648
|
-
}
|
|
3649
|
-
|
|
3650
|
-
// ../../src/bootstrap/providers/listeners.ts
|
|
3651
|
-
var registeredListenerGroups = new Set;
|
|
3652
|
-
function registerListenerGroup(name, register) {
|
|
3653
|
-
if (registeredListenerGroups.has(name)) {
|
|
3654
|
-
return;
|
|
3655
|
-
}
|
|
3656
|
-
registeredListenerGroups.add(name);
|
|
3657
|
-
register();
|
|
3658
|
-
}
|
|
3659
|
-
var listenersProvider = {
|
|
3660
|
-
name: "core.listeners",
|
|
3661
|
-
boot() {
|
|
3662
|
-
registerListenerGroup("cache.invalidate-on-model-write", () => {
|
|
3663
|
-
registerInvalidateCacheOnModelWriteListeners();
|
|
3664
|
-
});
|
|
3665
|
-
for (const [index, registerListener] of discoverListeners().entries()) {
|
|
3666
|
-
registerListenerGroup(`app.listener.${index}`, registerListener);
|
|
3667
|
-
}
|
|
3668
|
-
}
|
|
3669
|
-
};
|
|
3670
|
-
var listeners_default = listenersProvider;
|
|
3671
|
-
|
|
3672
|
-
// ../../src/core/auth/policy.ts
|
|
3673
|
-
var BLOCKED_POLICY_ACTIONS = new Set([
|
|
3674
|
-
"constructor",
|
|
3675
|
-
"toString",
|
|
3676
|
-
"valueOf",
|
|
3677
|
-
"hasOwnProperty",
|
|
3678
|
-
"isPrototypeOf",
|
|
3679
|
-
"propertyIsEnumerable",
|
|
3680
|
-
"__proto__"
|
|
3681
|
-
]);
|
|
3682
|
-
|
|
3683
|
-
class PolicyGate {
|
|
3684
|
-
constructor() {}
|
|
3685
|
-
policies = new Map;
|
|
3686
|
-
register(resource, policy) {
|
|
3687
|
-
this.policies.set(resource, policy);
|
|
3688
|
-
}
|
|
3689
|
-
allows(resource, action, user, model) {
|
|
3690
|
-
const policy = this.policies.get(resource);
|
|
3691
|
-
if (!policy) {
|
|
3692
|
-
return false;
|
|
3693
|
-
}
|
|
3694
|
-
if (BLOCKED_POLICY_ACTIONS.has(action) || !(action in policy)) {
|
|
3695
|
-
return false;
|
|
3696
|
-
}
|
|
3697
|
-
const handler = policy[action];
|
|
3698
|
-
if (typeof handler !== "function") {
|
|
3699
|
-
return false;
|
|
3700
|
-
}
|
|
3701
|
-
const resolvedUser = user === undefined ? currentAuthUser() : user;
|
|
3702
|
-
return model === undefined ? handler.call(policy, resolvedUser) : handler.call(policy, resolvedUser, model);
|
|
3703
|
-
}
|
|
3704
|
-
authorize(resource, action, user, model) {
|
|
3705
|
-
if (!this.allows(resource, action, user, model)) {
|
|
3706
|
-
throw new ForbiddenError2;
|
|
3707
|
-
}
|
|
3708
|
-
}
|
|
3709
|
-
}
|
|
3710
|
-
|
|
3711
|
-
// ../../src/bootstrap/providers/policy.ts
|
|
3712
|
-
var policyProvider = {
|
|
3713
|
-
name: "core.policy",
|
|
3714
|
-
register({ container }) {
|
|
3715
|
-
container.set(CORE_POLICY_GATE_TOKEN, new PolicyGate);
|
|
3716
|
-
}
|
|
3717
|
-
};
|
|
3718
|
-
var policy_default = policyProvider;
|
|
3719
|
-
|
|
3720
3729
|
// ../../src/bootstrap/providers/queue.ts
|
|
3721
3730
|
var queueProvider = {
|
|
3722
3731
|
name: "core.queue",
|
|
@@ -64,6 +64,105 @@ class PreconditionFailedError extends HttpError {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
// ../../src/core/contracts/applicationContext.ts
|
|
68
|
+
function getRequiredDependency(dependencies, key) {
|
|
69
|
+
const dependency = dependencies[key];
|
|
70
|
+
if (dependency === undefined) {
|
|
71
|
+
throw new Error(`Required dependency "${String(key)}" is not registered.`);
|
|
72
|
+
}
|
|
73
|
+
return dependency;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ../../src/core/contracts/serviceTokens.ts
|
|
77
|
+
var CORE_CONFIG_TOKEN = "core.config";
|
|
78
|
+
var CORE_CACHE_TOKEN = "core.cache";
|
|
79
|
+
var CORE_QUEUE_TOKEN = "core.queue";
|
|
80
|
+
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
81
|
+
var CORE_AUTH_TOKEN = "core.auth";
|
|
82
|
+
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
83
|
+
|
|
84
|
+
// ../../src/core/logging/logger.ts
|
|
85
|
+
class Logger {
|
|
86
|
+
channel;
|
|
87
|
+
constructor(channel = "app") {
|
|
88
|
+
this.channel = channel;
|
|
89
|
+
}
|
|
90
|
+
write(level, message, context = {}) {
|
|
91
|
+
const entry = {
|
|
92
|
+
level,
|
|
93
|
+
channel: this.channel,
|
|
94
|
+
message,
|
|
95
|
+
timestamp: new Date().toISOString(),
|
|
96
|
+
...context
|
|
97
|
+
};
|
|
98
|
+
const line = JSON.stringify(entry);
|
|
99
|
+
if (level === "error") {
|
|
100
|
+
console.error(line);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
console.log(line);
|
|
104
|
+
}
|
|
105
|
+
debug(message, context) {
|
|
106
|
+
this.write("debug", message, context);
|
|
107
|
+
}
|
|
108
|
+
info(message, context) {
|
|
109
|
+
this.write("info", message, context);
|
|
110
|
+
}
|
|
111
|
+
warn(message, context) {
|
|
112
|
+
this.write("warn", message, context);
|
|
113
|
+
}
|
|
114
|
+
error(message, context) {
|
|
115
|
+
this.write("error", message, context);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
var appLogger = new Logger("app");
|
|
119
|
+
|
|
120
|
+
// ../../src/core/runtime/applicationRegistry.ts
|
|
121
|
+
var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
|
|
122
|
+
var activeContext;
|
|
123
|
+
function readStoredApplicationContext() {
|
|
124
|
+
if (activeContext) {
|
|
125
|
+
return activeContext;
|
|
126
|
+
}
|
|
127
|
+
const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
|
|
128
|
+
if (globalContext) {
|
|
129
|
+
activeContext = globalContext;
|
|
130
|
+
}
|
|
131
|
+
return activeContext;
|
|
132
|
+
}
|
|
133
|
+
function setActiveApplicationContext(context) {
|
|
134
|
+
activeContext = context;
|
|
135
|
+
globalThis[APPLICATION_CONTEXT_KEY] = context;
|
|
136
|
+
}
|
|
137
|
+
function requireActiveApplicationContext() {
|
|
138
|
+
const context = readStoredApplicationContext();
|
|
139
|
+
if (!context) {
|
|
140
|
+
throw new Error("The application context has not been bootstrapped.");
|
|
141
|
+
}
|
|
142
|
+
return context;
|
|
143
|
+
}
|
|
144
|
+
function resolveApplicationCache() {
|
|
145
|
+
return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
|
|
146
|
+
}
|
|
147
|
+
function resolveApplicationQueue() {
|
|
148
|
+
return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
|
|
149
|
+
}
|
|
150
|
+
function resolveApplicationAuth() {
|
|
151
|
+
return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
|
|
152
|
+
}
|
|
153
|
+
function resolveApplicationPolicyGate() {
|
|
154
|
+
return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
|
|
155
|
+
}
|
|
156
|
+
function resolveApplicationConfig() {
|
|
157
|
+
return requireActiveApplicationContext().config;
|
|
158
|
+
}
|
|
159
|
+
function resolveApplicationLogger() {
|
|
160
|
+
return appLogger;
|
|
161
|
+
}
|
|
162
|
+
function resolveApplicationDependencies() {
|
|
163
|
+
return requireActiveApplicationContext().dependencies;
|
|
164
|
+
}
|
|
165
|
+
|
|
67
166
|
// ../../src/core/crypto/nonCryptographicHash.ts
|
|
68
167
|
function nonCryptographicDigest(input) {
|
|
69
168
|
return Bun.hash(input).toString(16);
|
|
@@ -167,105 +266,7 @@ function parsePositiveIntParam(value, name = "id") {
|
|
|
167
266
|
return parsed;
|
|
168
267
|
}
|
|
169
268
|
|
|
170
|
-
// ../../src/core/
|
|
171
|
-
function getRequiredDependency(dependencies, key) {
|
|
172
|
-
const dependency = dependencies[key];
|
|
173
|
-
if (dependency === undefined) {
|
|
174
|
-
throw new Error(`Required dependency "${String(key)}" is not registered.`);
|
|
175
|
-
}
|
|
176
|
-
return dependency;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// ../../src/core/contracts/serviceTokens.ts
|
|
180
|
-
var CORE_CONFIG_TOKEN = "core.config";
|
|
181
|
-
var CORE_CACHE_TOKEN = "core.cache";
|
|
182
|
-
var CORE_QUEUE_TOKEN = "core.queue";
|
|
183
|
-
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
184
|
-
var CORE_AUTH_TOKEN = "core.auth";
|
|
185
|
-
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
186
|
-
|
|
187
|
-
// ../../src/core/logging/logger.ts
|
|
188
|
-
class Logger {
|
|
189
|
-
channel;
|
|
190
|
-
constructor(channel = "app") {
|
|
191
|
-
this.channel = channel;
|
|
192
|
-
}
|
|
193
|
-
write(level, message, context = {}) {
|
|
194
|
-
const entry = {
|
|
195
|
-
level,
|
|
196
|
-
channel: this.channel,
|
|
197
|
-
message,
|
|
198
|
-
timestamp: new Date().toISOString(),
|
|
199
|
-
...context
|
|
200
|
-
};
|
|
201
|
-
const line = JSON.stringify(entry);
|
|
202
|
-
if (level === "error") {
|
|
203
|
-
console.error(line);
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
console.log(line);
|
|
207
|
-
}
|
|
208
|
-
debug(message, context) {
|
|
209
|
-
this.write("debug", message, context);
|
|
210
|
-
}
|
|
211
|
-
info(message, context) {
|
|
212
|
-
this.write("info", message, context);
|
|
213
|
-
}
|
|
214
|
-
warn(message, context) {
|
|
215
|
-
this.write("warn", message, context);
|
|
216
|
-
}
|
|
217
|
-
error(message, context) {
|
|
218
|
-
this.write("error", message, context);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
var appLogger = new Logger("app");
|
|
222
|
-
|
|
223
|
-
// ../../src/core/runtime/applicationRegistry.ts
|
|
224
|
-
var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
|
|
225
|
-
var activeContext;
|
|
226
|
-
function readStoredApplicationContext() {
|
|
227
|
-
if (activeContext) {
|
|
228
|
-
return activeContext;
|
|
229
|
-
}
|
|
230
|
-
const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
|
|
231
|
-
if (globalContext) {
|
|
232
|
-
activeContext = globalContext;
|
|
233
|
-
}
|
|
234
|
-
return activeContext;
|
|
235
|
-
}
|
|
236
|
-
function setActiveApplicationContext(context) {
|
|
237
|
-
activeContext = context;
|
|
238
|
-
globalThis[APPLICATION_CONTEXT_KEY] = context;
|
|
239
|
-
}
|
|
240
|
-
function requireActiveApplicationContext() {
|
|
241
|
-
const context = readStoredApplicationContext();
|
|
242
|
-
if (!context) {
|
|
243
|
-
throw new Error("The application context has not been bootstrapped.");
|
|
244
|
-
}
|
|
245
|
-
return context;
|
|
246
|
-
}
|
|
247
|
-
function resolveApplicationCache() {
|
|
248
|
-
return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
|
|
249
|
-
}
|
|
250
|
-
function resolveApplicationQueue() {
|
|
251
|
-
return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
|
|
252
|
-
}
|
|
253
|
-
function resolveApplicationAuth() {
|
|
254
|
-
return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
|
|
255
|
-
}
|
|
256
|
-
function resolveApplicationPolicyGate() {
|
|
257
|
-
return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
|
|
258
|
-
}
|
|
259
|
-
function resolveApplicationConfig() {
|
|
260
|
-
return requireActiveApplicationContext().config;
|
|
261
|
-
}
|
|
262
|
-
function resolveApplicationLogger() {
|
|
263
|
-
return appLogger;
|
|
264
|
-
}
|
|
265
|
-
function resolveApplicationDependencies() {
|
|
266
|
-
return requireActiveApplicationContext().dependencies;
|
|
267
|
-
}
|
|
268
|
-
// ../../src/bootstrap/http/securedRouteModelBinding.ts
|
|
269
|
+
// ../../src/core/http/securedRouteModelBinding.ts
|
|
269
270
|
function isMutatingPolicyAction(action) {
|
|
270
271
|
return action === "update" || action === "delete";
|
|
271
272
|
}
|