@getstrata/bootstrap 0.2.10 → 0.2.13
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/applicationRegistry.d.ts +1 -16
- package/dist/bootstrap/cache/modelCacheTags.d.ts +3 -0
- package/dist/bootstrap/config.d.ts +2 -7
- package/dist/bootstrap/discoverModules.d.ts +3 -2
- package/dist/bootstrap/modules.d.ts +1 -1
- package/dist/bootstrap/preloadModules.d.ts +1 -0
- package/dist/bootstrap/public-api.d.ts +2 -1
- package/dist/bootstrap/routeRegistry.d.ts +1 -5
- package/dist/bootstrap/server.d.ts +1 -1
- package/dist/core/auth/guard.d.ts +2 -2
- package/dist/core/auth/sessionGuard.d.ts +2 -2
- package/dist/core/cache/modelCacheTags.d.ts +1 -3
- package/dist/core/contracts/applicationContext.d.ts +18 -0
- package/dist/core/contracts/serviceContainer.d.ts +5 -0
- package/dist/core/contracts/serviceTokens.d.ts +7 -0
- package/dist/core/openapi/registeredRoute.d.ts +6 -0
- package/dist/core/runtime/applicationRegistry.d.ts +15 -0
- package/dist/core/view/webLayoutData.d.ts +2 -2
- package/dist/entries/applicationRegistry.js +18 -107
- package/dist/entries/config.js +8 -6
- package/dist/entries/context.js +130 -65
- package/dist/entries/createWebRoutes.js +13 -29
- package/dist/entries/http/securedRouteModelBinding.js +98 -3
- package/dist/entries/httpKernel.js +8 -6
- package/dist/entries/membershipService.js +98 -3
- package/dist/entries/providers/view.js +8 -6
- package/dist/entries/providers.js +126 -57
- package/dist/entries/queue/defaultJobs.js +98 -3
- package/dist/framework/public-api.d.ts +2 -1
- package/dist/index.js +108 -96
- package/package.json +2 -2
package/dist/entries/context.js
CHANGED
|
@@ -1,7 +1,102 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// ../../src/
|
|
3
|
-
|
|
2
|
+
// ../../src/core/contracts/applicationContext.ts
|
|
3
|
+
function getRequiredDependency(dependencies, key) {
|
|
4
|
+
const dependency = dependencies[key];
|
|
5
|
+
if (dependency === undefined) {
|
|
6
|
+
throw new Error(`Required dependency "${String(key)}" is not registered.`);
|
|
7
|
+
}
|
|
8
|
+
return dependency;
|
|
9
|
+
}
|
|
4
10
|
|
|
11
|
+
// ../../src/core/contracts/serviceTokens.ts
|
|
12
|
+
var CORE_CONFIG_TOKEN = "core.config";
|
|
13
|
+
var CORE_CACHE_TOKEN = "core.cache";
|
|
14
|
+
var CORE_QUEUE_TOKEN = "core.queue";
|
|
15
|
+
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
16
|
+
var CORE_AUTH_TOKEN = "core.auth";
|
|
17
|
+
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
18
|
+
|
|
19
|
+
// ../../src/core/logging/logger.ts
|
|
20
|
+
class Logger {
|
|
21
|
+
channel;
|
|
22
|
+
constructor(channel = "app") {
|
|
23
|
+
this.channel = channel;
|
|
24
|
+
}
|
|
25
|
+
write(level, message, context = {}) {
|
|
26
|
+
const entry = {
|
|
27
|
+
level,
|
|
28
|
+
channel: this.channel,
|
|
29
|
+
message,
|
|
30
|
+
timestamp: new Date().toISOString(),
|
|
31
|
+
...context
|
|
32
|
+
};
|
|
33
|
+
const line = JSON.stringify(entry);
|
|
34
|
+
if (level === "error") {
|
|
35
|
+
console.error(line);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
console.log(line);
|
|
39
|
+
}
|
|
40
|
+
debug(message, context) {
|
|
41
|
+
this.write("debug", message, context);
|
|
42
|
+
}
|
|
43
|
+
info(message, context) {
|
|
44
|
+
this.write("info", message, context);
|
|
45
|
+
}
|
|
46
|
+
warn(message, context) {
|
|
47
|
+
this.write("warn", message, context);
|
|
48
|
+
}
|
|
49
|
+
error(message, context) {
|
|
50
|
+
this.write("error", message, context);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
var appLogger = new Logger("app");
|
|
54
|
+
|
|
55
|
+
// ../../src/core/runtime/applicationRegistry.ts
|
|
56
|
+
var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
|
|
57
|
+
var activeContext;
|
|
58
|
+
function readStoredApplicationContext() {
|
|
59
|
+
if (activeContext) {
|
|
60
|
+
return activeContext;
|
|
61
|
+
}
|
|
62
|
+
const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
|
|
63
|
+
if (globalContext) {
|
|
64
|
+
activeContext = globalContext;
|
|
65
|
+
}
|
|
66
|
+
return activeContext;
|
|
67
|
+
}
|
|
68
|
+
function setActiveApplicationContext(context) {
|
|
69
|
+
activeContext = context;
|
|
70
|
+
globalThis[APPLICATION_CONTEXT_KEY] = context;
|
|
71
|
+
}
|
|
72
|
+
function requireActiveApplicationContext() {
|
|
73
|
+
const context = readStoredApplicationContext();
|
|
74
|
+
if (!context) {
|
|
75
|
+
throw new Error("The application context has not been bootstrapped.");
|
|
76
|
+
}
|
|
77
|
+
return context;
|
|
78
|
+
}
|
|
79
|
+
function resolveApplicationCache() {
|
|
80
|
+
return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
|
|
81
|
+
}
|
|
82
|
+
function resolveApplicationQueue() {
|
|
83
|
+
return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
|
|
84
|
+
}
|
|
85
|
+
function resolveApplicationAuth() {
|
|
86
|
+
return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
|
|
87
|
+
}
|
|
88
|
+
function resolveApplicationPolicyGate() {
|
|
89
|
+
return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
|
|
90
|
+
}
|
|
91
|
+
function resolveApplicationConfig() {
|
|
92
|
+
return requireActiveApplicationContext().config;
|
|
93
|
+
}
|
|
94
|
+
function resolveApplicationLogger() {
|
|
95
|
+
return appLogger;
|
|
96
|
+
}
|
|
97
|
+
function resolveApplicationDependencies() {
|
|
98
|
+
return requireActiveApplicationContext().dependencies;
|
|
99
|
+
}
|
|
5
100
|
// ../../src/bootstrap/contracts.ts
|
|
6
101
|
class ServiceContainer {
|
|
7
102
|
services = new Map;
|
|
@@ -71,7 +166,7 @@ var requiredDependencyKeys = [
|
|
|
71
166
|
"cache",
|
|
72
167
|
"storage"
|
|
73
168
|
];
|
|
74
|
-
function
|
|
169
|
+
function getRequiredDependency2(dependencies, key) {
|
|
75
170
|
const dependency = dependencies[key];
|
|
76
171
|
if (dependency === undefined) {
|
|
77
172
|
throw new Error(`Required dependency "${key}" is not registered.`);
|
|
@@ -80,7 +175,7 @@ function getRequiredDependency(dependencies, key) {
|
|
|
80
175
|
}
|
|
81
176
|
function assertAppDependenciesComplete(dependencies) {
|
|
82
177
|
for (const key of requiredDependencyKeys) {
|
|
83
|
-
|
|
178
|
+
getRequiredDependency2(dependencies, key);
|
|
84
179
|
}
|
|
85
180
|
}
|
|
86
181
|
function resolveService(dependencies, token) {
|
|
@@ -88,28 +183,10 @@ function resolveService(dependencies, token) {
|
|
|
88
183
|
}
|
|
89
184
|
|
|
90
185
|
// ../../src/bootstrap/discoverModules.ts
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
async function loadDiscoveredModules() {
|
|
95
|
-
const modulesDirectory = join(import.meta.dir, "../modules");
|
|
96
|
-
let moduleNames;
|
|
97
|
-
try {
|
|
98
|
-
moduleNames = readdirSync(modulesDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
99
|
-
} catch (error) {
|
|
100
|
-
if (error.code === "ENOENT") {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
throw error;
|
|
104
|
-
}
|
|
105
|
-
const modules = await Promise.all(moduleNames.map(async (moduleName) => {
|
|
106
|
-
const moduleUrl = pathToFileURL(join(modulesDirectory, moduleName, "index.ts")).href;
|
|
107
|
-
const loaded = await import(moduleUrl);
|
|
108
|
-
return loaded.default;
|
|
109
|
-
}));
|
|
110
|
-
return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
|
|
186
|
+
var appModules = [];
|
|
187
|
+
function discoverModules() {
|
|
188
|
+
return appModules;
|
|
111
189
|
}
|
|
112
|
-
var appModules = await loadDiscoveredModules();
|
|
113
190
|
// ../../src/config/auth.ts
|
|
114
191
|
var authConfig = {
|
|
115
192
|
allowDevHeaders: (process.env.AUTH_DEV_HEADERS ?? "true") !== "false",
|
|
@@ -161,12 +238,6 @@ var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
|
|
|
161
238
|
var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
|
|
162
239
|
var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
|
|
163
240
|
var DATABASE_URL_CONFIG_KEY = "database.url";
|
|
164
|
-
var CORE_CONFIG_TOKEN = "core.config";
|
|
165
|
-
var CORE_CACHE_TOKEN = "core.cache";
|
|
166
|
-
var CORE_QUEUE_TOKEN = "core.queue";
|
|
167
|
-
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
168
|
-
var CORE_AUTH_TOKEN = "core.auth";
|
|
169
|
-
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
170
241
|
var AUTH_DEV_HEADERS_CONFIG_KEY = "auth.allowDevHeaders";
|
|
171
242
|
var DEFAULT_APP_PORT = 3000;
|
|
172
243
|
var DEFAULT_CACHE_TTL_MS = 3600000;
|
|
@@ -1396,14 +1467,14 @@ var eventsProvider = {
|
|
|
1396
1467
|
var events_default = eventsProvider;
|
|
1397
1468
|
|
|
1398
1469
|
// ../../src/bootstrap/discoverListeners.ts
|
|
1399
|
-
import { readdirSync
|
|
1400
|
-
import { join
|
|
1401
|
-
import { pathToFileURL
|
|
1470
|
+
import { readdirSync } from "fs";
|
|
1471
|
+
import { join } from "path";
|
|
1472
|
+
import { pathToFileURL } from "url";
|
|
1402
1473
|
async function loadDiscoveredListeners() {
|
|
1403
|
-
const listenersDirectory =
|
|
1474
|
+
const listenersDirectory = join(import.meta.dir, "../listeners");
|
|
1404
1475
|
let entries;
|
|
1405
1476
|
try {
|
|
1406
|
-
entries =
|
|
1477
|
+
entries = readdirSync(listenersDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => entry.name);
|
|
1407
1478
|
} catch (error) {
|
|
1408
1479
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
1409
1480
|
return [];
|
|
@@ -1411,7 +1482,7 @@ async function loadDiscoveredListeners() {
|
|
|
1411
1482
|
throw error;
|
|
1412
1483
|
}
|
|
1413
1484
|
const listeners = await Promise.all(entries.map(async (fileName) => {
|
|
1414
|
-
const moduleUrl =
|
|
1485
|
+
const moduleUrl = pathToFileURL(join(listenersDirectory, fileName)).href;
|
|
1415
1486
|
const loaded = await import(moduleUrl);
|
|
1416
1487
|
return loaded.default;
|
|
1417
1488
|
}));
|
|
@@ -1422,21 +1493,6 @@ function discoverListeners() {
|
|
|
1422
1493
|
return appListeners;
|
|
1423
1494
|
}
|
|
1424
1495
|
|
|
1425
|
-
// ../../src/bootstrap/listeners/invalidateCacheOnModelWrite.ts
|
|
1426
|
-
import { resolveApplicationCache as resolveApplicationCache2, resolveApplicationQueue } from "@getstrata/core";
|
|
1427
|
-
|
|
1428
|
-
// ../../src/core/cache/modelCacheTags.ts
|
|
1429
|
-
function cacheTagsForModelWrite(tableName, action) {
|
|
1430
|
-
const module = appModules.find((entry) => entry.tableName === tableName);
|
|
1431
|
-
const baseTags = module?.cacheTags ?? [`${tableName}s`];
|
|
1432
|
-
const isDelete = action === "deleted" || action === "force-deleted";
|
|
1433
|
-
const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
|
|
1434
|
-
return [...new Set([...baseTags, ...extraTags])];
|
|
1435
|
-
}
|
|
1436
|
-
function discoverModelTableNames() {
|
|
1437
|
-
return appModules.map((module) => module.tableName).filter((tableName) => tableName !== undefined);
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
1496
|
// ../../src/core/queue/index.ts
|
|
1441
1497
|
class Job {
|
|
1442
1498
|
maxAttempts;
|
|
@@ -1747,10 +1803,10 @@ function buildHavingClause(tableName, having, params) {
|
|
|
1747
1803
|
return body.length > 0 ? ` HAVING ${body}` : "";
|
|
1748
1804
|
}
|
|
1749
1805
|
function buildJoinClause(joins = []) {
|
|
1750
|
-
return joins.map((
|
|
1751
|
-
const joinType =
|
|
1752
|
-
const onClause =
|
|
1753
|
-
return ` ${joinType} ${quoteIdentifier(
|
|
1806
|
+
return joins.map((join2) => {
|
|
1807
|
+
const joinType = join2.type === "left" ? "LEFT JOIN" : "INNER JOIN";
|
|
1808
|
+
const onClause = join2.on.map(({ left, right }) => `${qualifyColumn(left.table, left.column)} = ${qualifyColumn(right.table, right.column)}`).join(" AND ");
|
|
1809
|
+
return ` ${joinType} ${quoteIdentifier(join2.table)} ON ${onClause}`;
|
|
1754
1810
|
}).join("");
|
|
1755
1811
|
}
|
|
1756
1812
|
function buildLimitClause(limit) {
|
|
@@ -2186,7 +2242,7 @@ class RepositoryQuery {
|
|
|
2186
2242
|
const rightRef = parseQualifiedColumn(right);
|
|
2187
2243
|
const table = type === "inner" ? rightRef.table : rightRef.table;
|
|
2188
2244
|
const joins = this.queryOptions.joins ?? [];
|
|
2189
|
-
const existing = joins.find((
|
|
2245
|
+
const existing = joins.find((join2) => join2.table === table && join2.type === type);
|
|
2190
2246
|
if (existing) {
|
|
2191
2247
|
existing.on.push({ left: leftRef, right: rightRef });
|
|
2192
2248
|
return this;
|
|
@@ -3349,9 +3405,6 @@ function createProductionQueue(driver, options = {}) {
|
|
|
3349
3405
|
return new ResilientQueue(failedJobs, driver === "async");
|
|
3350
3406
|
}
|
|
3351
3407
|
|
|
3352
|
-
// ../../src/bootstrap/queue/defaultJobs.ts
|
|
3353
|
-
import { resolveApplicationCache } from "@getstrata/core";
|
|
3354
|
-
|
|
3355
3408
|
// ../../src/core/jobs/dispatchWebhookJob.ts
|
|
3356
3409
|
import { createHmac as createHmac2 } from "crypto";
|
|
3357
3410
|
|
|
@@ -3557,6 +3610,18 @@ function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(),
|
|
|
3557
3610
|
});
|
|
3558
3611
|
}
|
|
3559
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
|
+
|
|
3560
3625
|
// ../../src/bootstrap/listeners/invalidateCacheOnModelWrite.ts
|
|
3561
3626
|
var MODEL_WRITE_ACTIONS = ["created", "updated", "deleted", "restored", "force-deleted"];
|
|
3562
3627
|
function registerInvalidateCacheOnModelWriteListeners(bus = eventBus) {
|
|
@@ -3570,7 +3635,7 @@ function registerInvalidateCacheOnModelWriteListeners(bus = eventBus) {
|
|
|
3570
3635
|
let cache;
|
|
3571
3636
|
let queue;
|
|
3572
3637
|
try {
|
|
3573
|
-
cache =
|
|
3638
|
+
cache = resolveApplicationCache();
|
|
3574
3639
|
queue = resolveApplicationQueue();
|
|
3575
3640
|
} catch {
|
|
3576
3641
|
return;
|
|
@@ -3668,7 +3733,7 @@ var queue_default = queueProvider;
|
|
|
3668
3733
|
|
|
3669
3734
|
// ../../src/core/storage/storage.ts
|
|
3670
3735
|
import { mkdir, readFile, unlink, writeFile } from "fs/promises";
|
|
3671
|
-
import { dirname, join as
|
|
3736
|
+
import { dirname, join as join2 } from "path";
|
|
3672
3737
|
var {S3Client } = globalThis.Bun;
|
|
3673
3738
|
|
|
3674
3739
|
class LocalStorageDriver {
|
|
@@ -3680,7 +3745,7 @@ class LocalStorageDriver {
|
|
|
3680
3745
|
return this.rootDirectory ?? process.env.STORAGE_PATH ?? "storage";
|
|
3681
3746
|
}
|
|
3682
3747
|
resolvePath(path) {
|
|
3683
|
-
return
|
|
3748
|
+
return join2(this.resolveRootDirectory(), path.replace(/^\/+/, ""));
|
|
3684
3749
|
}
|
|
3685
3750
|
async put(path, contents) {
|
|
3686
3751
|
const absolutePath = this.resolvePath(path);
|
|
@@ -3813,9 +3878,9 @@ function currentRequestMeta() {
|
|
|
3813
3878
|
}
|
|
3814
3879
|
|
|
3815
3880
|
// ../../src/core/view/etaViewEngine.ts
|
|
3816
|
-
import { join as
|
|
3881
|
+
import { join as join3 } from "path";
|
|
3817
3882
|
import { Eta } from "eta";
|
|
3818
|
-
var DEFAULT_VIEWS_DIRECTORY =
|
|
3883
|
+
var DEFAULT_VIEWS_DIRECTORY = join3(process.cwd(), "resources/views");
|
|
3819
3884
|
var DEFAULT_LAYOUT = "layouts/app.eta";
|
|
3820
3885
|
|
|
3821
3886
|
class EtaViewEngine {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// ../../src/bootstrap/createWebRoutes.ts
|
|
3
|
-
import { join as
|
|
3
|
+
import { join as join2 } from "path";
|
|
4
4
|
|
|
5
5
|
// ../../src/config/frontend.ts
|
|
6
6
|
function readFrontendMode() {
|
|
@@ -110,6 +110,14 @@ function htmlResponse(html, init = {}) {
|
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
+
// ../../src/core/contracts/serviceTokens.ts
|
|
114
|
+
var CORE_CONFIG_TOKEN = "core.config";
|
|
115
|
+
var CORE_CACHE_TOKEN = "core.cache";
|
|
116
|
+
var CORE_QUEUE_TOKEN = "core.queue";
|
|
117
|
+
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
118
|
+
var CORE_AUTH_TOKEN = "core.auth";
|
|
119
|
+
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
120
|
+
|
|
113
121
|
// ../../src/bootstrap/config.ts
|
|
114
122
|
var APP_PORT_CONFIG_KEY = "app.port";
|
|
115
123
|
var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
|
|
@@ -117,12 +125,6 @@ var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
|
|
|
117
125
|
var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
|
|
118
126
|
var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
|
|
119
127
|
var DATABASE_URL_CONFIG_KEY = "database.url";
|
|
120
|
-
var CORE_CONFIG_TOKEN = "core.config";
|
|
121
|
-
var CORE_CACHE_TOKEN = "core.cache";
|
|
122
|
-
var CORE_QUEUE_TOKEN = "core.queue";
|
|
123
|
-
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
124
|
-
var CORE_AUTH_TOKEN = "core.auth";
|
|
125
|
-
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
126
128
|
var AUTH_DEV_HEADERS_CONFIG_KEY = "auth.allowDevHeaders";
|
|
127
129
|
var DEFAULT_APP_PORT = 3000;
|
|
128
130
|
var DEFAULT_CACHE_TTL_MS = 3600000;
|
|
@@ -905,28 +907,10 @@ function createHttpKernel(dependencies) {
|
|
|
905
907
|
}
|
|
906
908
|
|
|
907
909
|
// ../../src/bootstrap/discoverModules.ts
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
async function loadDiscoveredModules() {
|
|
912
|
-
const modulesDirectory = join2(import.meta.dir, "../modules");
|
|
913
|
-
let moduleNames;
|
|
914
|
-
try {
|
|
915
|
-
moduleNames = readdirSync(modulesDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
916
|
-
} catch (error) {
|
|
917
|
-
if (error.code === "ENOENT") {
|
|
918
|
-
return [];
|
|
919
|
-
}
|
|
920
|
-
throw error;
|
|
921
|
-
}
|
|
922
|
-
const modules = await Promise.all(moduleNames.map(async (moduleName) => {
|
|
923
|
-
const moduleUrl = pathToFileURL(join2(modulesDirectory, moduleName, "index.ts")).href;
|
|
924
|
-
const loaded = await import(moduleUrl);
|
|
925
|
-
return loaded.default;
|
|
926
|
-
}));
|
|
927
|
-
return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
|
|
910
|
+
var appModules = [];
|
|
911
|
+
function discoverModules() {
|
|
912
|
+
return appModules;
|
|
928
913
|
}
|
|
929
|
-
var appModules = await loadDiscoveredModules();
|
|
930
914
|
// ../../src/bootstrap/routeRegistry.ts
|
|
931
915
|
class RouteRegistry {
|
|
932
916
|
routes = [];
|
|
@@ -984,7 +968,7 @@ function createWebRoutes(dependencies) {
|
|
|
984
968
|
registerRoute("GET", "/assets/*", ["global", "web"]);
|
|
985
969
|
const pathname = new URL(request.url).pathname;
|
|
986
970
|
const relativePath = pathname.replace(/^\//, "");
|
|
987
|
-
const file = Bun.file(
|
|
971
|
+
const file = Bun.file(join2(process.cwd(), "public", relativePath));
|
|
988
972
|
if (!await file.exists()) {
|
|
989
973
|
return htmlResponse("Not Found", { status: 404 });
|
|
990
974
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// ../../src/bootstrap/http/securedRouteModelBinding.ts
|
|
3
|
-
import { resolveApplicationAuth, resolveApplicationPolicyGate } from "@getstrata/core";
|
|
4
|
-
|
|
5
2
|
// ../../src/core/runtime/asyncContextStore.ts
|
|
6
3
|
import { AsyncLocalStorage } from "async_hooks";
|
|
7
4
|
function createAsyncContextStore(key) {
|
|
@@ -170,6 +167,104 @@ function parsePositiveIntParam(value, name = "id") {
|
|
|
170
167
|
return parsed;
|
|
171
168
|
}
|
|
172
169
|
|
|
170
|
+
// ../../src/core/contracts/applicationContext.ts
|
|
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
|
+
}
|
|
173
268
|
// ../../src/bootstrap/http/securedRouteModelBinding.ts
|
|
174
269
|
function isMutatingPolicyAction(action) {
|
|
175
270
|
return action === "update" || action === "delete";
|
|
@@ -74,6 +74,14 @@ function resolveRegisterRateLimit() {
|
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
// ../../src/core/contracts/serviceTokens.ts
|
|
78
|
+
var CORE_CONFIG_TOKEN = "core.config";
|
|
79
|
+
var CORE_CACHE_TOKEN = "core.cache";
|
|
80
|
+
var CORE_QUEUE_TOKEN = "core.queue";
|
|
81
|
+
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
82
|
+
var CORE_AUTH_TOKEN = "core.auth";
|
|
83
|
+
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
84
|
+
|
|
77
85
|
// ../../src/bootstrap/config.ts
|
|
78
86
|
var APP_PORT_CONFIG_KEY = "app.port";
|
|
79
87
|
var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
|
|
@@ -81,12 +89,6 @@ var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
|
|
|
81
89
|
var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
|
|
82
90
|
var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
|
|
83
91
|
var DATABASE_URL_CONFIG_KEY = "database.url";
|
|
84
|
-
var CORE_CONFIG_TOKEN = "core.config";
|
|
85
|
-
var CORE_CACHE_TOKEN = "core.cache";
|
|
86
|
-
var CORE_QUEUE_TOKEN = "core.queue";
|
|
87
|
-
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
88
|
-
var CORE_AUTH_TOKEN = "core.auth";
|
|
89
|
-
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
90
92
|
var AUTH_DEV_HEADERS_CONFIG_KEY = "auth.allowDevHeaders";
|
|
91
93
|
var DEFAULT_APP_PORT = 3000;
|
|
92
94
|
var DEFAULT_CACHE_TTL_MS = 3600000;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// ../../src/bootstrap/membershipService.ts
|
|
3
|
-
import { resolveApplicationDependencies } from "@getstrata/core";
|
|
4
|
-
|
|
5
2
|
// ../../src/core/errors/http.ts
|
|
6
3
|
class HttpError extends Error {
|
|
7
4
|
status;
|
|
@@ -304,6 +301,104 @@ class MembershipService {
|
|
|
304
301
|
}
|
|
305
302
|
var membershipService_default = MembershipService;
|
|
306
303
|
|
|
304
|
+
// ../../src/core/contracts/applicationContext.ts
|
|
305
|
+
function getRequiredDependency(dependencies, key) {
|
|
306
|
+
const dependency = dependencies[key];
|
|
307
|
+
if (dependency === undefined) {
|
|
308
|
+
throw new Error(`Required dependency "${String(key)}" is not registered.`);
|
|
309
|
+
}
|
|
310
|
+
return dependency;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ../../src/core/contracts/serviceTokens.ts
|
|
314
|
+
var CORE_CONFIG_TOKEN = "core.config";
|
|
315
|
+
var CORE_CACHE_TOKEN = "core.cache";
|
|
316
|
+
var CORE_QUEUE_TOKEN = "core.queue";
|
|
317
|
+
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
318
|
+
var CORE_AUTH_TOKEN = "core.auth";
|
|
319
|
+
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
320
|
+
|
|
321
|
+
// ../../src/core/logging/logger.ts
|
|
322
|
+
class Logger {
|
|
323
|
+
channel;
|
|
324
|
+
constructor(channel = "app") {
|
|
325
|
+
this.channel = channel;
|
|
326
|
+
}
|
|
327
|
+
write(level, message, context = {}) {
|
|
328
|
+
const entry = {
|
|
329
|
+
level,
|
|
330
|
+
channel: this.channel,
|
|
331
|
+
message,
|
|
332
|
+
timestamp: new Date().toISOString(),
|
|
333
|
+
...context
|
|
334
|
+
};
|
|
335
|
+
const line = JSON.stringify(entry);
|
|
336
|
+
if (level === "error") {
|
|
337
|
+
console.error(line);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
console.log(line);
|
|
341
|
+
}
|
|
342
|
+
debug(message, context) {
|
|
343
|
+
this.write("debug", message, context);
|
|
344
|
+
}
|
|
345
|
+
info(message, context) {
|
|
346
|
+
this.write("info", message, context);
|
|
347
|
+
}
|
|
348
|
+
warn(message, context) {
|
|
349
|
+
this.write("warn", message, context);
|
|
350
|
+
}
|
|
351
|
+
error(message, context) {
|
|
352
|
+
this.write("error", message, context);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
var appLogger = new Logger("app");
|
|
356
|
+
|
|
357
|
+
// ../../src/core/runtime/applicationRegistry.ts
|
|
358
|
+
var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
|
|
359
|
+
var activeContext;
|
|
360
|
+
function readStoredApplicationContext() {
|
|
361
|
+
if (activeContext) {
|
|
362
|
+
return activeContext;
|
|
363
|
+
}
|
|
364
|
+
const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
|
|
365
|
+
if (globalContext) {
|
|
366
|
+
activeContext = globalContext;
|
|
367
|
+
}
|
|
368
|
+
return activeContext;
|
|
369
|
+
}
|
|
370
|
+
function setActiveApplicationContext(context) {
|
|
371
|
+
activeContext = context;
|
|
372
|
+
globalThis[APPLICATION_CONTEXT_KEY] = context;
|
|
373
|
+
}
|
|
374
|
+
function requireActiveApplicationContext() {
|
|
375
|
+
const context = readStoredApplicationContext();
|
|
376
|
+
if (!context) {
|
|
377
|
+
throw new Error("The application context has not been bootstrapped.");
|
|
378
|
+
}
|
|
379
|
+
return context;
|
|
380
|
+
}
|
|
381
|
+
function resolveApplicationCache() {
|
|
382
|
+
return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
|
|
383
|
+
}
|
|
384
|
+
function resolveApplicationQueue() {
|
|
385
|
+
return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
|
|
386
|
+
}
|
|
387
|
+
function resolveApplicationAuth() {
|
|
388
|
+
return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
|
|
389
|
+
}
|
|
390
|
+
function resolveApplicationPolicyGate() {
|
|
391
|
+
return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
|
|
392
|
+
}
|
|
393
|
+
function resolveApplicationConfig() {
|
|
394
|
+
return requireActiveApplicationContext().config;
|
|
395
|
+
}
|
|
396
|
+
function resolveApplicationLogger() {
|
|
397
|
+
return appLogger;
|
|
398
|
+
}
|
|
399
|
+
function resolveApplicationDependencies() {
|
|
400
|
+
return requireActiveApplicationContext().dependencies;
|
|
401
|
+
}
|
|
307
402
|
// ../../src/bootstrap/membershipService.ts
|
|
308
403
|
function resolveMembershipService() {
|
|
309
404
|
const dependencies = resolveApplicationDependencies();
|
|
@@ -79,6 +79,14 @@ function htmlResponse(html, init = {}) {
|
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
|
+
// ../../src/core/contracts/serviceTokens.ts
|
|
83
|
+
var CORE_CONFIG_TOKEN = "core.config";
|
|
84
|
+
var CORE_CACHE_TOKEN = "core.cache";
|
|
85
|
+
var CORE_QUEUE_TOKEN = "core.queue";
|
|
86
|
+
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
87
|
+
var CORE_AUTH_TOKEN = "core.auth";
|
|
88
|
+
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
89
|
+
|
|
82
90
|
// ../../src/bootstrap/config.ts
|
|
83
91
|
var APP_PORT_CONFIG_KEY = "app.port";
|
|
84
92
|
var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
|
|
@@ -86,12 +94,6 @@ var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
|
|
|
86
94
|
var CACHE_DRIVER_CONFIG_KEY = "cache.driver";
|
|
87
95
|
var REDIS_URL_CONFIG_KEY = "cache.redisUrl";
|
|
88
96
|
var DATABASE_URL_CONFIG_KEY = "database.url";
|
|
89
|
-
var CORE_CONFIG_TOKEN = "core.config";
|
|
90
|
-
var CORE_CACHE_TOKEN = "core.cache";
|
|
91
|
-
var CORE_QUEUE_TOKEN = "core.queue";
|
|
92
|
-
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
93
|
-
var CORE_AUTH_TOKEN = "core.auth";
|
|
94
|
-
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
95
97
|
var AUTH_DEV_HEADERS_CONFIG_KEY = "auth.allowDevHeaders";
|
|
96
98
|
var DEFAULT_APP_PORT = 3000;
|
|
97
99
|
var DEFAULT_CACHE_TTL_MS = 3600000;
|