@getstrata/bootstrap 0.2.50 → 0.2.51

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # @getstrata/bootstrap changelog
2
2
 
3
+ ## 0.2.51
4
+
5
+ - `createCookieSessionAuthManager` returns `CookieSessionAuthManager` (`signIn`, `signOut`, `signInRedirect`, `signOutRedirect`). Controllers no longer need a local cookie helper.
6
+ - Pass `loadSessionUser` to replace the default `users.learn_subscriber` / `users.is_admin` session query. Keep `mapUser` in the app.
7
+
3
8
  ## 0.2.50
4
9
 
5
10
  - `createCookieSessionAuthManager` / `CookieSessionGuard` turn `CookieSessionStore` into an `AuthGuard` / `AuthManager` for `CORE_AUTH_TOKEN`. Supply a `mapUser` mapper; WorkHub abilities are not baked in. Omit `sql` to read the client from `bindDatabaseConnection()` on every call.
package/README.md CHANGED
@@ -30,7 +30,7 @@ import { createHttpKernel, createAppContext, coreProviders } from "@getstrata/bo
30
30
 
31
31
  `createAppContext()` does not call `assertProductionSecrets`. WorkHub calls that from `App.serve()` / `queue:work`. Sibling HTMX apps can call it in production without WorkHub API tokens when feature flags are off — see [SIBLING-HTMX.md](../../docs/SIBLING-HTMX.md).
32
32
 
33
- Sibling HTMX apps should bind `createCookieSessionAuthManager` from `@getstrata/bootstrap/web/session` instead of HMAC `SessionGuard`. `CookieSessionStore` reads optional `is_admin` from the user row for `wrapWebGlobalAdmin`. Pass `mapUser` to map `is_admin` / `learn_subscriber` onto `AuthUser.role`.
33
+ Sibling HTMX apps should bind `createCookieSessionAuthManager` from `@getstrata/bootstrap/web/session` instead of HMAC `SessionGuard`. Use `signIn` / `signOut` (or the redirect helpers) instead of calling `CookieSessionStore` from controllers. Pass `mapUser` to map roles in the app. Pass `loadSessionUser` when the default `learn_subscriber` / `is_admin` SELECT does not match your schema.
34
34
 
35
35
  `wrapWeb` applies the web group (CSRF + flash) and `withErrorHandling`, so CSRF `ForbiddenError` becomes an HTML 403 in `FRONTEND_MODE=server-htmx`. `wrapWebLogin` / `wrapWebRegister` include that web group plus throttle — do not wrap them with `wrapWeb` again.
36
36
 
@@ -27,4 +27,4 @@ export { coreProviders } from "./providers/index.ts";
27
27
  export { registerDefaultJobs } from "./queue/defaultJobs.ts";
28
28
  export { RouteRegistry, routeRegistry } from "./routeRegistry.ts";
29
29
  export { assertProductionSecrets } from "./secretsGuard.ts";
30
- export { CookieSessionGuard, CookieSessionStore, createCookieSessionAuthManager, createCsrfProtection, createRouteKernel, createWebServer, type MapSessionUser, type ParsedForm, parseFormBody, routeParams, type SessionUser, slugify, toRouteRequest, type WebServerOptions, wrapSecuredRouteModelByKey, wrapWebLogin, wrapWebRegister, } from "./web/index.ts";
30
+ export { CookieSessionAuthManager, CookieSessionGuard, CookieSessionStore, createCookieSessionAuthManager, createCsrfProtection, createRouteKernel, createWebServer, type LoadSessionUser, type MapSessionUser, type ParsedForm, parseFormBody, routeParams, type SessionUser, slugify, toRouteRequest, type WebServerOptions, wrapSecuredRouteModelByKey, wrapWebLogin, wrapWebRegister, } from "./web/index.ts";
@@ -4,5 +4,5 @@
4
4
  export { createCsrfProtection, type ParsedForm, parseFormBody } from "./forms.ts";
5
5
  export { createRouteKernel, routeParams, toRouteRequest, wrapSecuredRouteModelByKey, wrapWebLogin, wrapWebRegister, } from "./routing.ts";
6
6
  export { convertAppRoutesToBunRoutes, createWebServer, type WebServerOptions } from "./server.ts";
7
- export { CookieSessionGuard, CookieSessionStore, createCookieSessionAuthManager, type MapSessionUser, type SessionUser, } from "./session.ts";
7
+ export { CookieSessionAuthManager, CookieSessionGuard, CookieSessionStore, createCookieSessionAuthManager, type LoadSessionUser, type MapSessionUser, type SessionUser, } from "./session.ts";
8
8
  export { slugify } from "./slug.ts";
@@ -11,6 +11,7 @@ type SqlClient = {
11
11
  unsafe<T>(query: string, params?: readonly unknown[]): Promise<T[]>;
12
12
  };
13
13
  type SqlSource = SqlClient | (() => SqlClient);
14
+ export type LoadSessionUser = (sql: SqlClient, sessionId: string) => Promise<SessionUser | null>;
14
15
  declare function defaultSessionSql(): SqlClient;
