@getstrata/bootstrap 0.2.9 → 0.2.12
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/cache/modelCacheTags.d.ts +3 -0
- 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 +1 -0
- package/dist/bootstrap/routeRegistry.d.ts +1 -5
- package/dist/bootstrap/server.d.ts +1 -1
- package/dist/core/auth/authContext.d.ts +1 -2
- package/dist/core/auth/guard.d.ts +2 -2
- package/dist/core/auth/membershipContext.d.ts +1 -2
- package/dist/core/auth/sessionGuard.d.ts +2 -2
- package/dist/core/cache/modelCacheTags.d.ts +1 -3
- package/dist/core/contracts/serviceContainer.d.ts +5 -0
- package/dist/core/http/requestMetaContext.d.ts +1 -2
- package/dist/core/openapi/registeredRoute.d.ts +6 -0
- package/dist/core/runtime/asyncContextStore.d.ts +3 -0
- package/dist/core/tenant/tenantContext.d.ts +1 -2
- package/dist/core/tracing/traceContext.d.ts +1 -2
- package/dist/core/view/webLayoutData.d.ts +2 -2
- package/dist/entries/applicationRegistry.js +15 -2
- package/dist/entries/cache/modelCacheTags.js +22 -0
- package/dist/entries/context.js +150 -147
- package/dist/entries/createWebRoutes.js +22 -29
- package/dist/entries/http/securedRouteModelBinding.js +31 -6
- package/dist/entries/membershipService.js +32 -10
- package/dist/entries/providers/view.js +17 -6
- package/dist/entries/providers.js +59 -52
- package/dist/entries/queue/defaultJobs.js +30 -4
- package/dist/framework/public-api.d.ts +1 -0
- package/dist/index.js +69 -68
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -70,9 +70,22 @@ function getBoundDatabaseConnection() {
|
|
|
70
70
|
return boundConnectionHolder.connection;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
// ../../src/core/
|
|
73
|
+
// ../../src/core/runtime/asyncContextStore.ts
|
|
74
74
|
import { AsyncLocalStorage } from "async_hooks";
|
|
75
|
-
|
|
75
|
+
function createAsyncContextStore(key) {
|
|
76
|
+
const symbol = Symbol.for(key);
|
|
77
|
+
const globalRecord = globalThis;
|
|
78
|
+
const existing = globalRecord[symbol];
|
|
79
|
+
if (existing) {
|
|
80
|
+
return existing;
|
|
81
|
+
}
|
|
82
|
+
const store = new AsyncLocalStorage;
|
|
83
|
+
globalRecord[symbol] = store;
|
|
84
|
+
return store;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ../../src/core/database/connectionContext.ts
|
|
88
|
+
var activeConnection = createAsyncContextStore("@getstrata/databaseConnectionContext");
|
|
76
89
|
function getActiveDatabaseConnection(fallback) {
|
|
77
90
|
return activeConnection.getStore() ?? fallback;
|
|
78
91
|
}
|
|
@@ -596,15 +609,28 @@ function resolveService(dependencies, token) {
|
|
|
596
609
|
}
|
|
597
610
|
|
|
598
611
|
// ../../src/bootstrap/applicationRegistry.ts
|
|
612
|
+
var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
|
|
599
613
|
var activeContext;
|
|
614
|
+
function readStoredApplicationContext() {
|
|
615
|
+
if (activeContext) {
|
|
616
|
+
return activeContext;
|
|
617
|
+
}
|
|
618
|
+
const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
|
|
619
|
+
if (globalContext) {
|
|
620
|
+
activeContext = globalContext;
|
|
621
|
+
}
|
|
622
|
+
return activeContext;
|
|
623
|
+
}
|
|
600
624
|
function setActiveApplicationContext(context) {
|
|
601
625
|
activeContext = context;
|
|
626
|
+
globalThis[APPLICATION_CONTEXT_KEY] = context;
|
|
602
627
|
}
|
|
603
628
|
function requireActiveApplicationContext() {
|
|
604
|
-
|
|
629
|
+
const context = readStoredApplicationContext();
|
|
630
|
+
if (!context) {
|
|
605
631
|
throw new Error("The application context has not been bootstrapped.");
|
|
606
632
|
}
|
|
607
|
-
return
|
|
633
|
+
return context;
|
|
608
634
|
}
|
|
609
635
|
function resolveApplicationCache() {
|
|
610
636
|
return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
|
|
@@ -627,32 +653,23 @@ function resolveApplicationLogger() {
|
|
|
627
653
|
function resolveApplicationDependencies() {
|
|
628
654
|
return requireActiveApplicationContext().dependencies;
|
|
629
655
|
}
|
|
630
|
-
// ../../src/bootstrap/context.ts
|
|
631
|
-
import { setActiveApplicationContext as setActiveApplicationContext2 } from "@getstrata/core";
|
|
632
|
-
|
|
633
656
|
// ../../src/bootstrap/discoverModules.ts
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
const moduleUrl = pathToFileURL(join(modulesDirectory, moduleName, "index.ts")).href;
|
|
650
|
-
const loaded = await import(moduleUrl);
|
|
651
|
-
return loaded.default;
|
|
652
|
-
}));
|
|
653
|
-
return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
|
|
657
|
+
var appModules = [];
|
|
658
|
+
function discoverModules() {
|
|
659
|
+
return appModules;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// ../../src/bootstrap/cache/modelCacheTags.ts
|
|
663
|
+
function cacheTagsForModelWrite(tableName, action) {
|
|
664
|
+
const module = discoverModules().find((entry) => entry.tableName === tableName);
|
|
665
|
+
const baseTags = module?.cacheTags ?? [`${tableName}s`];
|
|
666
|
+
const isDelete = action === "deleted" || action === "force-deleted";
|
|
667
|
+
const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
|
|
668
|
+
return [...new Set([...baseTags, ...extraTags])];
|
|
669
|
+
}
|
|
670
|
+
function discoverModelTableNames() {
|
|
671
|
+
return discoverModules().map((module) => module.tableName).filter((tableName) => tableName !== undefined);
|
|
654
672
|
}
|
|
655
|
-
var appModules = await loadDiscoveredModules();
|
|
656
673
|
// ../../src/config/auth.ts
|
|
657
674
|
var authConfig = {
|
|
658
675
|
allowDevHeaders: (process.env.AUTH_DEV_HEADERS ?? "true") !== "false",
|
|
@@ -942,8 +959,7 @@ import { resolveDefaultTokenExpiryDays as resolveDefaultTokenExpiryDays2 } from
|
|
|
942
959
|
var tokenServiceToken = CORE_TOKEN_SERVICE_TOKEN;
|
|
943
960
|
|
|
944
961
|
// ../../src/core/auth/authContext.ts
|
|
945
|
-
|
|
946
|
-
var authContext = new AsyncLocalStorage2;
|
|
962
|
+
var authContext = createAsyncContextStore("@getstrata/authContext");
|
|
947
963
|
function currentAuthUser() {
|
|
948
964
|
return authContext.getStore() ?? null;
|
|
949
965
|
}
|
|
@@ -1782,14 +1798,14 @@ var eventsProvider = {
|
|
|
1782
1798
|
var events_default = eventsProvider;
|
|
1783
1799
|
|
|
1784
1800
|
// ../../src/bootstrap/discoverListeners.ts
|
|
1785
|
-
import { readdirSync
|
|
1786
|
-
import { join
|
|
1787
|
-
import { pathToFileURL
|
|
1801
|
+
import { readdirSync } from "fs";
|
|
1802
|
+
import { join } from "path";
|
|
1803
|
+
import { pathToFileURL } from "url";
|
|
1788
1804
|
async function loadDiscoveredListeners() {
|
|
1789
|
-
const listenersDirectory =
|
|
1805
|
+
const listenersDirectory = join(import.meta.dir, "../listeners");
|
|
1790
1806
|
let entries;
|
|
1791
1807
|
try {
|
|
1792
|
-
entries =
|
|
1808
|
+
entries = readdirSync(listenersDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => entry.name);
|
|
1793
1809
|
} catch (error) {
|
|
1794
1810
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
1795
1811
|
return [];
|
|
@@ -1797,7 +1813,7 @@ async function loadDiscoveredListeners() {
|
|
|
1797
1813
|
throw error;
|
|
1798
1814
|
}
|
|
1799
1815
|
const listeners = await Promise.all(entries.map(async (fileName) => {
|
|
1800
|
-
const moduleUrl =
|
|
1816
|
+
const moduleUrl = pathToFileURL(join(listenersDirectory, fileName)).href;
|
|
1801
1817
|
const loaded = await import(moduleUrl);
|
|
1802
1818
|
return loaded.default;
|
|
1803
1819
|
}));
|
|
@@ -1808,18 +1824,6 @@ function discoverListeners() {
|
|
|
1808
1824
|
return appListeners;
|
|
1809
1825
|
}
|
|
1810
1826
|
|
|
1811
|
-
// ../../src/core/cache/modelCacheTags.ts
|
|
1812
|
-
function cacheTagsForModelWrite(tableName, action) {
|
|
1813
|
-
const module = appModules.find((entry) => entry.tableName === tableName);
|
|
1814
|
-
const baseTags = module?.cacheTags ?? [`${tableName}s`];
|
|
1815
|
-
const isDelete = action === "deleted" || action === "force-deleted";
|
|
1816
|
-
const extraTags = isDelete ? module?.cacheDeleteExtraTags ?? [] : [];
|
|
1817
|
-
return [...new Set([...baseTags, ...extraTags])];
|
|
1818
|
-
}
|
|
1819
|
-
function discoverModelTableNames() {
|
|
1820
|
-
return appModules.map((module) => module.tableName).filter((tableName) => tableName !== undefined);
|
|
1821
|
-
}
|
|
1822
|
-
|
|
1823
1827
|
// ../../src/core/queue/index.ts
|
|
1824
1828
|
class Job {
|
|
1825
1829
|
maxAttempts;
|
|
@@ -2130,10 +2134,10 @@ function buildHavingClause(tableName, having, params) {
|
|
|
2130
2134
|
return body.length > 0 ? ` HAVING ${body}` : "";
|
|
2131
2135
|
}
|
|
2132
2136
|
function buildJoinClause(joins = []) {
|
|
2133
|
-
return joins.map((
|
|
2134
|
-
const joinType =
|
|
2135
|
-
const onClause =
|
|
2136
|
-
return ` ${joinType} ${quoteIdentifier(
|
|
2137
|
+
return joins.map((join2) => {
|
|
2138
|
+
const joinType = join2.type === "left" ? "LEFT JOIN" : "INNER JOIN";
|
|
2139
|
+
const onClause = join2.on.map(({ left, right }) => `${qualifyColumn(left.table, left.column)} = ${qualifyColumn(right.table, right.column)}`).join(" AND ");
|
|
2140
|
+
return ` ${joinType} ${quoteIdentifier(join2.table)} ON ${onClause}`;
|
|
2137
2141
|
}).join("");
|
|
2138
2142
|
}
|
|
2139
2143
|
function buildLimitClause(limit) {
|
|
@@ -2546,7 +2550,7 @@ class RepositoryQuery {
|
|
|
2546
2550
|
const rightRef = parseQualifiedColumn(right);
|
|
2547
2551
|
const table = type === "inner" ? rightRef.table : rightRef.table;
|
|
2548
2552
|
const joins = this.queryOptions.joins ?? [];
|
|
2549
|
-
const existing = joins.find((
|
|
2553
|
+
const existing = joins.find((join2) => join2.table === table && join2.type === type);
|
|
2550
2554
|
if (existing) {
|
|
2551
2555
|
existing.on.push({ left: leftRef, right: rightRef });
|
|
2552
2556
|
return this;
|
|
@@ -3899,7 +3903,7 @@ var queue_default = queueProvider;
|
|
|
3899
3903
|
|
|
3900
3904
|
// ../../src/core/storage/storage.ts
|
|
3901
3905
|
import { mkdir, readFile, unlink, writeFile } from "fs/promises";
|
|
3902
|
-
import { dirname, join as
|
|
3906
|
+
import { dirname, join as join2 } from "path";
|
|
3903
3907
|
var {S3Client } = globalThis.Bun;
|
|
3904
3908
|
|
|
3905
3909
|
class LocalStorageDriver {
|
|
@@ -3911,7 +3915,7 @@ class LocalStorageDriver {
|
|
|
3911
3915
|
return this.rootDirectory ?? process.env.STORAGE_PATH ?? "storage";
|
|
3912
3916
|
}
|
|
3913
3917
|
resolvePath(path) {
|
|
3914
|
-
return
|
|
3918
|
+
return join2(this.resolveRootDirectory(), path.replace(/^\/+/, ""));
|
|
3915
3919
|
}
|
|
3916
3920
|
async put(path, contents) {
|
|
3917
3921
|
const absolutePath = this.resolvePath(path);
|
|
@@ -4035,8 +4039,7 @@ function isViewsEnabled() {
|
|
|
4035
4039
|
}
|
|
4036
4040
|
|
|
4037
4041
|
// ../../src/core/http/requestMetaContext.ts
|
|
4038
|
-
|
|
4039
|
-
var requestMetaContext = new AsyncLocalStorage3;
|
|
4042
|
+
var requestMetaContext = createAsyncContextStore("@getstrata/requestMetaContext");
|
|
4040
4043
|
function currentRequestMeta() {
|
|
4041
4044
|
return requestMetaContext.getStore() ?? {
|
|
4042
4045
|
ipAddress: null,
|
|
@@ -4045,9 +4048,9 @@ function currentRequestMeta() {
|
|
|
4045
4048
|
}
|
|
4046
4049
|
|
|
4047
4050
|
// ../../src/core/view/etaViewEngine.ts
|
|
4048
|
-
import { join as
|
|
4051
|
+
import { join as join3 } from "path";
|
|
4049
4052
|
import { Eta } from "eta";
|
|
4050
|
-
var DEFAULT_VIEWS_DIRECTORY =
|
|
4053
|
+
var DEFAULT_VIEWS_DIRECTORY = join3(process.cwd(), "resources/views");
|
|
4051
4054
|
var DEFAULT_LAYOUT = "layouts/app.eta";
|
|
4052
4055
|
|
|
4053
4056
|
class EtaViewEngine {
|
|
@@ -4369,11 +4372,11 @@ function createAppContext() {
|
|
|
4369
4372
|
config,
|
|
4370
4373
|
dependencies
|
|
4371
4374
|
};
|
|
4372
|
-
|
|
4375
|
+
setActiveApplicationContext(appContext);
|
|
4373
4376
|
return appContext;
|
|
4374
4377
|
}
|
|
4375
4378
|
// ../../src/bootstrap/createWebRoutes.ts
|
|
4376
|
-
import { join as
|
|
4379
|
+
import { join as join4 } from "path";
|
|
4377
4380
|
|
|
4378
4381
|
// ../../src/core/http/middleware.ts
|
|
4379
4382
|
function isRouteHandler(value) {
|
|
@@ -4707,7 +4710,7 @@ function createWebRoutes(dependencies) {
|
|
|
4707
4710
|
registerRoute("GET", "/assets/*", ["global", "web"]);
|
|
4708
4711
|
const pathname = new URL(request.url).pathname;
|
|
4709
4712
|
const relativePath = pathname.replace(/^\//, "");
|
|
4710
|
-
const file = Bun.file(
|
|
4713
|
+
const file = Bun.file(join4(process.cwd(), "public", relativePath));
|
|
4711
4714
|
if (!await file.exists()) {
|
|
4712
4715
|
return htmlResponse("Not Found", { status: 404 });
|
|
4713
4716
|
}
|
|
@@ -4817,8 +4820,7 @@ function applyConditionalGet(request, response, etag) {
|
|
|
4817
4820
|
}
|
|
4818
4821
|
|
|
4819
4822
|
// ../../src/core/tenant/tenantContext.ts
|
|
4820
|
-
|
|
4821
|
-
var tenantContext = new AsyncLocalStorage4;
|
|
4823
|
+
var tenantContext = createAsyncContextStore("@getstrata/tenantContext");
|
|
4822
4824
|
|
|
4823
4825
|
// ../../src/core/http/validation.ts
|
|
4824
4826
|
function parsePositiveIntParam(value, name = "id") {
|
|
@@ -4899,9 +4901,6 @@ function resolveUserId(user) {
|
|
|
4899
4901
|
return userId;
|
|
4900
4902
|
}
|
|
4901
4903
|
|
|
4902
|
-
// ../../src/core/auth/membershipContext.ts
|
|
4903
|
-
import { AsyncLocalStorage as AsyncLocalStorage5 } from "async_hooks";
|
|
4904
|
-
|
|
4905
4904
|
// ../../src/modules/organization/memberRepository.ts
|
|
4906
4905
|
class OrganizationMemberRepository {
|
|
4907
4906
|
constructor() {}
|
|
@@ -4954,7 +4953,7 @@ class OrganizationMemberRepository {
|
|
|
4954
4953
|
var memberRepository_default = OrganizationMemberRepository;
|
|
4955
4954
|
|
|
4956
4955
|
// ../../src/core/auth/membershipContext.ts
|
|
4957
|
-
var membershipContext =
|
|
4956
|
+
var membershipContext = createAsyncContextStore("@getstrata/membershipContext");
|
|
4958
4957
|
var membershipRepository = new memberRepository_default;
|
|
4959
4958
|
|
|
4960
4959
|
// ../../src/core/auth/membershipService.ts
|
|
@@ -5275,6 +5274,7 @@ export {
|
|
|
5275
5274
|
parseFormBody,
|
|
5276
5275
|
mergeWebRoutes,
|
|
5277
5276
|
getRequiredDependency,
|
|
5277
|
+
discoverModelTableNames,
|
|
5278
5278
|
createWebServer,
|
|
5279
5279
|
createWebRoutes,
|
|
5280
5280
|
createRouteKernel,
|
|
@@ -5283,6 +5283,7 @@ export {
|
|
|
5283
5283
|
createAppContext,
|
|
5284
5284
|
coreProviders,
|
|
5285
5285
|
collectProviders,
|
|
5286
|
+
cacheTagsForModelWrite,
|
|
5286
5287
|
assertAppDependenciesComplete,
|
|
5287
5288
|
appSchedule,
|
|
5288
5289
|
ServiceContainer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getstrata/bootstrap",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
4
4
|
"description": "Strata application bootstrap — HttpKernel, DI, web session helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
"import": "./dist/index.js",
|
|
16
16
|
"default": "./dist/index.js"
|
|
17
17
|
},
|
|
18
|
+
"./cache/modelCacheTags": {
|
|
19
|
+
"types": "./dist/bootstrap/cache/modelCacheTags.d.ts",
|
|
20
|
+
"import": "./dist/entries/cache/modelCacheTags.js",
|
|
21
|
+
"default": "./dist/entries/cache/modelCacheTags.js"
|
|
22
|
+
},
|
|
18
23
|
"./applicationRegistry": {
|
|
19
24
|
"types": "./dist/bootstrap/applicationRegistry.d.ts",
|
|
20
25
|
"import": "./dist/entries/applicationRegistry.js",
|
|
@@ -82,14 +87,14 @@
|
|
|
82
87
|
"build:bundle": "bun build index.ts --outdir dist --target bun --external bun --external eta --external @getstrata/core",
|
|
83
88
|
"build:types": "tsc -p tsconfig.types.json",
|
|
84
89
|
"prepublishOnly": "bun run build",
|
|
85
|
-
"build:subpaths": "bun build entries/applicationRegistry.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/membershipService.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core",
|
|
90
|
+
"build:subpaths": "bun build entries/applicationRegistry.ts entries/cache/modelCacheTags.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/membershipService.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core",
|
|
86
91
|
"build:shims": "true"
|
|
87
92
|
},
|
|
88
93
|
"publishConfig": {
|
|
89
94
|
"access": "public"
|
|
90
95
|
},
|
|
91
96
|
"peerDependencies": {
|
|
92
|
-
"@getstrata/core": "^0.5.
|
|
97
|
+
"@getstrata/core": "^0.5.20",
|
|
93
98
|
"typescript": "^5.9.0"
|
|
94
99
|
}
|
|
95
100
|
}
|