@getstrata/bootstrap 0.2.20 → 0.2.22
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 -1
- package/dist/bootstrap/config.d.ts +1 -1
- package/dist/bootstrap/discoverModules.d.ts +7 -3
- package/dist/bootstrap/modules.d.ts +1 -1
- package/dist/bootstrap/providers/events.d.ts +1 -1
- package/dist/bootstrap/public-api.d.ts +7 -2
- package/dist/core/contracts/serviceTokens.d.ts +2 -1
- package/dist/core/runtime/applicationRegistry.d.ts +3 -1
- package/dist/entries/applicationRegistry.js +5 -0
- package/dist/entries/cache/modelCacheTags.js +56 -2
- package/dist/entries/config.js +2 -0
- package/dist/entries/context.js +76 -19
- package/dist/entries/createWebRoutes.js +71 -6
- package/dist/entries/dependencies.js +4290 -0
- package/dist/entries/discoverModules.js +65 -0
- package/dist/entries/http/securedRouteModelBinding.js +4 -0
- package/dist/entries/httpKernel.js +1 -0
- package/dist/entries/membershipService.js +4 -0
- package/dist/entries/providers/view.js +1 -0
- package/dist/entries/providers.js +64 -7
- package/dist/entries/queue/defaultJobs.js +4 -0
- package/dist/entries/routeRegistry.js +29 -0
- package/dist/entries/secretsGuard.js +91 -0
- package/dist/entries/web/routing.js +4 -0
- package/dist/framework/public-api.d.ts +1 -1
- package/dist/index.js +103 -23
- package/dist/modules/scim/controller.d.ts +1 -1
- package/dist/modules/scim/service.d.ts +1 -1
- package/dist/modules/user/provider.d.ts +1 -1
- package/package.json +23 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, } from "../core/runtime/applicationRegistry.ts";
|
|
1
|
+
export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationEventBus, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, } from "../core/runtime/applicationRegistry.ts";
|
|
@@ -4,7 +4,7 @@ declare const CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
|
|
|
4
4
|
declare const CACHE_DRIVER_CONFIG_KEY = "cache.driver";
|
|
5
5
|
declare const REDIS_URL_CONFIG_KEY = "cache.redisUrl";
|
|
6
6
|
declare const DATABASE_URL_CONFIG_KEY = "database.url";
|
|
7
|
-
export { CORE_AUTH_TOKEN, CORE_CACHE_TOKEN, CORE_CONFIG_TOKEN, CORE_POLICY_GATE_TOKEN, CORE_QUEUE_TOKEN, CORE_TOKEN_SERVICE_TOKEN, } from "../core/contracts/serviceTokens.ts";
|
|
7
|
+
export { CORE_AUTH_TOKEN, CORE_CACHE_TOKEN, CORE_CONFIG_TOKEN, CORE_EVENT_BUS_TOKEN, CORE_POLICY_GATE_TOKEN, CORE_QUEUE_TOKEN, CORE_TOKEN_SERVICE_TOKEN, } from "../core/contracts/serviceTokens.ts";
|
|
8
8
|
declare const AUTH_DEV_HEADERS_CONFIG_KEY = "auth.allowDevHeaders";
|
|
9
9
|
declare const DEFAULT_APP_PORT = 3000;
|
|
10
10
|
declare const DEFAULT_CACHE_TTL_MS = 3600000;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { AppModule } from "./contracts";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
interface DiscoverModulesOptions {
|
|
3
|
+
modulesDir?: string;
|
|
4
|
+
}
|
|
5
|
+
declare function configureModulesDirectory(modulesDir: string): void;
|
|
6
|
+
declare function ensureModulesLoaded(options?: DiscoverModulesOptions): Promise<AppModule[]>;
|
|
4
7
|
declare function discoverModules(): AppModule[];
|
|
5
|
-
export {
|
|
8
|
+
export type { DiscoverModulesOptions };
|
|
9
|
+
export { configureModulesDirectory, discoverModules, ensureModulesLoaded };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { configureModulesDirectory, discoverModules, ensureModulesLoaded, } from "./discoverModules";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { CORE_EVENT_BUS_TOKEN } from "../config";
|
|
1
2
|
import type { ServiceProvider } from "../contracts";
|
|
2
|
-
declare const CORE_EVENT_BUS_TOKEN = "core.eventBus";
|
|
3
3
|
declare const eventsProvider: ServiceProvider;
|
|
4
4
|
export default eventsProvider;
|
|
5
5
|
export { CORE_EVENT_BUS_TOKEN };
|
|
@@ -4,17 +4,22 @@
|
|
|
4
4
|
export { scheduleRunCommand } from "../cli/commands/scheduleRun.ts";
|
|
5
5
|
export type { ScheduledTask } from "../core/scheduler/schedule.ts";
|
|
6
6
|
export { appSchedule, runDueScheduledTasks, Schedule } from "../core/scheduler/schedule.ts";
|
|
7
|
-
export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, } from "./applicationRegistry.ts";
|
|
7
|
+
export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationEventBus, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, } from "./applicationRegistry.ts";
|
|
8
8
|
export { cacheTagsForModelWrite, discoverModelTableNames } from "./cache/modelCacheTags.ts";
|
|
9
|
-
export { APP_PORT_CONFIG_KEY, CORE_AUTH_TOKEN, CORE_CACHE_TOKEN, CORE_CONFIG_TOKEN, CORE_POLICY_GATE_TOKEN, CORE_QUEUE_TOKEN, CORE_TOKEN_SERVICE_TOKEN, DATABASE_URL_CONFIG_KEY, DEFAULT_APP_PORT, REDIS_URL_CONFIG_KEY, } from "./config.ts";
|
|
9
|
+
export { APP_PORT_CONFIG_KEY, CORE_AUTH_TOKEN, CORE_CACHE_TOKEN, CORE_CONFIG_TOKEN, CORE_EVENT_BUS_TOKEN, CORE_POLICY_GATE_TOKEN, CORE_QUEUE_TOKEN, CORE_TOKEN_SERVICE_TOKEN, DATABASE_URL_CONFIG_KEY, DEFAULT_APP_PORT, REDIS_URL_CONFIG_KEY, } from "./config.ts";
|
|
10
10
|
export { collectProviders, createAppContext, runProviderPhase } from "./context.ts";
|
|
11
11
|
export type { AppContext, AppDependencies, AppModule, AppRouteMap, CachedJson, ConfigStore, ModuleRouteContext, MutableAppDependencies, ProviderContext, ServiceFactory, ServiceProvider, } from "./contracts.ts";
|
|
12
12
|
export { assertAppDependenciesComplete, getRequiredDependency, resolveService, ServiceContainer, } from "./contracts.ts";
|
|
13
13
|
export { createWebRoutes, mergeWebRoutes } from "./createWebRoutes.ts";
|
|
14
|
+
export { createAppDependencies } from "./dependencies.ts";
|
|
15
|
+
export type { DiscoverModulesOptions } from "./discoverModules.ts";
|
|
16
|
+
export { configureModulesDirectory, discoverModules, ensureModulesLoaded, } from "./discoverModules.ts";
|
|
14
17
|
export { type RouteModelAuthorization, securedBindRouteModel, securedBindRouteModelByKey, } from "./http/securedRouteModelBinding.ts";
|
|
15
18
|
export { createHttpKernel, type HttpKernel, type MiddlewareGroupName } from "./httpKernel.ts";
|
|
16
19
|
export { resolveMembershipService } from "./membershipService.ts";
|
|
17
20
|
export { prefixRouteMap } from "./prefixRouteMap.ts";
|
|
18
21
|
export { coreProviders } from "./providers/index.ts";
|
|
19
22
|
export { registerDefaultJobs } from "./queue/defaultJobs.ts";
|
|
23
|
+
export { RouteRegistry, routeRegistry } from "./routeRegistry.ts";
|
|
24
|
+
export { assertProductionSecrets } from "./secretsGuard.ts";
|
|
20
25
|
export { CookieSessionStore, createCsrfProtection, createRouteKernel, createWebServer, type ParsedForm, parseFormBody, routeParams, type SessionUser, slugify, toRouteRequest, type WebServerOptions, wrapSecuredRouteModelByKey, wrapWebLogin, wrapWebRegister, } from "./web/index.ts";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
declare const CORE_CONFIG_TOKEN = "core.config";
|
|
2
2
|
declare const CORE_CACHE_TOKEN = "core.cache";
|
|
3
3
|
declare const CORE_QUEUE_TOKEN = "core.queue";
|
|
4
|
+
declare const CORE_EVENT_BUS_TOKEN = "core.eventBus";
|
|
4
5
|
declare const CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
5
6
|
declare const CORE_AUTH_TOKEN = "core.auth";
|
|
6
7
|
declare const CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
7
|
-
export { CORE_AUTH_TOKEN, CORE_CACHE_TOKEN, CORE_CONFIG_TOKEN, CORE_POLICY_GATE_TOKEN, CORE_QUEUE_TOKEN, CORE_TOKEN_SERVICE_TOKEN, };
|
|
8
|
+
export { CORE_AUTH_TOKEN, CORE_CACHE_TOKEN, CORE_CONFIG_TOKEN, CORE_EVENT_BUS_TOKEN, CORE_POLICY_GATE_TOKEN, CORE_QUEUE_TOKEN, CORE_TOKEN_SERVICE_TOKEN, };
|
|
@@ -2,14 +2,16 @@ import type { CacheLike } from "../../types/services";
|
|
|
2
2
|
import type { AuthManager } from "../auth/guard";
|
|
3
3
|
import type { PolicyGate } from "../auth/policy";
|
|
4
4
|
import type { AppContext } from "../contracts/di";
|
|
5
|
+
import type { EventBus } from "../events";
|
|
5
6
|
import { type Logger } from "../logging/logger";
|
|
6
7
|
import type { Queue } from "../queue";
|
|
7
8
|
declare function setActiveApplicationContext(context: AppContext): void;
|
|
8
9
|
declare function resolveApplicationCache(): CacheLike;
|
|
9
10
|
declare function resolveApplicationQueue(): Queue;
|
|
11
|
+
declare function resolveApplicationEventBus(): EventBus;
|
|
10
12
|
declare function resolveApplicationAuth(): AuthManager;
|
|
11
13
|
declare function resolveApplicationPolicyGate(): PolicyGate;
|
|
12
14
|
declare function resolveApplicationConfig(): import("../contracts/container").ConfigStoreLike;
|
|
13
15
|
declare function resolveApplicationLogger(): Logger;
|
|
14
16
|
declare function resolveApplicationDependencies(): import("../contracts/di").AppDependencies;
|
|
15
|
-
export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, };
|
|
17
|
+
export { resolveApplicationAuth, resolveApplicationCache, resolveApplicationConfig, resolveApplicationDependencies, resolveApplicationEventBus, resolveApplicationLogger, resolveApplicationPolicyGate, resolveApplicationQueue, setActiveApplicationContext, };
|
|
@@ -25,6 +25,7 @@ function resolveService(dependencies, token) {
|
|
|
25
25
|
var CORE_CONFIG_TOKEN = "core.config";
|
|
26
26
|
var CORE_CACHE_TOKEN = "core.cache";
|
|
27
27
|
var CORE_QUEUE_TOKEN = "core.queue";
|
|
28
|
+
var CORE_EVENT_BUS_TOKEN = "core.eventBus";
|
|
28
29
|
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
29
30
|
var CORE_AUTH_TOKEN = "core.auth";
|
|
30
31
|
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
@@ -95,6 +96,9 @@ function resolveApplicationCache() {
|
|
|
95
96
|
function resolveApplicationQueue() {
|
|
96
97
|
return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
|
|
97
98
|
}
|
|
99
|
+
function resolveApplicationEventBus() {
|
|
100
|
+
return requireActiveApplicationContext().container.resolve(CORE_EVENT_BUS_TOKEN);
|
|
101
|
+
}
|
|
98
102
|
function resolveApplicationAuth() {
|
|
99
103
|
return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
|
|
100
104
|
}
|
|
@@ -115,6 +119,7 @@ export {
|
|
|
115
119
|
resolveApplicationQueue,
|
|
116
120
|
resolveApplicationPolicyGate,
|
|
117
121
|
resolveApplicationLogger,
|
|
122
|
+
resolveApplicationEventBus,
|
|
118
123
|
resolveApplicationDependencies,
|
|
119
124
|
resolveApplicationConfig,
|
|
120
125
|
resolveApplicationCache,
|
|
@@ -1,8 +1,62 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// ../../src/bootstrap/discoverModules.ts
|
|
3
|
-
|
|
3
|
+
import { readdirSync } from "fs";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { pathToFileURL } from "url";
|
|
6
|
+
var DISCOVER_MODULES_STATE_KEY = Symbol.for("@getstrata/discoverModulesState");
|
|
7
|
+
function readDiscoverModulesState() {
|
|
8
|
+
const existing = globalThis[DISCOVER_MODULES_STATE_KEY];
|
|
9
|
+
if (existing) {
|
|
10
|
+
return existing;
|
|
11
|
+
}
|
|
12
|
+
const state = { appModules: [] };
|
|
13
|
+
globalThis[DISCOVER_MODULES_STATE_KEY] = state;
|
|
14
|
+
return state;
|
|
15
|
+
}
|
|
16
|
+
function configureModulesDirectory(modulesDir) {
|
|
17
|
+
readDiscoverModulesState().configuredModulesDir = modulesDir;
|
|
18
|
+
}
|
|
19
|
+
function resolveModulesDirectory(options) {
|
|
20
|
+
const state = readDiscoverModulesState();
|
|
21
|
+
if (options?.modulesDir) {
|
|
22
|
+
return options.modulesDir;
|
|
23
|
+
}
|
|
24
|
+
if (state.configuredModulesDir) {
|
|
25
|
+
return state.configuredModulesDir;
|
|
26
|
+
}
|
|
27
|
+
return join(import.meta.dir, "../modules");
|
|
28
|
+
}
|
|
29
|
+
async function loadDiscoveredModules(options) {
|
|
30
|
+
const modulesDirectory = resolveModulesDirectory(options);
|
|
31
|
+
let moduleNames;
|
|
32
|
+
try {
|
|
33
|
+
moduleNames = readdirSync(modulesDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (error.code === "ENOENT") {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
const modules = await Promise.all(moduleNames.map(async (moduleName) => {
|
|
41
|
+
const moduleUrl = pathToFileURL(join(modulesDirectory, moduleName, "index.ts")).href;
|
|
42
|
+
const loaded = await import(moduleUrl);
|
|
43
|
+
return loaded.default;
|
|
44
|
+
}));
|
|
45
|
+
return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
|
|
46
|
+
}
|
|
47
|
+
async function ensureModulesLoaded(options) {
|
|
48
|
+
const state = readDiscoverModulesState();
|
|
49
|
+
if (state.appModules.length > 0) {
|
|
50
|
+
return state.appModules;
|
|
51
|
+
}
|
|
52
|
+
state.modulesReady ??= loadDiscoveredModules(options).then((modules) => {
|
|
53
|
+
state.appModules.splice(0, state.appModules.length, ...modules);
|
|
54
|
+
return state.appModules;
|
|
55
|
+
});
|
|
56
|
+
return state.modulesReady;
|
|
57
|
+
}
|
|
4
58
|
function discoverModules() {
|
|
5
|
-
return appModules;
|
|
59
|
+
return readDiscoverModulesState().appModules;
|
|
6
60
|
}
|
|
7
61
|
|
|
8
62
|
// ../../src/bootstrap/cache/modelCacheTags.ts
|
package/dist/entries/config.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var CORE_CONFIG_TOKEN = "core.config";
|
|
4
4
|
var CORE_CACHE_TOKEN = "core.cache";
|
|
5
5
|
var CORE_QUEUE_TOKEN = "core.queue";
|
|
6
|
+
var CORE_EVENT_BUS_TOKEN = "core.eventBus";
|
|
6
7
|
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
7
8
|
var CORE_AUTH_TOKEN = "core.auth";
|
|
8
9
|
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
@@ -33,6 +34,7 @@ export {
|
|
|
33
34
|
CORE_TOKEN_SERVICE_TOKEN,
|
|
34
35
|
CORE_QUEUE_TOKEN,
|
|
35
36
|
CORE_POLICY_GATE_TOKEN,
|
|
37
|
+
CORE_EVENT_BUS_TOKEN,
|
|
36
38
|
CORE_CONFIG_TOKEN,
|
|
37
39
|
CORE_CACHE_TOKEN,
|
|
38
40
|
CORE_AUTH_TOKEN,
|
package/dist/entries/context.js
CHANGED
|
@@ -25,6 +25,7 @@ function resolveService(dependencies, token) {
|
|
|
25
25
|
var CORE_CONFIG_TOKEN = "core.config";
|
|
26
26
|
var CORE_CACHE_TOKEN = "core.cache";
|
|
27
27
|
var CORE_QUEUE_TOKEN = "core.queue";
|
|
28
|
+
var CORE_EVENT_BUS_TOKEN = "core.eventBus";
|
|
28
29
|
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
29
30
|
var CORE_AUTH_TOKEN = "core.auth";
|
|
30
31
|
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
@@ -95,6 +96,9 @@ function resolveApplicationCache() {
|
|
|
95
96
|
function resolveApplicationQueue() {
|
|
96
97
|
return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
|
|
97
98
|
}
|
|
99
|
+
function resolveApplicationEventBus() {
|
|
100
|
+
return requireActiveApplicationContext().container.resolve(CORE_EVENT_BUS_TOKEN);
|
|
101
|
+
}
|
|
98
102
|
function resolveApplicationAuth() {
|
|
99
103
|
return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
|
|
100
104
|
}
|
|
@@ -175,9 +179,63 @@ class ConfigStore {
|
|
|
175
179
|
}
|
|
176
180
|
}
|
|
177
181
|
// ../../src/bootstrap/discoverModules.ts
|
|
178
|
-
|
|
182
|
+
import { readdirSync } from "fs";
|
|
183
|
+
import { join } from "path";
|
|
184
|
+
import { pathToFileURL } from "url";
|
|
185
|
+
var DISCOVER_MODULES_STATE_KEY = Symbol.for("@getstrata/discoverModulesState");
|
|
186
|
+
function readDiscoverModulesState() {
|
|
187
|
+
const existing = globalThis[DISCOVER_MODULES_STATE_KEY];
|
|
188
|
+
if (existing) {
|
|
189
|
+
return existing;
|
|
190
|
+
}
|
|
191
|
+
const state = { appModules: [] };
|
|
192
|
+
globalThis[DISCOVER_MODULES_STATE_KEY] = state;
|
|
193
|
+
return state;
|
|
194
|
+
}
|
|
195
|
+
function configureModulesDirectory(modulesDir) {
|
|
196
|
+
readDiscoverModulesState().configuredModulesDir = modulesDir;
|
|
197
|
+
}
|
|
198
|
+
function resolveModulesDirectory(options) {
|
|
199
|
+
const state = readDiscoverModulesState();
|
|
200
|
+
if (options?.modulesDir) {
|
|
201
|
+
return options.modulesDir;
|
|
202
|
+
}
|
|
203
|
+
if (state.configuredModulesDir) {
|
|
204
|
+
return state.configuredModulesDir;
|
|
205
|
+
}
|
|
206
|
+
return join(import.meta.dir, "../modules");
|
|
207
|
+
}
|
|
208
|
+
async function loadDiscoveredModules(options) {
|
|
209
|
+
const modulesDirectory = resolveModulesDirectory(options);
|
|
210
|
+
let moduleNames;
|
|
211
|
+
try {
|
|
212
|
+
moduleNames = readdirSync(modulesDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
if (error.code === "ENOENT") {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
const modules = await Promise.all(moduleNames.map(async (moduleName) => {
|
|
220
|
+
const moduleUrl = pathToFileURL(join(modulesDirectory, moduleName, "index.ts")).href;
|
|
221
|
+
const loaded = await import(moduleUrl);
|
|
222
|
+
return loaded.default;
|
|
223
|
+
}));
|
|
224
|
+
return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
|
|
225
|
+
}
|
|
226
|
+
async function ensureModulesLoaded(options) {
|
|
227
|
+
const state = readDiscoverModulesState();
|
|
228
|
+
if (state.appModules.length > 0) {
|
|
229
|
+
return state.appModules;
|
|
230
|
+
}
|
|
231
|
+
state.modulesReady ??= loadDiscoveredModules(options).then((modules) => {
|
|
232
|
+
state.appModules.splice(0, state.appModules.length, ...modules);
|
|
233
|
+
return state.appModules;
|
|
234
|
+
});
|
|
235
|
+
return state.modulesReady;
|
|
236
|
+
}
|
|
179
237
|
function discoverModules() {
|
|
180
|
-
return appModules;
|
|
238
|
+
return readDiscoverModulesState().appModules;
|
|
181
239
|
}
|
|
182
240
|
// ../../src/config/auth.ts
|
|
183
241
|
var authConfig = {
|
|
@@ -1449,7 +1507,6 @@ function modelEventName(tableName, action) {
|
|
|
1449
1507
|
}
|
|
1450
1508
|
|
|
1451
1509
|
// ../../src/bootstrap/providers/events.ts
|
|
1452
|
-
var CORE_EVENT_BUS_TOKEN = "core.eventBus";
|
|
1453
1510
|
var eventsProvider = {
|
|
1454
1511
|
name: "core.events",
|
|
1455
1512
|
register({ container }) {
|
|
@@ -1459,14 +1516,14 @@ var eventsProvider = {
|
|
|
1459
1516
|
var events_default = eventsProvider;
|
|
1460
1517
|
|
|
1461
1518
|
// ../../src/bootstrap/discoverListeners.ts
|
|
1462
|
-
import { readdirSync } from "fs";
|
|
1463
|
-
import { join } from "path";
|
|
1464
|
-
import { pathToFileURL } from "url";
|
|
1519
|
+
import { readdirSync as readdirSync2 } from "fs";
|
|
1520
|
+
import { join as join2 } from "path";
|
|
1521
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
1465
1522
|
async function loadDiscoveredListeners() {
|
|
1466
|
-
const listenersDirectory =
|
|
1523
|
+
const listenersDirectory = join2(import.meta.dir, "../listeners");
|
|
1467
1524
|
let entries;
|
|
1468
1525
|
try {
|
|
1469
|
-
entries =
|
|
1526
|
+
entries = readdirSync2(listenersDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => entry.name);
|
|
1470
1527
|
} catch (error) {
|
|
1471
1528
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
1472
1529
|
return [];
|
|
@@ -1474,7 +1531,7 @@ async function loadDiscoveredListeners() {
|
|
|
1474
1531
|
throw error;
|
|
1475
1532
|
}
|
|
1476
1533
|
const listeners = await Promise.all(entries.map(async (fileName) => {
|
|
1477
|
-
const moduleUrl =
|
|
1534
|
+
const moduleUrl = pathToFileURL2(join2(listenersDirectory, fileName)).href;
|
|
1478
1535
|
const loaded = await import(moduleUrl);
|
|
1479
1536
|
return loaded.default;
|
|
1480
1537
|
}));
|
|
@@ -1795,10 +1852,10 @@ function buildHavingClause(tableName, having, params) {
|
|
|
1795
1852
|
return body.length > 0 ? ` HAVING ${body}` : "";
|
|
1796
1853
|
}
|
|
1797
1854
|
function buildJoinClause(joins = []) {
|
|
1798
|
-
return joins.map((
|
|
1799
|
-
const joinType =
|
|
1800
|
-
const onClause =
|
|
1801
|
-
return ` ${joinType} ${quoteIdentifier(
|
|
1855
|
+
return joins.map((join3) => {
|
|
1856
|
+
const joinType = join3.type === "left" ? "LEFT JOIN" : "INNER JOIN";
|
|
1857
|
+
const onClause = join3.on.map(({ left, right }) => `${qualifyColumn(left.table, left.column)} = ${qualifyColumn(right.table, right.column)}`).join(" AND ");
|
|
1858
|
+
return ` ${joinType} ${quoteIdentifier(join3.table)} ON ${onClause}`;
|
|
1802
1859
|
}).join("");
|
|
1803
1860
|
}
|
|
1804
1861
|
function buildLimitClause(limit) {
|
|
@@ -2234,7 +2291,7 @@ class RepositoryQuery {
|
|
|
2234
2291
|
const rightRef = parseQualifiedColumn(right);
|
|
2235
2292
|
const table = type === "inner" ? rightRef.table : rightRef.table;
|
|
2236
2293
|
const joins = this.queryOptions.joins ?? [];
|
|
2237
|
-
const existing = joins.find((
|
|
2294
|
+
const existing = joins.find((join3) => join3.table === table && join3.type === type);
|
|
2238
2295
|
if (existing) {
|
|
2239
2296
|
existing.on.push({ left: leftRef, right: rightRef });
|
|
2240
2297
|
return this;
|
|
@@ -3734,7 +3791,7 @@ var queue_default = queueProvider;
|
|
|
3734
3791
|
|
|
3735
3792
|
// ../../src/core/storage/storage.ts
|
|
3736
3793
|
import { mkdir, readFile, unlink, writeFile } from "fs/promises";
|
|
3737
|
-
import { dirname, join as
|
|
3794
|
+
import { dirname, join as join3 } from "path";
|
|
3738
3795
|
var {S3Client } = globalThis.Bun;
|
|
3739
3796
|
|
|
3740
3797
|
class LocalStorageDriver {
|
|
@@ -3746,7 +3803,7 @@ class LocalStorageDriver {
|
|
|
3746
3803
|
return this.rootDirectory ?? process.env.STORAGE_PATH ?? "storage";
|
|
3747
3804
|
}
|
|
3748
3805
|
resolvePath(path) {
|
|
3749
|
-
return
|
|
3806
|
+
return join3(this.resolveRootDirectory(), path.replace(/^\/+/, ""));
|
|
3750
3807
|
}
|
|
3751
3808
|
async put(path, contents) {
|
|
3752
3809
|
const absolutePath = this.resolvePath(path);
|
|
@@ -3879,9 +3936,9 @@ function currentRequestMeta() {
|
|
|
3879
3936
|
}
|
|
3880
3937
|
|
|
3881
3938
|
// ../../src/core/view/etaViewEngine.ts
|
|
3882
|
-
import { join as
|
|
3939
|
+
import { join as join4 } from "path";
|
|
3883
3940
|
import { Eta } from "eta";
|
|
3884
|
-
var DEFAULT_VIEWS_DIRECTORY =
|
|
3941
|
+
var DEFAULT_VIEWS_DIRECTORY = join4(process.cwd(), "resources/views");
|
|
3885
3942
|
var DEFAULT_LAYOUT = "layouts/app.eta";
|
|
3886
3943
|
|
|
3887
3944
|
class EtaViewEngine {
|
|
@@ -4174,7 +4231,7 @@ function assertProductionSecrets(env = process.env) {
|
|
|
4174
4231
|
}
|
|
4175
4232
|
|
|
4176
4233
|
// ../../src/bootstrap/context.ts
|
|
4177
|
-
function collectProviders(modules =
|
|
4234
|
+
function collectProviders(modules = discoverModules()) {
|
|
4178
4235
|
return [...coreProviders, ...modules.flatMap((module) => module.providers ?? [])];
|
|
4179
4236
|
}
|
|
4180
4237
|
function runProviderPhase(providers, phase, context) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// ../../src/bootstrap/createWebRoutes.ts
|
|
3
|
-
import { join as
|
|
3
|
+
import { join as join3 } from "path";
|
|
4
4
|
|
|
5
5
|
// ../../src/config/frontend.ts
|
|
6
6
|
function readFrontendMode() {
|
|
@@ -114,6 +114,7 @@ function htmlResponse(html, init = {}) {
|
|
|
114
114
|
var CORE_CONFIG_TOKEN = "core.config";
|
|
115
115
|
var CORE_CACHE_TOKEN = "core.cache";
|
|
116
116
|
var CORE_QUEUE_TOKEN = "core.queue";
|
|
117
|
+
var CORE_EVENT_BUS_TOKEN = "core.eventBus";
|
|
117
118
|
var CORE_POLICY_GATE_TOKEN = "core.policyGate";
|
|
118
119
|
var CORE_AUTH_TOKEN = "core.auth";
|
|
119
120
|
var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
|
|
@@ -907,9 +908,63 @@ function createHttpKernel(dependencies) {
|
|
|
907
908
|
}
|
|
908
909
|
|
|
909
910
|
// ../../src/bootstrap/discoverModules.ts
|
|
910
|
-
|
|
911
|
+
import { readdirSync } from "fs";
|
|
912
|
+
import { join as join2 } from "path";
|
|
913
|
+
import { pathToFileURL } from "url";
|
|
914
|
+
var DISCOVER_MODULES_STATE_KEY = Symbol.for("@getstrata/discoverModulesState");
|
|
915
|
+
function readDiscoverModulesState() {
|
|
916
|
+
const existing = globalThis[DISCOVER_MODULES_STATE_KEY];
|
|
917
|
+
if (existing) {
|
|
918
|
+
return existing;
|
|
919
|
+
}
|
|
920
|
+
const state = { appModules: [] };
|
|
921
|
+
globalThis[DISCOVER_MODULES_STATE_KEY] = state;
|
|
922
|
+
return state;
|
|
923
|
+
}
|
|
924
|
+
function configureModulesDirectory(modulesDir) {
|
|
925
|
+
readDiscoverModulesState().configuredModulesDir = modulesDir;
|
|
926
|
+
}
|
|
927
|
+
function resolveModulesDirectory(options) {
|
|
928
|
+
const state = readDiscoverModulesState();
|
|
929
|
+
if (options?.modulesDir) {
|
|
930
|
+
return options.modulesDir;
|
|
931
|
+
}
|
|
932
|
+
if (state.configuredModulesDir) {
|
|
933
|
+
return state.configuredModulesDir;
|
|
934
|
+
}
|
|
935
|
+
return join2(import.meta.dir, "../modules");
|
|
936
|
+
}
|
|
937
|
+
async function loadDiscoveredModules(options) {
|
|
938
|
+
const modulesDirectory = resolveModulesDirectory(options);
|
|
939
|
+
let moduleNames;
|
|
940
|
+
try {
|
|
941
|
+
moduleNames = readdirSync(modulesDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
942
|
+
} catch (error) {
|
|
943
|
+
if (error.code === "ENOENT") {
|
|
944
|
+
return [];
|
|
945
|
+
}
|
|
946
|
+
throw error;
|
|
947
|
+
}
|
|
948
|
+
const modules = await Promise.all(moduleNames.map(async (moduleName) => {
|
|
949
|
+
const moduleUrl = pathToFileURL(join2(modulesDirectory, moduleName, "index.ts")).href;
|
|
950
|
+
const loaded = await import(moduleUrl);
|
|
951
|
+
return loaded.default;
|
|
952
|
+
}));
|
|
953
|
+
return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
|
|
954
|
+
}
|
|
955
|
+
async function ensureModulesLoaded(options) {
|
|
956
|
+
const state = readDiscoverModulesState();
|
|
957
|
+
if (state.appModules.length > 0) {
|
|
958
|
+
return state.appModules;
|
|
959
|
+
}
|
|
960
|
+
state.modulesReady ??= loadDiscoveredModules(options).then((modules) => {
|
|
961
|
+
state.appModules.splice(0, state.appModules.length, ...modules);
|
|
962
|
+
return state.appModules;
|
|
963
|
+
});
|
|
964
|
+
return state.modulesReady;
|
|
965
|
+
}
|
|
911
966
|
function discoverModules() {
|
|
912
|
-
return appModules;
|
|
967
|
+
return readDiscoverModulesState().appModules;
|
|
913
968
|
}
|
|
914
969
|
// ../../src/bootstrap/routeRegistry.ts
|
|
915
970
|
class RouteRegistry {
|
|
@@ -924,7 +979,17 @@ class RouteRegistry {
|
|
|
924
979
|
return [...this.routes].sort((left, right) => left.path.localeCompare(right.path));
|
|
925
980
|
}
|
|
926
981
|
}
|
|
927
|
-
var
|
|
982
|
+
var ROUTE_REGISTRY_KEY = Symbol.for("@getstrata/routeRegistry");
|
|
983
|
+
function readSharedRouteRegistry() {
|
|
984
|
+
const globalRegistry = globalThis[ROUTE_REGISTRY_KEY];
|
|
985
|
+
if (globalRegistry) {
|
|
986
|
+
return globalRegistry;
|
|
987
|
+
}
|
|
988
|
+
const registry = new RouteRegistry;
|
|
989
|
+
globalThis[ROUTE_REGISTRY_KEY] = registry;
|
|
990
|
+
return registry;
|
|
991
|
+
}
|
|
992
|
+
var routeRegistry = readSharedRouteRegistry();
|
|
928
993
|
|
|
929
994
|
// ../../src/bootstrap/createWebRoutes.ts
|
|
930
995
|
function registerRoute(method, path, middleware) {
|
|
@@ -953,7 +1018,7 @@ function createWebRoutes(dependencies) {
|
|
|
953
1018
|
"/": () => Response.redirect("/organizations", 302)
|
|
954
1019
|
};
|
|
955
1020
|
registerRoute("GET", "/", ["global", "web"]);
|
|
956
|
-
for (const module of
|
|
1021
|
+
for (const module of discoverModules()) {
|
|
957
1022
|
if (!module.webRoutes) {
|
|
958
1023
|
continue;
|
|
959
1024
|
}
|
|
@@ -968,7 +1033,7 @@ function createWebRoutes(dependencies) {
|
|
|
968
1033
|
registerRoute("GET", "/assets/*", ["global", "web"]);
|
|
969
1034
|
const pathname = new URL(request.url).pathname;
|
|
970
1035
|
const relativePath = pathname.replace(/^\//, "");
|
|
971
|
-
const file = Bun.file(
|
|
1036
|
+
const file = Bun.file(join3(process.cwd(), "public", relativePath));
|
|
972
1037
|
if (!await file.exists()) {
|
|
973
1038
|
return htmlResponse("Not Found", { status: 404 });
|
|
974
1039
|
}
|