@getstrata/bootstrap 0.2.66 → 0.4.2

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,18 +1,53 @@
1
1
  # @getstrata/bootstrap changelog
2
2
 
3
+ ## 0.4.2
4
+
5
+ - `HttpKernel.wrapApi` uses `withJsonErrorHandling`. Hybrid views do not turn API errors into HTML.
6
+
7
+ ## 0.4.1
8
+
9
+ - `createSpaRoutes` reads `SPA_PREFIX`, registers `prefix`, `prefix/`, and `prefix/*`, and accepts `distDirectory` plus `wrap`. Hybrid still does not redirect `/`.
10
+ - `appEnvSchema` defaults `SPA_PREFIX` from core `DEFAULT_SPA_PREFIX`.
11
+ - Peer `@getstrata/core` `^0.7.1`.
12
+
13
+ ## 0.4.0
14
+
15
+ - Peer `@getstrata/core` `^0.7.0`.
16
+ - Production `SESSION_SECRET` is required whenever views are on (`FRONTEND_MODE=server-htmx` or `hybrid`).
17
+ - Hybrid SPA routes stay under `/app/*`. They do not redirect `/`, so staff HTML keeps the home path.
18
+ - `appEnvSchema` validates `FRONTEND_MODE` with the core pattern, including `hybrid`.
19
+ - `HttpKernel.wrapApi` maps thrown HTTP errors to JSON the same way `wrapWeb` maps them to HTML.
20
+
21
+ ## 0.3.0
22
+
23
+ - Peer `@getstrata/core` `^0.6.0`.
24
+ - Cookie session SQL uses the current SQL dialect for placeholders, `NOW()`, and `NULLS LAST`.
25
+ - Kernel comments describe guest, verified-email, and password-confirm gates without referring to another framework.
26
+
27
+ ## 0.2.68
28
+
29
+ - `configureModulesDirectory()` clears the discovered-module cache when the directory changes, so OpenAPI/`createApp` can load HiroApp after core tests pointed at empty fixtures.
30
+ - `createWebRoutes()` / `mergeWebRoutes()` accept optional `{ modules }` so leftover bootstrap route assembly does not pick up the dogfood app's modules. `CreateWebRoutesOptions` is exported from the public API.
31
+
32
+ ## 0.2.67
33
+
34
+ - `CookieSessionStore.create()` records optional browser metadata (`userAgent`, `ipAddress`, `last_active_at`).
35
+ - `CookieSessionStore` can list live sessions, touch `last_active_at`, and destroy every session except the current cookie (`listForUser`, `touch`, `destroyOtherSessions`).
36
+ - `CookieSessionAuthManager.signIn()` / `signInRedirect()` accept the same metadata. Apps that use cookie sessions (HiroApp) must have `user_agent`, `ip_address`, and `last_active_at` on `sessions`.
37
+
3
38
  ## 0.2.66
4
39
 
5
- - `assertProductionSecrets()` is feature-gated for every app. API tokens no longer imply WorkHub’s encryption/CORS/OAuth/public-read checklist. Published test token strings are still denied. WorkHub’s extra production profile lives in the app (`src/config/productionSecrets.ts`).
6
- - **Breaking:** `HttpKernel.wrapWebGuest()` defaults `home` to `/` instead of `/organizations`. Apps with an org home should pass that path (WorkHub already does).
40
+ - `assertProductionSecrets()` is feature-gated for every app. API tokens no longer imply the previous in-repo app's encryption/CORS/OAuth/public-read checklist. Published test token strings are still denied. the previous in-repo app's extra production profile lives in the app (`src/config/productionSecrets.ts`).
41
+ - **Breaking:** `HttpKernel.wrapWebGuest()` defaults `home` to `/` instead of `/organizations`. Apps with an org home should pass that path (the previous in-repo app already does).
7
42
  - `createWebRoutes()` no longer seeds a `/` → `/organizations` redirect. The in-repo app owns `/` via its organization module.
8
43
 
9
44
  ## 0.2.65
10
45
 
11
- - App listener discovery reads `src/listeners` from `process.cwd()` so a built `@getstrata/bootstrap` bundle still finds WorkHub registrars (`import.meta.dir` after `build:bootstrap` is the package dist). Listener boot calls each registrar every time (registrars are idempotent per `eventBus`).
46
+ - App listener discovery reads `src/listeners` from `process.cwd()` so a built `@getstrata/bootstrap` bundle still finds the previous in-repo app registrars (`import.meta.dir` after `build:bootstrap` is the package dist). Listener boot calls each registrar every time (registrars are idempotent per `eventBus`).
12
47
 