15
16
  export type MapSessionUser = (user: SessionUser) => AuthUser;
16
17
  declare function defaultMapSessionUser(user: SessionUser): AuthUser;
@@ -19,9 +20,11 @@ export declare class CookieSessionStore {
19
20
  private readonly secret;
20
21
  private readonly cookieName;
21
22
  private readonly maxAgeSeconds;
22
- constructor(sqlSource: SqlSource, secret: string, cookieName?: string, maxAgeSeconds?: number);
23
+ private readonly loadSessionUser;
24
+ constructor(sqlSource: SqlSource, secret: string, cookieName?: string, maxAgeSeconds?: number, loadSessionUser?: LoadSessionUser);
23
25
  cookieHeader(_user: SessionUser, sessionId: string): string;
24
26
  clearCookieHeader(): string;
27
+ sessionIdFromRequest(request: Request): string | null;
25
28
  private withSecureFlag;
26
29
  private sql;
27
30
  create(user: SessionUser): Promise<string>;
@@ -35,6 +38,19 @@ export declare class CookieSessionGuard implements AuthGuard {
35
38
  constructor(store: CookieSessionStore, mapUser?: MapSessionUser);
36
39
  resolve(request: Request): Promise<AuthUser | null>;
37
40
  }
41
+ export declare class CookieSessionAuthManager extends AuthManager {
42
+ readonly store: CookieSessionStore;
43
+ constructor(store: CookieSessionStore, mapUser?: MapSessionUser);
44
+ signIn(user: SessionUser): Promise<{
45
+ sessionId: string;
46
+ setCookie: string;
47
+ }>;
48
+ signOut(request: Request): Promise<{
49
+ setCookie: string;
50
+ }>;
51
+ signInRedirect(user: SessionUser, location: string, status?: number): Promise<Response>;
52
+ signOutRedirect(request: Request, location: string, status?: number): Promise<Response>;
53
+ }
38
54
  export interface CreateCookieSessionAuthManagerOptions {
39
55
  store?: CookieSessionStore;
40
56
  sql?: SqlSource;
@@ -42,6 +58,7 @@ export interface CreateCookieSessionAuthManagerOptions {
42
58
  cookieName?: string;
43
59
  maxAgeSeconds?: number;
44
60
  mapUser?: MapSessionUser;
61
+ loadSessionUser?: LoadSessionUser;
45
62
  }
46
- declare function createCookieSessionAuthManager(options?: CreateCookieSessionAuthManagerOptions): AuthManager;
63
+ declare function createCookieSessionAuthManager(options?: CreateCookieSessionAuthManagerOptions): CookieSessionAuthManager;
47
64
  export { createCookieSessionAuthManager, defaultMapSessionUser, defaultSessionSql };
@@ -29,17 +29,45 @@ function defaultMapSessionUser(user) {
29
29
  role: user.is_admin ? "admin" : "member"
30
30
  };
31
31
  }
32
+ async function defaultLoadSessionUser(sql, sessionId) {
33
+ const rows = await sql.unsafe(`SELECT s.id, s.user_id, s.expires_at, u.name, u.email, u.learn_subscriber,
34
+ COALESCE(u.is_admin, false) AS is_admin
35
+ FROM sessions s
36
+ INNER JOIN users u ON u.id = s.user_id
37
+ WHERE s.id = $1 AND s.expires_at > NOW()`, [sessionId]);
38
+ const row = rows[0];
39
+ if (!row)
40
+ return null;
41
+ return {
42
+ id: row.user_id,
43
+ name: row.name,
44
+ email: row.email,
45
+ learn_subscriber: row.learn_subscriber,
46
+ is_admin: row.is_admin
47
+ };
48
+ }
49
+ function redirectWithCookie(location, setCookie, status) {
50
+ return new Response(null, {
51
+ status,
52
+ headers: {
53
+ Location: location,
54
+ "Set-Cookie": setCookie
55
+ }
56
+ });
57
+ }
32
58
 
33
59
  class CookieSessionStore {
34
60
  sqlSource;
35
61
  secret;
36
62
  cookieName;
37
63
  maxAgeSeconds;
38
- constructor(sqlSource, secret, cookieName = "strata_session", maxAgeSeconds = 60 * 60 * 24 * 14) {
64
+ loadSessionUser;
65
+ constructor(sqlSource, secret, cookieName = "strata_session", maxAgeSeconds = 60 * 60 * 24 * 14, loadSessionUser = defaultLoadSessionUser) {
39
66
  this.sqlSource = sqlSource;
40
67
  this.secret = secret;
41
68
  this.cookieName = cookieName;
42
69
  this.maxAgeSeconds = maxAgeSeconds;
70
+ this.loadSessionUser = loadSessionUser;
43
71
  }
44
72
  cookieHeader(_user, sessionId) {
45
73
  const payload = `${sessionId}.${this.sign(sessionId)}`;
@@ -48,6 +76,17 @@ class CookieSessionStore {
48
76
  clearCookieHeader() {
49
77
  return this.withSecureFlag(`${this.cookieName}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`);
50
78
  }
79
+ sessionIdFromRequest(request) {
80
+ const cookie = readRequestCookie(request, this.cookieName);
81
+ const raw = cookie ?? null;
82
+ if (!raw)
83
+ return null;
84
+ const [sessionId, signature] = raw.split(".");
85
+ if (!sessionId || !signature || signature !== this.sign(sessionId)) {
86
+ return null;
87
+ }
88
+ return sessionId;
89
+ }
51
90
  withSecureFlag(header) {
52
91
  if (true) {
53
92
  return header;
@@ -71,29 +110,10 @@ class CookieSessionStore {
71
110
  await this.sql().unsafe(`DELETE FROM sessions WHERE id = $1`, [sessionId]);
72
111
  }
73
112
  async read(request) {
74
- const cookie = readRequestCookie(request, this.cookieName);
75
- const raw = cookie ?? null;
76
- if (!raw)
113
+ const sessionId = this.sessionIdFromRequest(request);
114
+ if (!sessionId)
77
115
  return null;
78
- const [sessionId, signature] = raw.split(".");
79
- if (!sessionId || !signature || signature !== this.sign(sessionId)) {
80
- return null;
81
- }
82
- const rows = await this.sql().unsafe(`SELECT s.id, s.user_id, s.expires_at, u.name, u.email, u.learn_subscriber,
83
- COALESCE(u.is_admin, false) AS is_admin
84
- FROM sessions s
85
- INNER JOIN users u ON u.id = s.user_id
86
- WHERE s.id = $1 AND s.expires_at > NOW()`, [sessionId]);
87
- const row = rows[0];
88
- if (!row)
89
- return null;
90
- return {
91
- id: row.user_id,
92
- name: row.name,
93
- email: row.email,
94
- learn_subscriber: row.learn_subscriber,
95
- is_admin: row.is_admin
96
- };
116
+ return this.loadSessionUser(this.sql(), sessionId);
97
117
  }
98
118
  sign(value) {
99
119
  return createHash("sha256").update(`${value}.${this.secret}`).digest("hex").slice(0, 32);
@@ -115,11 +135,39 @@ class CookieSessionGuard {
115
135
  return this.mapUser(user);
116
136
  }
117
137
  }
138
+
139
+ class CookieSessionAuthManager extends AuthManager {
140
+ store;
141
+ constructor(store, mapUser = defaultMapSessionUser) {
142
+ super(new CookieSessionGuard(store, mapUser));
143
+ this.store = store;
144
+ }
145
+ async signIn(user) {
146
+ const sessionId = await this.store.create(user);
147
+ return { sessionId, setCookie: this.store.cookieHeader(user, sessionId) };
148
+ }
149
+ async signOut(request) {
150
+ const sessionId = this.store.sessionIdFromRequest(request);
151
+ if (sessionId) {
152
+ await this.store.destroy(sessionId);
153
+ }
154
+ return { setCookie: this.store.clearCookieHeader() };
155
+ }
156
+ async signInRedirect(user, location, status = 302) {
157
+ const { setCookie } = await this.signIn(user);
158
+ return redirectWithCookie(location, setCookie, status);
159
+ }
160
+ async signOutRedirect(request, location, status = 302) {
161
+ const { setCookie } = await this.signOut(request);
162
+ return redirectWithCookie(location, setCookie, status);
163
+ }
164
+ }
118
165
  function createCookieSessionAuthManager(options = {}) {
119
- const store = options.store ?? new CookieSessionStore(options.sql ?? defaultSessionSql, options.secret ?? process.env.SESSION_SECRET?.trim() ?? "", options.cookieName, options.maxAgeSeconds);
120
- return new AuthManager(new CookieSessionGuard(store, options.mapUser ?? defaultMapSessionUser));
166
+ const store = options.store ?? new CookieSessionStore(options.sql ?? defaultSessionSql, options.secret ?? process.env.SESSION_SECRET?.trim() ?? "", options.cookieName, options.maxAgeSeconds, options.loadSessionUser);
167
+ return new CookieSessionAuthManager(store, options.mapUser ?? defaultMapSessionUser);
121
168
  }
122
169
  export {
170
+ CookieSessionAuthManager,
123
171
  CookieSessionGuard,
124
172
  CookieSessionStore,
125
173
  createCookieSessionAuthManager,
package/dist/index.js CHANGED
@@ -1280,17 +1280,45 @@ function defaultMapSessionUser(user) {
1280
1280
  role: user.is_admin ? "admin" : "member"
1281
1281
  };
1282
1282
  }
1283
+ async function defaultLoadSessionUser(sql, sessionId) {
1284
+ const rows = await sql.unsafe(`SELECT s.id, s.user_id, s.expires_at, u.name, u.email, u.learn_subscriber,
1285
+ COALESCE(u.is_admin, false) AS is_admin
1286
+ FROM sessions s
1287
+ INNER JOIN users u ON u.id = s.user_id
1288
+ WHERE s.id = $1 AND s.expires_at > NOW()`, [sessionId]);
1289
+ const row = rows[0];
1290
+ if (!row)
1291
+ return null;
1292
+ return {
1293
+ id: row.user_id,
1294
+ name: row.name,
1295
+ email: row.email,
1296
+ learn_subscriber: row.learn_subscriber,
1297
+ is_admin: row.is_admin
1298
+ };
1299
+ }
1300
+ function redirectWithCookie(location, setCookie, status) {
1301
+ return new Response(null, {
1302
+ status,
1303
+ headers: {
1304
+ Location: location,
1305
+ "Set-Cookie": setCookie
1306
+ }
1307
+ });
1308
+ }
1283
1309
 
1284
1310
  class CookieSessionStore {
1285
1311
  sqlSource;
1286
1312
  secret;
1287
1313
  cookieName;
1288
1314
  maxAgeSeconds;
1289
- constructor(sqlSource, secret, cookieName = "strata_session", maxAgeSeconds = 60 * 60 * 24 * 14) {
1315
+ loadSessionUser;
1316
+ constructor(sqlSource, secret, cookieName = "strata_session", maxAgeSeconds = 60 * 60 * 24 * 14, loadSessionUser = defaultLoadSessionUser) {
1290
1317
  this.sqlSource = sqlSource;
1291
1318
  this.secret = secret;
1292
1319
  this.cookieName = cookieName;
1293
1320
  this.maxAgeSeconds = maxAgeSeconds;
1321
+ this.loadSessionUser = loadSessionUser;
1294
1322
  }
1295
1323
  cookieHeader(_user, sessionId) {
1296
1324
  const payload = `${sessionId}.${this.sign(sessionId)}`;
@@ -1299,6 +1327,17 @@ class CookieSessionStore {
1299
1327
  clearCookieHeader() {
1300
1328
  return this.withSecureFlag(`${this.cookieName}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`);
1301
1329
  }
1330
+ sessionIdFromRequest(request) {
1331
+ const cookie = readRequestCookie(request, this.cookieName);
1332
+ const raw = cookie ?? null;
1333
+ if (!raw)
1334
+ return null;
1335
+ const [sessionId, signature] = raw.split(".");
1336
+ if (!sessionId || !signature || signature !== this.sign(sessionId)) {
1337
+ return null;
1338
+ }
1339
+ return sessionId;
1340
+ }
1302
1341
  withSecureFlag(header) {
1303
1342
  if (true) {
1304
1343
  return header;
@@ -1322,29 +1361,10 @@ class CookieSessionStore {
1322
1361
  await this.sql().unsafe(`DELETE FROM sessions WHERE id = $1`, [sessionId]);
1323
1362
  }
1324
1363
  async read(request) {
1325
- const cookie = readRequestCookie(request, this.cookieName);
1326
- const raw = cookie ?? null;
1327
- if (!raw)
1364
+ const sessionId = this.sessionIdFromRequest(request);
1365
+ if (!sessionId)
1328
1366
  return null;
1329
- const [sessionId, signature] = raw.split(".");
1330
- if (!sessionId || !signature || signature !== this.sign(sessionId)) {
1331
- return null;
1332
- }
1333
- const rows = await this.sql().unsafe(`SELECT s.id, s.user_id, s.expires_at, u.name, u.email, u.learn_subscriber,
1334
- COALESCE(u.is_admin, false) AS is_admin
1335
- FROM sessions s
1336
- INNER JOIN users u ON u.id = s.user_id
1337
- WHERE s.id = $1 AND s.expires_at > NOW()`, [sessionId]);
1338
- const row = rows[0];
1339
- if (!row)
1340
- return null;
1341
- return {
1342
- id: row.user_id,
1343
- name: row.name,
1344
- email: row.email,
1345
- learn_subscriber: row.learn_subscriber,
1346
- is_admin: row.is_admin
1347
- };
1367
+ return this.loadSessionUser(this.sql(), sessionId);
1348
1368
  }
1349
1369
  sign(value) {
1350
1370
  return createHash("sha256").update(`${value}.${this.secret}`).digest("hex").slice(0, 32);
@@ -1366,9 +1386,36 @@ class CookieSessionGuard {
1366
1386
  return this.mapUser(user);
1367
1387
  }
1368
1388
  }
1389
+
1390
+ class CookieSessionAuthManager extends AuthManager2 {
1391
+ store;
1392
+ constructor(store, mapUser = defaultMapSessionUser) {
1393
+ super(new CookieSessionGuard(store, mapUser));
1394
+ this.store = store;
1395
+ }
1396
+ async signIn(user) {
1397
+ const sessionId = await this.store.create(user);
1398
+ return { sessionId, setCookie: this.store.cookieHeader(user, sessionId) };
1399
+ }
1400
+ async signOut(request) {
1401
+ const sessionId = this.store.sessionIdFromRequest(request);
1402
+ if (sessionId) {
1403
+ await this.store.destroy(sessionId);
1404
+ }
1405
+ return { setCookie: this.store.clearCookieHeader() };
1406
+ }
1407
+ async signInRedirect(user, location, status = 302) {
1408
+ const { setCookie } = await this.signIn(user);
1409
+ return redirectWithCookie(location, setCookie, status);
1410
+ }
1411
+ async signOutRedirect(request, location, status = 302) {
1412
+ const { setCookie } = await this.signOut(request);
1413
+ return redirectWithCookie(location, setCookie, status);
1414
+ }
1415
+ }
1369
1416
  function createCookieSessionAuthManager(options = {}) {
1370
- const store = options.store ?? new CookieSessionStore(options.sql ?? defaultSessionSql, options.secret ?? process.env.SESSION_SECRET?.trim() ?? "", options.cookieName, options.maxAgeSeconds);
1371
- return new AuthManager2(new CookieSessionGuard(store, options.mapUser ?? defaultMapSessionUser));
1417
+ const store = options.store ?? new CookieSessionStore(options.sql ?? defaultSessionSql, options.secret ?? process.env.SESSION_SECRET?.trim() ?? "", options.cookieName, options.maxAgeSeconds, options.loadSessionUser);
1418
+ return new CookieSessionAuthManager(store, options.mapUser ?? defaultMapSessionUser);
1372
1419
  }
1373
1420
  // ../../src/bootstrap/web/slug.ts
1374
1421
  function slugify(value) {
@@ -1385,6 +1432,7 @@ export {
1385
1432
  CORE_POLICY_GATE_TOKEN,
1386
1433
  CORE_QUEUE_TOKEN,
1387
1434
  CORE_TOKEN_SERVICE_TOKEN,
1435
+ CookieSessionAuthManager,
1388
1436
  CookieSessionGuard,
1389
1437
  CookieSessionStore,
1390
1438
  DATABASE_URL_CONFIG_KEY,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getstrata/bootstrap",
3
- "version": "0.2.50",
3
+ "version": "0.2.51",
4
4
  "description": "Strata application bootstrap — HttpKernel, DI, web session helpers",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -173,14 +173,14 @@
173
173
  "build:bundle": "bun build index.ts --outdir dist --target bun --external bun --external eta --external @getstrata/core",
174
174
  "build:types": "tsc -p tsconfig.types.json && bun ../../scripts/prune-bootstrap-dist-types.ts",
175
175
  "prepublishOnly": "bun run build",
176
- "build:subpaths": "bun build entries/applicationRegistry.ts entries/buildModuleRoutes.ts entries/buildWebModuleRoutes.ts entries/cache/modelCacheTags.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/createRoutes.ts entries/createSpaRoutes.ts entries/dependencies.ts entries/discoverModules.ts entries/health.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/listeners/invalidateCacheOnModelWrite.ts entries/membershipService.ts entries/metricsRoutes.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts entries/routeRegistry.ts entries/schedule.ts entries/secretsGuard.ts entries/web/forms.ts entries/web/routing.ts entries/web/server.ts entries/web/session.ts entries/web/slug.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core --external @getstrata/bootstrap --external @getstrata/bootstrap/applicationRegistry --external @getstrata/bootstrap/buildModuleRoutes --external @getstrata/bootstrap/buildWebModuleRoutes --external @getstrata/bootstrap/cache/modelCacheTags --external @getstrata/bootstrap/config --external @getstrata/bootstrap/context --external @getstrata/bootstrap/contracts --external @getstrata/bootstrap/createWebRoutes --external @getstrata/bootstrap/createRoutes --external @getstrata/bootstrap/createSpaRoutes --external @getstrata/bootstrap/dependencies --external @getstrata/bootstrap/discoverModules --external @getstrata/bootstrap/health --external @getstrata/bootstrap/http/securedRouteModelBinding --external @getstrata/bootstrap/httpKernel --external @getstrata/bootstrap/listeners/invalidateCacheOnModelWrite --external @getstrata/bootstrap/membershipService --external @getstrata/bootstrap/metricsRoutes --external @getstrata/bootstrap/queue/defaultJobs --external @getstrata/bootstrap/providers --external @getstrata/bootstrap/providers/view --external @getstrata/bootstrap/routeRegistry --external @getstrata/bootstrap/schedule --external @getstrata/bootstrap/secretsGuard --external @getstrata/bootstrap/web/forms --external @getstrata/bootstrap/web/routing --external @getstrata/bootstrap/web/server --external @getstrata/bootstrap/web/session --external @getstrata/bootstrap/web/slug --external @getstrata/core/auth/accessControl --external @getstrata/core/auth/abilityChecker --external @getstrata/core/auth/authContext --external @getstrata/core/auth/guard --external @getstrata/core/auth/membershipContext --external @getstrata/core/auth/membershipMiddleware --external @getstrata/core/auth/membershipScope --external @getstrata/core/auth/membershipService --external @getstrata/core/auth/oauth/oidcProvider --external @getstrata/core/auth/oauth/providers --external @getstrata/core/auth/oauth/samlProvider --external @getstrata/core/auth/oauth/types --external @getstrata/core/auth/password --external @getstrata/core/auth/policy --external @getstrata/core/auth/scimAuthMiddleware --external @getstrata/core/auth/sessionCookie --external @getstrata/core/auth/sessionGuard --external @getstrata/core/auth/tokenHash --external @getstrata/core/audit/exportAuditLogs --external @getstrata/core/audit/siemFormatter --external @getstrata/core/admin/formatValue --external @getstrata/core/admin/registry --external @getstrata/core/admin/types --external @getstrata/core/cache/tags --external @getstrata/core/cache/createCacheStore --external @getstrata/core/cache/repository --external @getstrata/core/cache/simpleCache --external @getstrata/core/cache/simpleCacheStore --external @getstrata/core/config/envSchema --external @getstrata/core/contracts/serviceTokens --external @getstrata/core/contracts/container --external @getstrata/core/contracts/di --external @getstrata/core/crypto/fieldEncryption --external @getstrata/core/crypto/mfaSecret --external @getstrata/core/database --external @getstrata/core/database/baseRepository --external @getstrata/core/database/bindConnection --external @getstrata/core/database/boundConnection --external @getstrata/core/database/connection --external @getstrata/core/database/defaultConnection --external @getstrata/core/database/errors --external @getstrata/core/database/factory --external @getstrata/core/database/migrations --external @getstrata/core/database/migrations/types --external @getstrata/core/database/model --external @getstrata/core/database/query --external @getstrata/core/database/relationships --external @getstrata/core/database/repositoryConnection --external @getstrata/core/database/repositoryQuery --external @getstrata/core/database/seeders --external @getstrata/core/database/seeders/types --external @getstrata/core/database/schema --external @getstrata/core/database/table --external @getstrata/core/database/transaction --external @getstrata/core/database/types --external @getstrata/core/database/whereBuilder --external @getstrata/core/errors/http --external @getstrata/core/events --external @getstrata/core/facades --external @getstrata/core/http --external @getstrata/core/http/authMiddleware --external @getstrata/core/http/authorizeMiddleware --external @getstrata/core/http/bodySizeLimitMiddleware --external @getstrata/core/http/clientIp --external @getstrata/core/http/cookies --external @getstrata/core/http/contentNegotiation --external @getstrata/core/http/conditionalResponse --external @getstrata/core/http/corsMiddleware --external @getstrata/core/http/csrfMiddleware --external @getstrata/core/http/csrfProtection --external @getstrata/core/http/csrfToken --external @getstrata/core/http/etag --external @getstrata/core/http/flashSession --external @getstrata/core/http/flashMiddleware --external @getstrata/core/http/formRequest --external @getstrata/core/http/middleware --external @getstrata/core/http/metricsMiddleware --external @getstrata/core/http/loginThrottleMiddleware --external @getstrata/core/http/memoryThrottleMiddleware --external @getstrata/core/http/pagination --external @getstrata/core/http/parseFormBody --external @getstrata/core/http/parseMultipartUpload --external @getstrata/core/http/requireAbilityMiddleware --external @getstrata/core/http/requireAuthMiddleware --external @getstrata/core/http/requireGlobalAdminMiddleware --external @getstrata/core/http/requireWebAuthMiddleware --external @getstrata/core/http/resources --external @getstrata/core/http/response --external @getstrata/core/http/route --external @getstrata/core/http/routeMiddleware --external @getstrata/core/http/routeModelBinding --external @getstrata/core/http/scimThrottleMiddleware --external @getstrata/core/http/securityHeadersMiddleware --external @getstrata/core/http/securedRouteModelBinding --external @getstrata/core/http/requestMetaContext --external @getstrata/core/http/webErrorResponse --external @getstrata/core/http/webFormRequest --external @getstrata/core/http/throttleMiddleware --external @getstrata/core/http/validation --external @getstrata/core/jobs/dispatchWebhookJob --external @getstrata/core/jobs/invalidateCacheTagsJob --external @getstrata/core/lifecycle/gracefulShutdown --external @getstrata/core/logging/logger --external @getstrata/core/logging/requestLoggingMiddleware --external @getstrata/core/mail/mailer --external @getstrata/core/mail/markdownMail --external @getstrata/core/mail/markdownMailable --external @getstrata/core/media/imageTransform --external @getstrata/core/metrics/prometheus --external @getstrata/core/notifications --external @getstrata/core/openapi/generator --external @getstrata/core/openapi/registeredRoute --external @getstrata/core/openapi/validate --external @getstrata/core/pagination --external @getstrata/core/queue --external @getstrata/core/queue/createAppQueue --external @getstrata/core/queue/failedJobRepository --external @getstrata/core/queue/failedJobService --external @getstrata/core/queue/jobRegistry --external @getstrata/core/queue/jobRunner --external @getstrata/core/queue/queueMetrics --external @getstrata/core/queue/publicQueue --external @getstrata/core/queue/redisQueue --external @getstrata/core/queue/types --external @getstrata/core/runtime/applicationRegistry --external @getstrata/core/runtime/asyncContextStore --external @getstrata/core/scheduler/schedule --external @getstrata/core/scheduler/osCron --external @getstrata/core/security/oauthState --external @getstrata/core/security/publicReads --external @getstrata/core/security/safeFetch --external @getstrata/core/security/safeUrl --external @getstrata/core/security/scimTenantTokens --external @getstrata/core/security/securityEvents --external @getstrata/core/security/stripeWebhook --external @getstrata/core/security/timingSafeCompare --external @getstrata/core/security/tokenExpiry --external @getstrata/core/security/totp --external @getstrata/core/storage/storage --external @getstrata/core/tenant/tenancyConfig --external @getstrata/core/tenant/tenantContext --external @getstrata/core/tenant/tenantDatabaseScope --external @getstrata/core/tenant/databaseTenantContext --external @getstrata/core/tenant/tenantMiddleware --external @getstrata/core/terminal/runShell --external @getstrata/core/tracing/traceContext --external @getstrata/core/tracing/tracingMiddleware --external @getstrata/core/validation/rules --external @getstrata/core/view",
176
+ "build:subpaths": "bun build entries/applicationRegistry.ts entries/buildModuleRoutes.ts entries/buildWebModuleRoutes.ts entries/cache/modelCacheTags.ts entries/config.ts entries/context.ts entries/contracts.ts entries/createWebRoutes.ts entries/createRoutes.ts entries/createSpaRoutes.ts entries/dependencies.ts entries/discoverModules.ts entries/health.ts entries/http/securedRouteModelBinding.ts entries/httpKernel.ts entries/listeners/invalidateCacheOnModelWrite.ts entries/membershipService.ts entries/metricsRoutes.ts entries/queue/defaultJobs.ts entries/providers.ts entries/providers/view.ts entries/routeRegistry.ts entries/schedule.ts entries/secretsGuard.ts entries/web/forms.ts entries/web/routing.ts entries/web/server.ts entries/web/session.ts entries/web/slug.ts --outdir dist --root . --target bun --external bun --external eta --external @getstrata/core --external @getstrata/bootstrap --external @getstrata/bootstrap/applicationRegistry --external @getstrata/bootstrap/buildModuleRoutes --external @getstrata/bootstrap/buildWebModuleRoutes --external @getstrata/bootstrap/cache/modelCacheTags --external @getstrata/bootstrap/config --external @getstrata/bootstrap/context --external @getstrata/bootstrap/contracts --external @getstrata/bootstrap/createWebRoutes --external @getstrata/bootstrap/createRoutes --external @getstrata/bootstrap/createSpaRoutes --external @getstrata/bootstrap/dependencies --external @getstrata/bootstrap/discoverModules --external @getstrata/bootstrap/health --external @getstrata/bootstrap/http/securedRouteModelBinding --external @getstrata/bootstrap/httpKernel --external @getstrata/bootstrap/listeners/invalidateCacheOnModelWrite --external @getstrata/bootstrap/membershipService --external @getstrata/bootstrap/metricsRoutes --external @getstrata/bootstrap/queue/defaultJobs --external @getstrata/bootstrap/providers --external @getstrata/bootstrap/providers/view --external @getstrata/bootstrap/routeRegistry --external @getstrata/bootstrap/schedule --external @getstrata/bootstrap/secretsGuard --external @getstrata/bootstrap/web/forms --external @getstrata/bootstrap/web/routing --external @getstrata/bootstrap/web/server --external @getstrata/bootstrap/web/session --external @getstrata/bootstrap/web/slug --external @getstrata/core/auth/accessControl --external @getstrata/core/auth/abilityChecker --external @getstrata/core/auth/authContext --external @getstrata/core/auth/guard --external @getstrata/core/auth/membershipContext --external @getstrata/core/auth/membershipMiddleware --external @getstrata/core/auth/membershipScope --external @getstrata/core/auth/membershipService --external @getstrata/core/auth/oauth/oidcProvider --external @getstrata/core/auth/oauth/providers --external @getstrata/core/auth/oauth/samlProvider --external @getstrata/core/auth/oauth/types --external @getstrata/core/auth/password --external @getstrata/core/auth/policy --external @getstrata/core/auth/scimAuthMiddleware --external @getstrata/core/auth/sessionCookie --external @getstrata/core/auth/sessionGuard --external @getstrata/core/auth/tokenHash --external @getstrata/core/audit/exportAuditLogs --external @getstrata/core/audit/siemFormatter --external @getstrata/core/admin/formatValue --external @getstrata/core/admin/registry --external @getstrata/core/admin/types --external @getstrata/core/cache/tags --external @getstrata/core/cache/createCacheStore --external @getstrata/core/cache/repository --external @getstrata/core/cache/simpleCache --external @getstrata/core/cache/simpleCacheStore --external @getstrata/core/config/envSchema --external @getstrata/core/contracts/serviceTokens --external @getstrata/core/contracts/container --external @getstrata/core/contracts/di --external @getstrata/core/crypto/fieldEncryption --external @getstrata/core/crypto/mfaSecret --external @getstrata/core/database --external @getstrata/core/database/baseRepository --external @getstrata/core/database/bindConnection --external @getstrata/core/database/boundConnection --external @getstrata/core/database/bunSql --external @getstrata/core/database/connection --external @getstrata/core/database/defaultConnection --external @getstrata/core/database/errors --external @getstrata/core/database/factory --external @getstrata/core/database/migrations --external @getstrata/core/database/migrations/types --external @getstrata/core/database/model --external @getstrata/core/database/query --external @getstrata/core/database/relationships --external @getstrata/core/database/repositoryConnection --external @getstrata/core/database/repositoryQuery --external @getstrata/core/database/seeders --external @getstrata/core/database/seeders/types --external @getstrata/core/database/schema --external @getstrata/core/database/table --external @getstrata/core/database/transaction --external @getstrata/core/database/types --external @getstrata/core/database/whereBuilder --external @getstrata/core/errors/http --external @getstrata/core/events --external @getstrata/core/facades --external @getstrata/core/http --external @getstrata/core/http/authMiddleware --external @getstrata/core/http/authorizeMiddleware --external @getstrata/core/http/bodySizeLimitMiddleware --external @getstrata/core/http/clientIp --external @getstrata/core/http/cookies --external @getstrata/core/http/contentNegotiation --external @getstrata/core/http/conditionalResponse --external @getstrata/core/http/corsMiddleware --external @getstrata/core/http/csrfMiddleware --external @getstrata/core/http/csrfProtection --external @getstrata/core/http/csrfToken --external @getstrata/core/http/etag --external @getstrata/core/http/flashSession --external @getstrata/core/http/flashMiddleware --external @getstrata/core/http/formRequest --external @getstrata/core/http/middleware --external @getstrata/core/http/metricsMiddleware --external @getstrata/core/http/loginThrottleMiddleware --external @getstrata/core/http/memoryThrottleMiddleware --external @getstrata/core/http/pagination --external @getstrata/core/http/parseFormBody --external @getstrata/core/http/parseMultipartUpload --external @getstrata/core/http/requireAbilityMiddleware --external @getstrata/core/http/requireAuthMiddleware --external @getstrata/core/http/requireGlobalAdminMiddleware --external @getstrata/core/http/requireWebAuthMiddleware --external @getstrata/core/http/resources --external @getstrata/core/http/response --external @getstrata/core/http/route --external @getstrata/core/http/routeMiddleware --external @getstrata/core/http/routeModelBinding --external @getstrata/core/http/scimThrottleMiddleware --external @getstrata/core/http/securityHeadersMiddleware --external @getstrata/core/http/securedRouteModelBinding --external @getstrata/core/http/requestMetaContext --external @getstrata/core/http/webErrorResponse --external @getstrata/core/http/webFormRequest --external @getstrata/core/http/throttleMiddleware --external @getstrata/core/http/validation --external @getstrata/core/jobs/dispatchWebhookJob --external @getstrata/core/jobs/invalidateCacheTagsJob --external @getstrata/core/lifecycle/gracefulShutdown --external @getstrata/core/logging/logger --external @getstrata/core/logging/requestLoggingMiddleware --external @getstrata/core/mail/mailer --external @getstrata/core/mail/markdownMail --external @getstrata/core/mail/markdownMailable --external @getstrata/core/media/imageTransform --external @getstrata/core/metrics/prometheus --external @getstrata/core/notifications --external @getstrata/core/openapi/generator --external @getstrata/core/openapi/registeredRoute --external @getstrata/core/openapi/validate --external @getstrata/core/pagination --external @getstrata/core/queue --external @getstrata/core/queue/createAppQueue --external @getstrata/core/queue/failedJobRepository --external @getstrata/core/queue/failedJobService --external @getstrata/core/queue/jobRegistry --external @getstrata/core/queue/jobRunner --external @getstrata/core/queue/queueMetrics --external @getstrata/core/queue/publicQueue --external @getstrata/core/queue/redisQueue --external @getstrata/core/queue/types --external @getstrata/core/runtime/applicationRegistry --external @getstrata/core/runtime/asyncContextStore --external @getstrata/core/scheduler/schedule --external @getstrata/core/scheduler/osCron --external @getstrata/core/security/oauthState --external @getstrata/core/security/publicReads --external @getstrata/core/security/safeFetch --external @getstrata/core/security/safeUrl --external @getstrata/core/security/scimTenantTokens --external @getstrata/core/security/securityEvents --external @getstrata/core/security/stripeWebhook --external @getstrata/core/security/timingSafeCompare --external @getstrata/core/security/tokenExpiry --external @getstrata/core/security/totp --external @getstrata/core/storage/storage --external @getstrata/core/tenant/tenancyConfig --external @getstrata/core/tenant/tenantContext --external @getstrata/core/tenant/tenantDatabaseScope --external @getstrata/core/tenant/databaseTenantContext --external @getstrata/core/tenant/tenantMiddleware --external @getstrata/core/terminal/runShell --external @getstrata/core/tracing/traceContext --external @getstrata/core/tracing/tracingMiddleware --external @getstrata/core/validation/rules --external @getstrata/core/view",
177
177
  "build:shims": "true"
178
178
  },
179
179
  "publishConfig": {
180
180
  "access": "public"
181
181
  },
182
182
  "peerDependencies": {
183
- "@getstrata/core": "^0.5.59",
183
+ "@getstrata/core": "^0.5.60",
184
184
  "typescript": "^5.9.0"
185
185
  }
186
186
  }