13
48
  ## 0.2.64
14
49
 
15
- - `registerDefaultJobs()` no longer registers WorkHub `webhook.dispatch`. Apps that dispatch model webhooks should call `registerWebhookJobs()` (WorkHub’s webhook provider and `queue:work` do).
50
+ - `registerDefaultJobs()` no longer registers the previous in-repo app `webhook.dispatch`. Apps that dispatch model webhooks should call `registerWebhookJobs()` (the previous in-repo app's webhook provider and `queue:work` do).
16
51
 
17
52
  ## 0.2.63
18
53
 
@@ -20,7 +55,7 @@
20
55
 
21
56
  ## 0.2.62
22
57
 
23
- - `HttpKernel.wrapWebPasswordConfirm()` is Laravel `password.confirm` for HTML routes. Peer `@getstrata/core` `^0.5.75`.
58
+ - `HttpKernel.wrapWebPasswordConfirm()` is the previous PHP framework `password.confirm` for HTML routes. Peer `@getstrata/core` `^0.5.75`.
24
59
 
25
60
  ## 0.2.61
26
61
 
@@ -32,7 +67,7 @@
32
67
 
33
68
  ## 0.2.59
34
69
 
35
- - `HttpKernel.wrapWebGuest()` is Laravel `guest` / `RedirectIfAuthenticated`. Signed-in HTML users redirect to `/organizations` (override the home path). Peer `@getstrata/core` `^0.5.72`.
70
+ - `HttpKernel.wrapWebGuest()` is the previous PHP framework `guest` / `RedirectIfAuthenticated`. Signed-in HTML users redirect to `/organizations` (override the home path). Peer `@getstrata/core` `^0.5.72`.
36
71
 
37
72
  ## 0.2.58
38
73
 
@@ -48,7 +83,7 @@
48
83
 
49
84
  ## 0.2.55
50
85
 
51
- - HttpKernel and route builders read `isViewsEnabled` / `isSpaEnabled` from `@getstrata/core/runtime/frontendMode` instead of WorkHub `src/config/frontend`.
86
+ - HttpKernel and route builders read `isViewsEnabled` / `isSpaEnabled` from `@getstrata/core/runtime/frontendMode` instead of the previous in-repo app `src/config/frontend`.
52
87
 
53
88
  ## 0.2.54
54
89
 
@@ -72,7 +107,7 @@
72
107
 
73
108
  ## 0.2.50
74
109
 
75
- - `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.
76
- - `checkDatabase()` / `createHealthRoutes()` ping the bound database client, not WorkHub’s private connection holder. `/health` stays `{ status: "ok" }` unless `{ pingOnHealth: true }`. Extra JSON fields are optional.
77
- - `assertProductionSecrets()` is feature-gated. A production HTMX app with `SESSION_SECRET` (32+), `AUTH_DEV_HEADERS=false`, and feature flags off does not need WorkHub API tokens. WorkHub’s current production env (rotated tokens, CORS, pepper, expiry) still passes.
110
+ - `createCookieSessionAuthManager` / `CookieSessionGuard` turn `CookieSessionStore` into an `AuthGuard` / `AuthManager` for `CORE_AUTH_TOKEN`. Supply a `mapUser` mapper; the previous in-repo app abilities are not baked in. Omit `sql` to read the client from `bindDatabaseConnection()` on every call.
111
+ - `checkDatabase()` / `createHealthRoutes()` ping the bound database client, not the previous in-repo app's private connection holder. `/health` stays `{ status: "ok" }` unless `{ pingOnHealth: true }`. Extra JSON fields are optional.
112
+ - `assertProductionSecrets()` is feature-gated. A production HTMX app with `SESSION_SECRET` (32+), `AUTH_DEV_HEADERS=false`, and feature flags off does not need the previous in-repo app API tokens. the previous in-repo app's current production env (rotated tokens, CORS, pepper, expiry) still passes.
78
113
  - Re-exports `CORE_ABILITY_CHECKER_TOKEN` and `CORE_AUTH_USER_DIRECTORY_TOKEN`.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @getstrata/bootstrap
2
2
 
3
- Application bootstrap for Strata sibling apps: HttpKernel, service container, and web utilities.
3
+ Application bootstrap for Strata apps: HttpKernel, service container, and web utilities.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,7 +8,7 @@ Application bootstrap for Strata sibling apps: HttpKernel, service container, an
8
8
  bun add @getstrata/bootstrap @getstrata/core
9
9
  ```
10
10
 
11
- ## Web utilities (getstrata-style apps)
11
+ ## Web utilities
12
12
 
13
13
  ```typescript
14
14
  import {
@@ -20,22 +20,22 @@ import {
20
20
  } from "@getstrata/bootstrap";
21
21
  ```
22
22
 
23
- `CookieSessionStore` reads optional `is_admin` from the user row for global admin routing via `wrapWebGlobalAdmin`.
23
+ `CookieSessionStore` can read `is_admin` from the user row for `wrapWebGlobalAdmin`. Pass `loadSessionUser` when your `users` table does not match the default `SELECT u.*`.
24
24
 
25
- ## HttpKernel (API / module apps)
25
+ ## HttpKernel
26
26
 
27
27
  ```typescript
28
28
  import { createHttpKernel, createAppContext, coreProviders } from "@getstrata/bootstrap";
29
29
  ```
30
30
 
31
- `createAppContext()` does not call `assertProductionSecrets`. That helper is feature-gated for every app (tokens, CORS, OAuth, encryption only when those features are on). WorkHub also runs its own production extras from `App.serve()` / `queue:work`. Sibling HTMX apps can call the published helper without API tokens when feature flags are off see [SIBLING-HTMX.md](../../docs/SIBLING-HTMX.md).
31
+ `createAppContext()` does not call `assertProductionSecrets`. That helper is feature-gated (tokens, CORS, OAuth, encryption only when those features are on). HTML apps can call it without API tokens when those flags are off. See [docs/BUILDING-APPS.md](../../docs/BUILDING-APPS.md) and [docs/PRODUCTION.md](../../docs/PRODUCTION.md).
32
32
 
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.
33
+ HTML apps should bind `createCookieSessionAuthManager` from `@getstrata/bootstrap/web/session` instead of HMAC `SessionGuard`. Use `signIn` / `signOut` (or the redirect helpers). Pass `mapUser` to map roles in the app.
34
34
 
35
- `wrapWeb` applies the web group (CSRF + flash) and `withErrorHandling`, so CSRF `ForbiddenError` becomes an HTML 403 in `FRONTEND_MODE=server-htmx`. `wrapWebGuest` is Laravel `guest` / `RedirectIfAuthenticated` (signed-in users go to `/` by default; pass a string or `(user) => path` to override). `wrapWebLogin` / `wrapWebRegister` include that web group plus throttle do not wrap them with `wrapWeb` again. The throttle callback should return an HTML form at 429.
35
+ `wrapWeb` applies the web group (CSRF + flash) and `withErrorHandling`, so CSRF `ForbiddenError` becomes an HTML 403 when views are on (`FRONTEND_MODE=server-htmx` or `hybrid`). `wrapWebGuest` sends signed-in users to `/` by default (pass a string or `(user) => path` to override). `wrapWebLogin` / `wrapWebRegister` include that web group plus throttle. Do not wrap them with `wrapWeb` again. The throttle callback should return an HTML form at 429.
36
36
 
37
- `registerDefaultJobs()` registers `cache.invalidate-tags` and `audit.export` only. Apps that dispatch model webhooks should call `registerWebhookJobs()` themselves.
37
+ `createSpaRoutes` / `mergeSpaRoutes` serve `SPA_PREFIX` (default `/app`) as `prefix`, `prefix/`, and `prefix/*`. Hybrid does not redirect `/`. Pass `distDirectory` and `wrap` when the app is not the process cwd. Apps should not copy a second static-file server.
38
38
 
39
- These subpaths assemble the in-repo dogfood app and are not a generic starter API: `@getstrata/bootstrap/createRoutes` (includes SCIM), `@getstrata/bootstrap/schedule`, and `@getstrata/bootstrap/createWebRoutes` (discovers app `webRoutes`; `/` is owned by the app). Sibling apps should use `buildWebModuleRoutes` / `buildModuleRoutes`.
39
+ `registerDefaultJobs()` registers `cache.invalidate-tags` and `audit.export` only. Apps that dispatch model webhooks should call `registerWebhookJobs()` themselves.
40
40
 
41
- See the [strata](https://github.com/EyK-26/strata) monorepo reference app for full module patterns.
41
+ These subpaths assemble leftover fixture HTTP for framework tests and are not a generic starter API: `@getstrata/bootstrap/createRoutes`, `@getstrata/bootstrap/schedule`, `@getstrata/bootstrap/createWebRoutes`. New apps should use `buildWebModuleRoutes` / `buildModuleRoutes`. HiroApp uses `createApp()` in `apps/hiroapp`.
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>WorkHub API</title>
6
+ <title>Strata</title>
7
7
  <style>
8
8
  :root {
9
9
  color-scheme: dark;
@@ -78,7 +78,7 @@
78
78
  <script type="module" crossorigin src="../../index-sfreg6q3.js"></script></head>
79
79
 
80
80
  <body>
81
- <h1>WorkHub API</h1>
81
+ <h1>Strata</h1>
82
82
  <p class="hint">
83
83
  Framework reference domain for organizations, projects, tasks, and
84
84
  comments.
@@ -1,5 +1,12 @@
1
+ import type { RouteHandler } from "@getstrata/core/http/middleware";
1
2
  import type { AppDependencies, AppRouteMap } from "./contracts";
2
3
  declare const SPA_DIST_DIRECTORY: string;
3
- declare function createSpaRoutes(_dependencies: AppDependencies): AppRouteMap;
4
- declare function mergeSpaRoutes(dependencies: AppDependencies, routes: AppRouteMap): AppRouteMap;
4
+ type SpaRouteOptions = {
5
+ prefix?: string;
6
+ distDirectory?: string;
7
+ wrap?: (handler: RouteHandler) => RouteHandler;
8
+ };
9
+ declare function createSpaRoutes(_dependencies: AppDependencies, options?: SpaRouteOptions): AppRouteMap;
10
+ declare function mergeSpaRoutes(dependencies: AppDependencies, routes: AppRouteMap, options?: SpaRouteOptions): AppRouteMap;
11
+ export type { SpaRouteOptions };
5
12
  export { createSpaRoutes, mergeSpaRoutes, SPA_DIST_DIRECTORY };
@@ -1,4 +1,8 @@
1
- import type { AppDependencies, AppRouteMap } from "./contracts";
2
- declare function createWebRoutes(dependencies: AppDependencies): AppRouteMap;
3
- declare function mergeWebRoutes(dependencies: AppDependencies, routes: AppRouteMap): AppRouteMap;
1
+ import type { AppDependencies, AppModule, AppRouteMap } from "./contracts";
2
+ interface CreateWebRoutesOptions {
3
+ modules?: AppModule[];
4
+ }
5
+ declare function createWebRoutes(dependencies: AppDependencies, options?: CreateWebRoutesOptions): AppRouteMap;
6
+ declare function mergeWebRoutes(dependencies: AppDependencies, routes: AppRouteMap, options?: CreateWebRoutesOptions): AppRouteMap;
7
+ export type { CreateWebRoutesOptions };
4
8
  export { createWebRoutes, mergeWebRoutes };
@@ -0,0 +1,7 @@
1
+ type DogfoodApp = "hiroapp";
2
+ declare function readDogfoodApp(): DogfoodApp;
3
+ declare function isHiroappDogfood(): boolean;
4
+ declare function hiroappSourcePath(...segments: string[]): string;
5
+ declare function importHiroappModule<T = unknown>(relativeFromApp: string): Promise<T>;
6
+ export type { DogfoodApp };
7
+ export { hiroappSourcePath, importHiroappModule, isHiroappDogfood, readDogfoodApp };
@@ -12,19 +12,19 @@ declare class HttpKernel {
12
12
  wrap(groups: MiddlewareGroupName | MiddlewareGroupName[], handler: RouteHandler): RouteHandler;
13
13
  wrapApi(handler: RouteHandler): RouteHandler;
14
14
  wrapWeb(handler: RouteHandler): RouteHandler;
15
- /** Laravel `guest` / `RedirectIfAuthenticated` signed-in users go to `home`. */
15
+ /** Signed-in HTML users redirect to `home` instead of seeing guest pages. */
16
16
  wrapWebGuest(handler: RouteHandler, home?: WebGuestHome): RouteHandler;
17
17
  wrapWebPublicRead(handler: RouteHandler): RouteHandler;
18
18
  wrapWebAuthenticated(handler: RouteHandler): RouteHandler;
19
- /** Signed-in HTML without Laravel `verified` (logout, verification notice). */
19
+ /** Signed-in HTML without the email-verified gate (logout, verification notice). */
20
20
  wrapWebAuthenticatedAllowUnverified(handler: RouteHandler): RouteHandler;
21
21
  wrapWebVerified(handler: RouteHandler): RouteHandler;
22
- /** Laravel `password.confirm` — requires a fresh signed confirmation cookie. */
22
+ /** Requires a fresh signed password-confirmation cookie. */
23
23
  wrapWebPasswordConfirm(handler: RouteHandler): RouteHandler;
24
24
  wrapWebAbility(ability: string, handler: RouteHandler): RouteHandler;
25
25
  wrapWebGlobalAdmin(handler: RouteHandler): RouteHandler;
26
26
  wrapAuthenticated(handler: RouteHandler): RouteHandler;
27
- /** Laravel `verified` for JSON/API routes. No-op when `FEATURE_EMAIL_VERIFICATION` is off. */
27
+ /** JSON routes that require a verified email. No-op when `FEATURE_EMAIL_VERIFICATION` is off. */
28
28
  wrapVerified(handler: RouteHandler): RouteHandler;
29
29
  wrapPublicRead(handler: RouteHandler): RouteHandler;
30
30
  wrapGlobalAdmin(handler: RouteHandler): RouteHandler;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @getstrata/bootstrap application shell for Strata sibling apps.
2
+ * @getstrata/bootstrap: application shell for Strata apps.
3
3
  */
4
4
  export type { ScheduledTask } from "@getstrata/core/scheduler/schedule";
5
5
  export { appSchedule, runDueScheduledTasks, Schedule } from "@getstrata/core/scheduler/schedule";
@@ -13,6 +13,7 @@ export { APP_PORT_CONFIG_KEY, CORE_ABILITY_CHECKER_TOKEN, CORE_AUTH_TOKEN, CORE_
13
13
  export { collectProviders, createAppContext, runProviderPhase } from "./context.ts";
14
14
  export type { AppContext, AppDependencies, AppModule, AppRouteMap, CachedJson, ConfigStore, ModuleRouteContext, MutableAppDependencies, ProviderContext, ServiceFactory, ServiceProvider, } from "./contracts.ts";
15
15
  export { assertAppDependenciesComplete, getRequiredDependency, resolveService, ServiceContainer, } from "./contracts.ts";
16
+ export type { CreateWebRoutesOptions } from "./createWebRoutes.ts";
16
17
  export { createWebRoutes, mergeWebRoutes } from "./createWebRoutes.ts";
17
18
  export { createAppDependencies } from "./dependencies.ts";
18
19
  export type { DiscoverModulesOptions } from "./discoverModules.ts";
@@ -0,0 +1,5 @@
1
+ type SchemaTarget = "app" | "fixture";
2
+ declare function readSchemaTarget(): SchemaTarget;
3
+ declare function isFixtureSchema(): boolean;
4
+ export type { SchemaTarget };
5
+ export { isFixtureSchema, readSchemaTarget };
@@ -1 +1 @@
1
- import "./preloadModules.ts";
1
+ export {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Web-focused bootstrap utilities for sibling apps (getstrata, marketing sites).
2
+ * Web-focused bootstrap utilities for HTML and cookie-session apps.
3
3
  */
4
4
  export { createCsrfProtection, type ParsedForm, parseFormBody } from "./forms.ts";
5
5
  export { createRouteKernel, routeParams, toRouteRequest, wrapSecuredRouteModelByKey, wrapWebLogin, wrapWebRegister, } from "./routing.ts";
@@ -10,7 +10,7 @@ export declare function routeParams(request: Request): Record<string, string>;
10
10
  */
11
11
  export declare function toRouteRequest<TParams extends Record<string, string>>(request: Request): RouteRequest<TParams>;
12
12
  /**
13
- * Laravel-style secured route-model binding for string keys (slugs, UUIDs).
13
+ * Secured route-model binding for string keys (slugs, UUIDs).
14
14
  * Public HTML show pages should look up the model in the controller instead.
15
15
  * If this wrapper is still used on HTML, a missing model becomes a styled 404
16
16
  * and GET ETags are skipped for HTML / composite objects unless `etag: true`.
@@ -24,5 +24,5 @@ export declare function wrapSecuredRouteModelByKey<TParams extends Record<string
24
24
  export declare function wrapWebLogin(kernel: HttpKernel, handler: RouteHandler, onThrottled: (request: Request) => Response | Promise<Response>): RouteHandler;
25
25
  /** Web group (CSRF + flash + HTML errors) plus register throttle. Do not wrap with wrapWeb again. */
26
26
  export declare function wrapWebRegister(kernel: HttpKernel, handler: RouteHandler, onThrottled: (request: Request) => Response | Promise<Response>): RouteHandler;
27
- /** Convenience alias: HttpKernel is the Laravel-style router middleware wrapper. */
27
+ /** Convenience alias for `createHttpKernel`. */
28
28
  export declare function createRouteKernel(dependencies: AppDependencies): HttpKernel;
@@ -12,6 +12,18 @@ type SqlClient = {
12
12
  };
13
13
  type SqlSource = SqlClient | (() => SqlClient);
14
14
  export type LoadSessionUser = (sql: SqlClient, sessionId: string) => Promise<SessionUser | null>;
15
+ export interface SessionCreateMeta {
16
+ userAgent?: string | null;
17
+ ipAddress?: string | null;
18
+ }
19
+ export interface BrowserSessionRecord {
20
+ id: string;
21
+ user_id: number;
22
+ user_agent: string | null;
23
+ ip_address: string | null;
24
+ last_active_at: Date | string | null;
25
+ expires_at: Date | string;
26
+ }
15
27
  declare function defaultSessionSql(): SqlClient;
16
28
  export type MapSessionUser = (user: SessionUser) => AuthUser;
17
29
  declare function defaultMapSessionUser(user: SessionUser): AuthUser;
@@ -27,8 +39,11 @@ export declare class CookieSessionStore {
27
39
  sessionIdFromRequest(request: Request): string | null;
28
40
  private withSecureFlag;
29
41
  private sql;
30
- create(user: SessionUser): Promise<string>;
42
+ create(user: SessionUser, meta?: SessionCreateMeta): Promise<string>;
31
43
  destroy(sessionId: string): Promise<void>;
44
+ destroyOtherSessions(userId: number, keepSessionId: string): Promise<void>;
45
+ listForUser(userId: number): Promise<BrowserSessionRecord[]>;
46
+ touch(sessionId: string): Promise<void>;
32
47
  read(request: Request): Promise<SessionUser | null>;
33
48
  private sign;
34
49
  }
@@ -41,14 +56,14 @@ export declare class CookieSessionGuard implements AuthGuard {
41
56
  export declare class CookieSessionAuthManager extends AuthManager {
42
57
  readonly store: CookieSessionStore;
43
58
  constructor(store: CookieSessionStore, mapUser?: MapSessionUser);
44
- signIn(user: SessionUser): Promise<{
59
+ signIn(user: SessionUser, meta?: SessionCreateMeta): Promise<{
45
60
  sessionId: string;
46
61
  setCookie: string;
47
62
  }>;
48
63
  signOut(request: Request): Promise<{
49
64
  setCookie: string;
50
65
  }>;
51
- signInRedirect(user: SessionUser, location: string, status?: number): Promise<Response>;
66
+ signInRedirect(user: SessionUser, location: string, status?: number, meta?: SessionCreateMeta): Promise<Response>;
52
67
  signOutRedirect(request: Request, location: string, status?: number): Promise<Response>;
53
68
  }
54
69
  export interface CreateCookieSessionAuthManagerOptions {
@@ -28,7 +28,7 @@ import { createRequireGlobalAdminMiddleware } from "@getstrata/core/http/require
28
28
  import { createRequirePasswordConfirmMiddleware } from "@getstrata/core/http/requirePasswordConfirmMiddleware";
29
29
  import { createRequireVerifiedMiddleware } from "@getstrata/core/http/requireVerifiedMiddleware";
30
30
  import { createRequireWebAuthMiddleware } from "@getstrata/core/http/requireWebAuthMiddleware";
31
- import { withErrorHandling } from "@getstrata/core/http/response";
31
+ import { withErrorHandling, withJsonErrorHandling } from "@getstrata/core/http/response";
32
32
  import { withMiddleware } from "@getstrata/core/http/routeMiddleware";
33
33
  import { createSecurityHeadersMiddleware } from "@getstrata/core/http/securityHeadersMiddleware";
34
34
  import { createValidateSignatureMiddleware } from "@getstrata/core/http/signedUrl";
@@ -176,7 +176,7 @@ class HttpKernel {
176
176
  return withMiddleware(...middleware)(handler);
177
177
  }
178
178
  wrapApi(handler) {
179
- return this.wrap(["api", "authenticated"], handler);
179
+ return withJsonErrorHandling(this.wrap(["api", "authenticated"], handler));
180
180
  }
181
181
  wrapWeb(handler) {
182
182
  return withErrorHandling(this.wrap("web", handler));
@@ -341,7 +341,12 @@ function readDiscoverModulesState() {
341
341
  return state;
342
342
  }
343
343
  function configureModulesDirectory(modulesDir) {
344
- readDiscoverModulesState().configuredModulesDir = modulesDir;
344
+ const state = readDiscoverModulesState();
345
+ if (state.configuredModulesDir !== modulesDir) {
346
+ state.appModules.length = 0;
347
+ state.modulesReady = undefined;
348
+ }
349
+ state.configuredModulesDir = modulesDir;
345
350
  }
346
351
  function resolveModulesDirectory(options) {
347
352
  const state = readDiscoverModulesState();
@@ -31,7 +31,7 @@ import { createRequireGlobalAdminMiddleware } from "@getstrata/core/http/require
31
31
  import { createRequirePasswordConfirmMiddleware } from "@getstrata/core/http/requirePasswordConfirmMiddleware";
32
32
  import { createRequireVerifiedMiddleware } from "@getstrata/core/http/requireVerifiedMiddleware";
33
33
  import { createRequireWebAuthMiddleware } from "@getstrata/core/http/requireWebAuthMiddleware";
34
- import { withErrorHandling } from "@getstrata/core/http/response";
34
+ import { withErrorHandling, withJsonErrorHandling } from "@getstrata/core/http/response";
35
35
  import { withMiddleware } from "@getstrata/core/http/routeMiddleware";
36
36
  import { createSecurityHeadersMiddleware } from "@getstrata/core/http/securityHeadersMiddleware";
37
37
  import { createValidateSignatureMiddleware } from "@getstrata/core/http/signedUrl";
@@ -179,7 +179,7 @@ class HttpKernel {
179
179
  return withMiddleware(...middleware)(handler);
180
180
  }
181
181
  wrapApi(handler) {
182
- return this.wrap(["api", "authenticated"], handler);
182
+ return withJsonErrorHandling(this.wrap(["api", "authenticated"], handler));
183
183
  }
184
184
  wrapWeb(handler) {
185
185
  return withErrorHandling(this.wrap("web", handler));
@@ -344,7 +344,12 @@ function readDiscoverModulesState() {
344
344
  return state;
345
345
  }
346
346
  function configureModulesDirectory(modulesDir) {
347
- readDiscoverModulesState().configuredModulesDir = modulesDir;
347
+ const state = readDiscoverModulesState();
348
+ if (state.configuredModulesDir !== modulesDir) {
349
+ state.appModules.length = 0;
350
+ state.modulesReady = undefined;
351
+ }
352
+ state.configuredModulesDir = modulesDir;
348
353
  }
349
354
  function resolveModulesDirectory(options) {
350
355
  const state = readDiscoverModulesState();
@@ -16,7 +16,12 @@ function readDiscoverModulesState() {
16
16
  return state;
17
17
  }
18
18
  function configureModulesDirectory(modulesDir) {
19
- readDiscoverModulesState().configuredModulesDir = modulesDir;
19
+ const state = readDiscoverModulesState();
20
+ if (state.configuredModulesDir !== modulesDir) {
21
+ state.appModules.length = 0;
22
+ state.modulesReady = undefined;
23
+ }
24
+ state.configuredModulesDir = modulesDir;
20
25
  }
21
26
  function resolveModulesDirectory(options) {
22
27
  const state = readDiscoverModulesState();