@stratal/framework 0.0.0-canary-41a9140 → 0.0.0-canary-ccb3f17

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.
Files changed (44) hide show
  1. package/dist/access-control/index.d.mts +38 -11
  2. package/dist/access-control/index.d.mts.map +1 -1
  3. package/dist/access-control/index.mjs +5 -5
  4. package/dist/access-control/index.mjs.map +1 -1
  5. package/dist/{access.service-BmDhE-re.mjs → access.service-rsEreT-4.mjs} +35 -17
  6. package/dist/access.service-rsEreT-4.mjs.map +1 -0
  7. package/dist/auth/index.d.mts +59 -58
  8. package/dist/auth/index.d.mts.map +1 -1
  9. package/dist/auth/index.mjs +41 -11
  10. package/dist/auth/index.mjs.map +1 -1
  11. package/dist/{auth-context-CGVbiSX3.d.mts → auth-context-C1om3Zsr.d.mts} +1 -2
  12. package/dist/auth-context-C1om3Zsr.d.mts.map +1 -0
  13. package/dist/{auth-context-C8NBfiMa.mjs → auth-context-CE_-TV27.mjs} +2 -2
  14. package/dist/{auth-context-C8NBfiMa.mjs.map → auth-context-CE_-TV27.mjs.map} +1 -1
  15. package/dist/auth.service-Onf3JkyL.d.mts +44 -0
  16. package/dist/auth.service-Onf3JkyL.d.mts.map +1 -0
  17. package/dist/context/index.d.mts +1 -2
  18. package/dist/context/index.d.mts.map +1 -1
  19. package/dist/context/index.mjs +1 -1
  20. package/dist/database/index.d.mts +3 -3
  21. package/dist/database/index.mjs +127 -27
  22. package/dist/database/index.mjs.map +1 -1
  23. package/dist/{decorate-B7nr7eBl.mjs → decorate-ZDdbRmsv.mjs} +1 -1
  24. package/dist/{decorateParam-DwV9LSPl.mjs → decorateParam-DQ95ttaa.mjs} +2 -2
  25. package/dist/{decorateParam-DwV9LSPl.mjs.map → decorateParam-DQ95ttaa.mjs.map} +1 -1
  26. package/dist/factory/index.d.mts +1 -2
  27. package/dist/factory/index.d.mts.map +1 -1
  28. package/dist/factory/index.mjs.map +1 -1
  29. package/dist/guards/index.d.mts +0 -1
  30. package/dist/guards/index.d.mts.map +1 -1
  31. package/dist/guards/index.mjs +2 -2
  32. package/dist/guards/index.mjs.map +1 -1
  33. package/dist/{index-Dt0YUA7r.d.mts → index-B8EVn7T5.d.mts} +57 -22
  34. package/dist/index-B8EVn7T5.d.mts.map +1 -0
  35. package/dist/index.d.mts +1 -1
  36. package/dist/{types-CWZ9q74G.d.mts → types-DjLXYLlD.d.mts} +1 -2
  37. package/dist/types-DjLXYLlD.d.mts.map +1 -0
  38. package/package.json +22 -22
  39. package/dist/access.service-BmDhE-re.mjs.map +0 -1
  40. package/dist/auth-context-CGVbiSX3.d.mts.map +0 -1
  41. package/dist/index-Dt0YUA7r.d.mts.map +0 -1
  42. package/dist/types-CWZ9q74G.d.mts.map +0 -1
  43. package/dist/types-DabF8LGz.d.mts +0 -11
  44. package/dist/types-DabF8LGz.d.mts.map +0 -1
@@ -1,13 +1,14 @@
1
- import { n as RolePermissions, t as AccessControlOptions } from "../types-DabF8LGz.mjs";
2
- import { M as DatabaseService } from "../index-Dt0YUA7r.mjs";
3
- import { t as AuthContext } from "../auth-context-CGVbiSX3.mjs";
1
+ import { n as AccessControlOptions, r as RolePermissions, t as AuthService } from "../auth.service-Onf3JkyL.mjs";
2
+ import { t as AuthContext } from "../auth-context-C1om3Zsr.mjs";
4
3
  import { HttpException } from "stratal/errors";
4
+ import { Middleware, Next, RouterContext } from "stratal/router";
5
5
  import { AccessControl, Role, Statements } from "better-auth/plugins/access";
6
6
  import { BetterAuthPlugin } from "better-auth";
7
-
8
7
  //#region src/access-control/tokens.d.ts
9
8
  declare const AC_TOKENS: {
10
- /** Request-scoped access service */readonly AccessService: symbol; /** Access control module options (ac, roles) */
9
+ /** Request-scoped access service */
10
+ readonly AccessService: symbol;
11
+ /** Access control module options (ac, roles) */
11
12
  readonly Options: symbol;
12
13
  };
13
14
  //#endregion
@@ -24,7 +25,7 @@ declare const AC_TOKENS: {
24
25
  * resources: {
25
26
  * posts: ['create', 'read', 'update', 'delete'],
26
27
  * admin: ['access'],
27
- * } as const,
28
+ * },
28
29
  * roles: {
29
30
  * admin: { posts: ['create', 'read', 'update', 'delete'], admin: ['access'] },
30
31
  * user: { posts: ['create', 'read'] },
@@ -38,7 +39,7 @@ declare const AC_TOKENS: {
38
39
  * plugins: [admin({ ...permissions })]
39
40
  * ```
40
41
  */
41
- declare function createAccessControl<TResources extends Statements, TRoles extends Record<string, RolePermissions<TResources>>>(config: {
42
+ declare function createAccessControl<const TResources extends Statements, const TRoles extends Record<string, RolePermissions<TResources>>>(config: {
42
43
  resources: TResources;
43
44
  roles: TRoles;
44
45
  }): AccessControlOptions<TResources, TRoles>;
@@ -55,7 +56,7 @@ declare function createAccessControl<TResources extends Statements, TRoles exten
55
56
  * // → { posts: readonly ('create' | 'read' | 'update')[]; admin: readonly ['access'] }
56
57
  * ```
57
58
  */
58
- type MergeStatements<A extends Statements, B extends Partial<Record<string, readonly string[]>>> = { [K in keyof A | keyof B]: K extends keyof A ? K extends keyof B ? readonly (A[K][number] | NonNullable<B[K]>[number])[] : A[K] : K extends keyof B ? NonNullable<B[K]> : never } & {};
59
+ type MergeStatements<A extends Statements, B extends Partial<Record<string, readonly string[]>>> = { [K in keyof A | keyof B]: K extends keyof A ? K extends keyof B ? readonly (A[K][number] | NonNullable<B[K]>[number])[] : A[K] : K extends keyof B ? NonNullable<B[K]> : never; } & {};
59
60
  /**
60
61
  * Extend an existing role with additional permissions.
61
62
  *
@@ -117,9 +118,9 @@ declare function createStratalAcPlugin(_options: AccessControlOptions): BetterAu
117
118
  */
118
119
  declare class AccessService {
119
120
  private readonly authContext;
120
- private readonly db;
121
+ private readonly authService;
121
122
  private readonly options;
122
- constructor(authContext: AuthContext, db: DatabaseService, options: AccessControlOptions);
123
+ constructor(authContext: AuthContext, authService: AuthService, options: AccessControlOptions);
123
124
  /**
124
125
  * Get all roles for a user.
125
126
  *
@@ -163,6 +164,32 @@ declare class AccessService {
163
164
  private mergePermissions;
164
165
  }
165
166
  //#endregion
167
+ //#region src/access-control/access-share.middleware.d.ts
168
+ /**
169
+ * Shares the current user's roles and merged permissions as the `access` prop
170
+ * on every Inertia page rendered during the request, so the client can gate
171
+ * rendering with `<Can>` / `<HasRole>` from `@stratal/inertia/react/access`.
172
+ *
173
+ * Both values come from `AuthContext` (populated by
174
+ * `SessionVerificationMiddleware`) — no database hit and no I/O, which is why
175
+ * this is registered globally by `AuthModule` rather than being opt-in the way
176
+ * `FeatureFlagShareMiddleware` is.
177
+ *
178
+ * Inert unless access control is configured and Inertia is installed. Not
179
+ * restricted to `GET`: an Inertia render can legally happen on any method —
180
+ * e.g. `return ctx.inertia('Posts/Create', {...})` from a `POST` handler
181
+ * re-rendering after a validation failure — and every `<Can>` / `useCan` on
182
+ * that page needs `access` just as much as it would on a full `GET` visit.
183
+ *
184
+ * Wrapped in `ctx.always()` so partial reloads never drop the prop; the client
185
+ * treats an absent `access` prop as a wiring error, not as "denied".
186
+ */
187
+ declare class AccessShareMiddleware implements Middleware {
188
+ private readonly access?;
189
+ constructor(access?: AccessService | undefined);
190
+ handle(ctx: RouterContext, next: Next): Promise<void>;
191
+ }
192
+ //#endregion
166
193
  //#region src/access-control/errors/insufficient-permissions.error.d.ts
167
194
  declare class InsufficientPermissionsError extends HttpException {
168
195
  readonly requiredPermissions: string;
@@ -170,5 +197,5 @@ declare class InsufficientPermissionsError extends HttpException {
170
197
  constructor(requiredPermissions: string | string[], userId?: string);
171
198
  }
172
199
  //#endregion
173
- export { AC_TOKENS, type AccessControlOptions, AccessService, InsufficientPermissionsError, createAccessControl, createStratalAcPlugin, extendRole };
200
+ export { AC_TOKENS, type AccessControlOptions, AccessService, AccessShareMiddleware, InsufficientPermissionsError, createAccessControl, createStratalAcPlugin, extendRole };
174
201
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/access-control/tokens.ts","../../src/access-control/create-access-control.ts","../../src/access-control/extend-role.ts","../../src/access-control/plugin.ts","../../src/access-control/services/access.service.ts","../../src/access-control/errors/insufficient-permissions.error.ts"],"mappings":";;;;;;;;cAAa,SAAA;+CAKH,aAAA;WAAA,OAAA;AAAA;;;;;;;;;AALV;;;;;;;;AC8BA;;;;;;;;;;;;iBAAgB,mBAAA,oBACK,UAAA,iBACJ,MAAA,SAAe,eAAA,CAAgB,UAAA,IAC9C,MAAA;EACA,SAAA,EAAW,UAAA;EACX,KAAA,EAAO,MAAA;AAAA,IACL,oBAAA,CAAqB,UAAA,EAAY,MAAA;;;;;;;;;;ADpCrC;;;;KEaK,eAAA,WACO,UAAA,YACA,OAAA,CAAQ,MAAA,8CAEN,CAAA,SAAU,CAAA,GAAI,CAAA,eAAgB,CAAA,GACxC,CAAA,eAAgB,CAAA,aACN,CAAA,CAAE,CAAA,YAAa,WAAA,CAAY,CAAA,CAAE,CAAA,gBACvC,CAAA,CAAE,CAAA,IACF,CAAA,eAAgB,CAAA,GAChB,WAAA,CAAY,CAAA,CAAE,CAAA;;ADQlB;;;;;;;;;;;;;;;;iBCagB,UAAA,iBACE,UAAA,iBACD,OAAA,CAAQ,MAAA,8BAEvB,EAAA,EAAI,aAAA,CAAc,OAAA,GAClB,MAAA,EAAQ,IAAA,CAAK,OAAA,GACb,KAAA,EAAO,MAAA,GACN,IAAA,CAAK,eAAA,CAAgB,OAAA,EAAS,MAAA;;;;;;;;;AFlDjC;;;iBGYgB,qBAAA,CAAsB,QAAA,EAAU,oBAAA,GAAuB,gBAAgB;;;;;;;;AHZvF;;;;;;;;AC8BA;;;;;;;;;;;;;;cGSa,aAAA;EAAA,iBAGQ,WAAA;EAAA,iBAEA,EAAA;EAAA,iBAEA,OAAA;cAJA,WAAA,EAAa,WAAA,EAEb,EAAA,EAAI,eAAA,EAEJ,OAAA,EAAS,oBAAA;EHdkB;;;;;;EGuBxC,YAAA,CAAa,MAAA,WAAiB,OAAA;EHnBb;;;AAAkB;;EGoCnC,WAAA,CAAY,MAAA,UAAgB,IAAA,sBAA0B,OAAA;;AFxEmB;;;;EEqFzE,aAAA,CAAc,MAAA,UAAgB,WAAA,EAAa,MAAA,qBAA2B,OAAA;EFtElE;;;;EE+EJ,qBAAA,CAAsB,MAAA,WAAiB,OAAA,CAAQ,MAAA;EF5EnD;;;;EEqFF,mBAAA;EFpFyC;;;;EE4FzC,wBAAA,CAAyB,WAAA,EAAa,MAAA;EF1FpB;;;;EEoGlB,yBAAA,IAA6B,MAAA;EAAA,QAKrB,gBAAA;EAAA,QAqBA,gBAAA;AAAA;;;cCjJG,4BAAA,SAAqC,aAAa;EAAA,SAC7C,mBAAA;EAAA,SACA,MAAA;cAEJ,mBAAA,qBAAwC,MAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/access-control/tokens.ts","../../src/access-control/create-access-control.ts","../../src/access-control/extend-role.ts","../../src/access-control/plugin.ts","../../src/access-control/services/access.service.ts","../../src/access-control/access-share.middleware.ts","../../src/access-control/errors/insufficient-permissions.error.ts"],"mappings":";;;;;;;cAAa;;WAEX;;WAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC0Bc,0BACR,mBAAmB,kBACnB,eAAe,eAAe,gBAAgB,cACpD;EACA,WAAW;EACX,OAAO;IACL,qBAAqB,YAAY;;;;;;;;;;;;;;KCvBhC,gBACH,UAAU,YACV,UAAU,QAAQ,yCAEjB,WAAW,UAAU,IAAI,gBAAgB,IACxC,gBAAgB,cACN,EAAE,aAAa,YAAY,EAAE,iBACvC,EAAE,KACF,gBAAgB,IAChB,YAAY,EAAE;;;;;;;;;;;;;;;;;;iBAqBF,WACd,gBAAgB,YAChB,eAAe,QAAQ,oCAEvB,IAAI,cAAc,UAClB,QAAQ,KAAK,UACb,OAAO,SACN,KAAK,gBAAgB,SAAS;;;;;;;;;;;;iBCtCjB,sBAAsB,UAAU,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cC4B1D;mBAGQ;mBAEA;mBAEA;EANnB,YAEmB,aAAa,aAEb,aAAa,aAEb,SAAS;;;;;;;EAStB,aAAa,iBAAiB;;;;;;EAe9B,YAAY,gBAAgB,0BAA0B;;;;;;EActD,cAAc,gBAAgB,aAAa,2BAA2B;;;;;EAStE,sBAAsB,iBAAiB,QAAQ;;;;;EASrD;;;;;EAQA,yBAAyB,aAAa;;;;;EAUtC,6BAA6B;UAKrB;UAqBA;;;;;;;;;;;;;;;;;;;;;;;cC7GG,iCAAiC;mBAGzB;EAFnB,YAEmB,SAAS;EAGtB,OAAO,KAAK,eAAe,MAAM,OAAO;;;;cC1CnC,qCAAqC;WAChC;WACA;EAEhB,YAAY,wCAAwC"}
@@ -1,5 +1,5 @@
1
- import { n as createStratalAcPlugin, t as AccessService } from "../access.service-BmDhE-re.mjs";
2
- import { n as AC_TOKENS } from "../decorateParam-DwV9LSPl.mjs";
1
+ import { n as AC_TOKENS } from "../decorateParam-DQ95ttaa.mjs";
2
+ import { a as AccessShareMiddleware, i as createStratalAcPlugin, t as AccessService } from "../access.service-rsEreT-4.mjs";
3
3
  import { t as InsufficientPermissionsError } from "../insufficient-permissions.error-DeEyZRgy.mjs";
4
4
  import { createAccessControl as createAccessControl$1 } from "better-auth/plugins/access";
5
5
  //#region src/access-control/create-access-control.ts
@@ -15,7 +15,7 @@ import { createAccessControl as createAccessControl$1 } from "better-auth/plugin
15
15
  * resources: {
16
16
  * posts: ['create', 'read', 'update', 'delete'],
17
17
  * admin: ['access'],
18
- * } as const,
18
+ * },
19
19
  * roles: {
20
20
  * admin: { posts: ['create', 'read', 'update', 'delete'], admin: ['access'] },
21
21
  * user: { posts: ['create', 'read'] },
@@ -60,12 +60,12 @@ function extendRole(ac, parent, extra) {
60
60
  for (const [key, actions] of Object.entries(parent.statements)) merged[key] = [...actions];
61
61
  for (const [key, actions] of Object.entries(extra)) {
62
62
  if (!actions) continue;
63
- if (key in merged) merged[key] = [...new Set([...merged[key], ...actions])];
63
+ if (key in merged) merged[key] = [.../* @__PURE__ */ new Set([...merged[key], ...actions])];
64
64
  else merged[key] = [...actions];
65
65
  }
66
66
  return ac.newRole(merged);
67
67
  }
68
68
  //#endregion
69
- export { AC_TOKENS, AccessService, InsufficientPermissionsError, createAccessControl, createStratalAcPlugin, extendRole };
69
+ export { AC_TOKENS, AccessService, AccessShareMiddleware, InsufficientPermissionsError, createAccessControl, createStratalAcPlugin, extendRole };
70
70
 
71
71
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["baCreateAC"],"sources":["../../src/access-control/create-access-control.ts","../../src/access-control/extend-role.ts"],"sourcesContent":["import type { Role, Statements } from 'better-auth/plugins/access'\nimport { createAccessControl as baCreateAC } from 'better-auth/plugins/access'\nimport type { AccessControlOptions, RolePermissions } from './types'\n\n/**\n * Define access control resources and roles in one place.\n *\n * Returns `{ ac, roles }` — spread this directly into `accessControl`,\n * `admin({ ...permissions })`, or `organization({ ...permissions })`.\n *\n * @example\n * ```typescript\n * export const permissions = createAccessControl({\n * resources: {\n * posts: ['create', 'read', 'update', 'delete'],\n * admin: ['access'],\n * } as const,\n * roles: {\n * admin: { posts: ['create', 'read', 'update', 'delete'], admin: ['access'] },\n * user: { posts: ['create', 'read'] },\n * },\n * })\n *\n * // In AuthModule:\n * accessControl: permissions\n *\n * // With Better Auth admin plugin (same object):\n * plugins: [admin({ ...permissions })]\n * ```\n */\nexport function createAccessControl<\n TResources extends Statements,\n TRoles extends Record<string, RolePermissions<TResources>>,\n>(config: {\n resources: TResources\n roles: TRoles\n}): AccessControlOptions<TResources, TRoles> {\n const ac = baCreateAC(config.resources)\n const roles = Object.fromEntries(\n Object.entries(config.roles).map(([name, perms]) => [name, ac.newRole(perms as unknown as Statements)])\n ) as { [K in keyof TRoles]: Role<TResources> }\n return { ac, roles }\n}\n","import type { AccessControl, Role, Statements } from 'better-auth/plugins/access'\n\n/**\n * Merges two Statements types, unioning the action arrays for overlapping resource keys.\n *\n * @example\n * ```typescript\n * type A = { posts: readonly ['create', 'read'] }\n * type B = { posts: readonly ['update']; admin: readonly ['access'] }\n * type M = MergeStatements<A, B>\n * // → { posts: readonly ('create' | 'read' | 'update')[]; admin: readonly ['access'] }\n * ```\n */\ntype MergeStatements<\n A extends Statements,\n B extends Partial<Record<string, readonly string[]>>\n> = {\n [K in keyof A | keyof B]: K extends keyof A\n ? K extends keyof B\n ? readonly (A[K][number] | NonNullable<B[K]>[number])[]\n : A[K]\n : K extends keyof B\n ? NonNullable<B[K]>\n : never\n} & {}\n\n/**\n * Extend an existing role with additional permissions.\n *\n * Duplicate resource keys are merged (actions are unioned), not overwritten.\n * Better Auth has no built-in role inheritance — use this to compose roles.\n *\n * @example\n * ```typescript\n * const adminRole = ac.newRole({ posts: ['create', 'read', 'update', 'delete'] })\n * const superAdminRole = extendRole(ac, adminRole, { users: ['ban', 'delete'] })\n * // superAdminRole has both posts and users permissions\n *\n * // Duplicate keys are merged, not overwritten:\n * const editorRole = extendRole(ac, userRole, { posts: ['update'] })\n * // if userRole had posts: ['create', 'read'], editorRole has posts: ['create', 'read', 'update']\n * ```\n */\nexport function extendRole<\n TParent extends Statements,\n TExtra extends Partial<Record<string, readonly string[]>>\n>(\n ac: AccessControl<TParent>,\n parent: Role<TParent>,\n extra: TExtra\n): Role<MergeStatements<TParent, TExtra>> {\n const merged: Record<string, string[]> = {}\n\n for (const [key, actions] of Object.entries(parent.statements)) {\n merged[key] = [...(actions as string[])]\n }\n\n for (const [key, actions] of Object.entries(extra)) {\n if (!actions) continue\n if (key in merged) {\n merged[key] = [...new Set([...merged[key], ...actions])]\n } else {\n merged[key] = [...actions]\n }\n }\n\n return ac.newRole(merged) as Role<MergeStatements<TParent, TExtra>>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,oBAGd,QAG2C;CAC3C,MAAM,KAAKA,sBAAW,OAAO,SAAS;CAItC,OAAO;EAAE;EAAI,OAHC,OAAO,YACnB,OAAO,QAAQ,OAAO,KAAK,EAAE,KAAK,CAAC,MAAM,WAAW,CAAC,MAAM,GAAG,QAAQ,KAA8B,CAAC,CAAC,CAEvF;CAAE;AACrB;;;;;;;;;;;;;;;;;;;;ACCA,SAAgB,WAId,IACA,QACA,OACwC;CACxC,MAAM,SAAmC,CAAC;CAE1C,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,OAAO,UAAU,GAC3D,OAAO,OAAO,CAAC,GAAI,OAAoB;CAGzC,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,KAAK,GAAG;EAClD,IAAI,CAAC,SAAS;EACd,IAAI,OAAO,QACT,OAAO,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,OAAO,MAAM,GAAG,OAAO,CAAC,CAAC;OAEvD,OAAO,OAAO,CAAC,GAAG,OAAO;CAE7B;CAEA,OAAO,GAAG,QAAQ,MAAM;AAC1B"}
1
+ {"version":3,"file":"index.mjs","names":["baCreateAC"],"sources":["../../src/access-control/create-access-control.ts","../../src/access-control/extend-role.ts"],"sourcesContent":["import type { Role, Statements } from 'better-auth/plugins/access'\nimport { createAccessControl as baCreateAC } from 'better-auth/plugins/access'\nimport type { AccessControlOptions, RolePermissions } from './types'\n\n/**\n * Define access control resources and roles in one place.\n *\n * Returns `{ ac, roles }` — spread this directly into `accessControl`,\n * `admin({ ...permissions })`, or `organization({ ...permissions })`.\n *\n * @example\n * ```typescript\n * export const permissions = createAccessControl({\n * resources: {\n * posts: ['create', 'read', 'update', 'delete'],\n * admin: ['access'],\n * },\n * roles: {\n * admin: { posts: ['create', 'read', 'update', 'delete'], admin: ['access'] },\n * user: { posts: ['create', 'read'] },\n * },\n * })\n *\n * // In AuthModule:\n * accessControl: permissions\n *\n * // With Better Auth admin plugin (same object):\n * plugins: [admin({ ...permissions })]\n * ```\n */\nexport function createAccessControl<\n const TResources extends Statements,\n const TRoles extends Record<string, RolePermissions<TResources>>,\n>(config: {\n resources: TResources\n roles: TRoles\n}): AccessControlOptions<TResources, TRoles> {\n const ac = baCreateAC(config.resources)\n const roles = Object.fromEntries(\n Object.entries(config.roles).map(([name, perms]) => [name, ac.newRole(perms as unknown as Statements)])\n ) as { [K in keyof TRoles]: Role<TResources> }\n return { ac, roles }\n}\n","import type { AccessControl, Role, Statements } from 'better-auth/plugins/access'\n\n/**\n * Merges two Statements types, unioning the action arrays for overlapping resource keys.\n *\n * @example\n * ```typescript\n * type A = { posts: readonly ['create', 'read'] }\n * type B = { posts: readonly ['update']; admin: readonly ['access'] }\n * type M = MergeStatements<A, B>\n * // → { posts: readonly ('create' | 'read' | 'update')[]; admin: readonly ['access'] }\n * ```\n */\ntype MergeStatements<\n A extends Statements,\n B extends Partial<Record<string, readonly string[]>>\n> = {\n [K in keyof A | keyof B]: K extends keyof A\n ? K extends keyof B\n ? readonly (A[K][number] | NonNullable<B[K]>[number])[]\n : A[K]\n : K extends keyof B\n ? NonNullable<B[K]>\n : never\n} & {}\n\n/**\n * Extend an existing role with additional permissions.\n *\n * Duplicate resource keys are merged (actions are unioned), not overwritten.\n * Better Auth has no built-in role inheritance — use this to compose roles.\n *\n * @example\n * ```typescript\n * const adminRole = ac.newRole({ posts: ['create', 'read', 'update', 'delete'] })\n * const superAdminRole = extendRole(ac, adminRole, { users: ['ban', 'delete'] })\n * // superAdminRole has both posts and users permissions\n *\n * // Duplicate keys are merged, not overwritten:\n * const editorRole = extendRole(ac, userRole, { posts: ['update'] })\n * // if userRole had posts: ['create', 'read'], editorRole has posts: ['create', 'read', 'update']\n * ```\n */\nexport function extendRole<\n TParent extends Statements,\n TExtra extends Partial<Record<string, readonly string[]>>\n>(\n ac: AccessControl<TParent>,\n parent: Role<TParent>,\n extra: TExtra\n): Role<MergeStatements<TParent, TExtra>> {\n const merged: Record<string, string[]> = {}\n\n for (const [key, actions] of Object.entries(parent.statements)) {\n merged[key] = [...(actions as string[])]\n }\n\n for (const [key, actions] of Object.entries(extra)) {\n if (!actions) continue\n if (key in merged) {\n merged[key] = [...new Set([...merged[key], ...actions])]\n } else {\n merged[key] = [...actions]\n }\n }\n\n return ac.newRole(merged) as Role<MergeStatements<TParent, TExtra>>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,oBAGd,QAG2C;CAC3C,MAAM,KAAKA,sBAAW,OAAO,SAAS;CAItC,OAAO;EAAE;EAAI,OAHC,OAAO,YACnB,OAAO,QAAQ,OAAO,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW,CAAC,MAAM,GAAG,QAAQ,KAA8B,CAAC,CAAC,CAEvF;CAAE;AACrB;;;;;;;;;;;;;;;;;;;;ACCA,SAAgB,WAId,IACA,QACA,OACwC;CACxC,MAAM,SAAmC,CAAC;CAE1C,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,OAAO,UAAU,GAC3D,OAAO,OAAO,CAAC,GAAI,OAAoB;CAGzC,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,KAAK,GAAG;EAClD,IAAI,CAAC,SAAS;EACd,IAAI,OAAO,QACT,OAAO,OAAO,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,OAAO,MAAM,GAAG,OAAO,CAAC,CAAC;OAEvD,OAAO,OAAO,CAAC,GAAG,OAAO;CAE7B;CAEA,OAAO,GAAG,QAAQ,MAAM;AAC1B"}
@@ -1,6 +1,24 @@
1
- import { n as AC_TOKENS, t as __decorateParam } from "./decorateParam-DwV9LSPl.mjs";
2
- import { t as __decorate } from "./decorate-B7nr7eBl.mjs";
3
- import { DI_TOKENS, Request, inject } from "stratal/di";
1
+ import { n as AC_TOKENS, t as __decorateParam } from "./decorateParam-DQ95ttaa.mjs";
2
+ import { t as __decorate } from "./decorate-ZDdbRmsv.mjs";
3
+ import { DI_TOKENS, Request, Transient, inject } from "stratal/di";
4
+ //#region src/access-control/access-share.middleware.ts
5
+ let AccessShareMiddleware = class AccessShareMiddleware {
6
+ access;
7
+ constructor(access) {
8
+ this.access = access;
9
+ }
10
+ async handle(ctx, next) {
11
+ const access = this.access;
12
+ const inertia = ctx;
13
+ if (access && typeof inertia.share === "function" && typeof inertia.always === "function") inertia.share("access", inertia.always(() => ({
14
+ roles: access.getCurrentUserRoles(),
15
+ permissions: access.getCurrentUserPermissions()
16
+ })));
17
+ await next();
18
+ }
19
+ };
20
+ AccessShareMiddleware = __decorate([Transient(), __decorateParam(0, inject(AC_TOKENS.AccessService, { isOptional: true }))], AccessShareMiddleware);
21
+ //#endregion
4
22
  //#region src/access-control/plugin.ts
5
23
  /**
6
24
  * Creates the Stratal access control Better Auth plugin.
@@ -23,6 +41,12 @@ function createStratalAcPlugin(_options) {
23
41
  };
24
42
  }
25
43
  //#endregion
44
+ //#region src/auth/auth.tokens.ts
45
+ /** Token for AuthService - core authentication service */
46
+ const AUTH_SERVICE = Symbol.for("stratal:auth:service");
47
+ /** Token for Better Auth options configuration */
48
+ const AUTH_OPTIONS = Symbol.for("stratal:auth:options");
49
+ //#endregion
26
50
  //#region src/access-control/services/access.service.ts
27
51
  function parseRoles(role) {
28
52
  if (!role) return [];
@@ -30,11 +54,11 @@ function parseRoles(role) {
30
54
  }
31
55
  let AccessService = class AccessService {
32
56
  authContext;
33
- db;
57
+ authService;
34
58
  options;
35
- constructor(authContext, db, options) {
59
+ constructor(authContext, authService, options) {
36
60
  this.authContext = authContext;
37
- this.db = db;
61
+ this.authService = authService;
38
62
  this.options = options;
39
63
  }
40
64
  /**
@@ -48,10 +72,7 @@ let AccessService = class AccessService {
48
72
  const roles = this.authContext.getRoles();
49
73
  if (roles.length > 0) return roles;
50
74
  }
51
- return parseRoles((await this.db.user.findUnique({
52
- where: { id: userId },
53
- select: { role: true }
54
- }))?.role);
75
+ return parseRoles((await (await this.authService.auth.$context).internalAdapter.findUserById(userId))?.role);
55
76
  }
56
77
  /**
57
78
  * Assign one or more roles to a user.
@@ -60,10 +81,7 @@ let AccessService = class AccessService {
60
81
  */
61
82
  async setUserRole(userId, role) {
62
83
  const roleStr = Array.isArray(role) ? role.join(",") : role;
63
- await this.db.user.update({
64
- where: { id: userId },
65
- data: { role: roleStr }
66
- });
84
+ await (await this.authService.auth.$context).internalAdapter.updateUser(userId, { role: roleStr });
67
85
  }
68
86
  /**
69
87
  * Check if a user has the required permissions.
@@ -133,10 +151,10 @@ let AccessService = class AccessService {
133
151
  AccessService = __decorate([
134
152
  Request(AC_TOKENS.AccessService),
135
153
  __decorateParam(0, inject(DI_TOKENS.AuthContext)),
136
- __decorateParam(1, inject(DI_TOKENS.Database)),
154
+ __decorateParam(1, inject(AUTH_SERVICE)),
137
155
  __decorateParam(2, inject(AC_TOKENS.Options))
138
156
  ], AccessService);
139
157
  //#endregion
140
- export { createStratalAcPlugin as n, AccessService as t };
158
+ export { AccessShareMiddleware as a, createStratalAcPlugin as i, AUTH_OPTIONS as n, AUTH_SERVICE as r, AccessService as t };
141
159
 
142
- //# sourceMappingURL=access.service-BmDhE-re.mjs.map
160
+ //# sourceMappingURL=access.service-rsEreT-4.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.service-rsEreT-4.mjs","names":[],"sources":["../src/access-control/access-share.middleware.ts","../src/access-control/plugin.ts","../src/auth/auth.tokens.ts","../src/access-control/services/access.service.ts"],"sourcesContent":["import { inject, Transient } from 'stratal/di'\nimport type { Middleware, Next, RouterContext } from 'stratal/router'\nimport type { AccessService } from './services/access.service'\nimport { AC_TOKENS } from './tokens'\n\n/**\n * The Inertia methods this middleware needs, declared structurally.\n *\n * `@stratal/framework` must not depend on `@stratal/inertia` (the dependency\n * runs the other way at the type level, via the generated registry), so the\n * two optional context methods are described here and probed at runtime\n * instead of pulled in through a `/// <reference types=\"...\" />`.\n */\ninterface MaybeInertiaContext {\n share?: (key: string, value: unknown) => void\n always?: <T>(callback: () => T) => unknown\n}\n\n/**\n * Shares the current user's roles and merged permissions as the `access` prop\n * on every Inertia page rendered during the request, so the client can gate\n * rendering with `<Can>` / `<HasRole>` from `@stratal/inertia/react/access`.\n *\n * Both values come from `AuthContext` (populated by\n * `SessionVerificationMiddleware`) — no database hit and no I/O, which is why\n * this is registered globally by `AuthModule` rather than being opt-in the way\n * `FeatureFlagShareMiddleware` is.\n *\n * Inert unless access control is configured and Inertia is installed. Not\n * restricted to `GET`: an Inertia render can legally happen on any method —\n * e.g. `return ctx.inertia('Posts/Create', {...})` from a `POST` handler\n * re-rendering after a validation failure — and every `<Can>` / `useCan` on\n * that page needs `access` just as much as it would on a full `GET` visit.\n *\n * Wrapped in `ctx.always()` so partial reloads never drop the prop; the client\n * treats an absent `access` prop as a wiring error, not as \"denied\".\n */\n@Transient()\nexport class AccessShareMiddleware implements Middleware {\n constructor(\n @inject(AC_TOKENS.AccessService, { isOptional: true })\n private readonly access?: AccessService,\n ) { }\n\n async handle(ctx: RouterContext, next: Next): Promise<void> {\n const access = this.access\n const inertia = ctx as RouterContext & MaybeInertiaContext\n\n if (\n access\n && typeof inertia.share === 'function'\n && typeof inertia.always === 'function'\n ) {\n inertia.share('access', inertia.always(() => ({\n roles: access.getCurrentUserRoles(),\n permissions: access.getCurrentUserPermissions(),\n })))\n }\n\n await next()\n }\n}\n","import type { BetterAuthPlugin } from 'better-auth'\nimport type { AccessControlOptions } from './types'\n\n/**\n * Creates the Stratal access control Better Auth plugin.\n *\n * Ensures the `user.role` schema field exists.\n * No endpoints are added — all permission logic lives in AccessService.\n *\n * Auto-added to Better Auth options when `accessControl` is provided to\n * `AuthModule.forRootAsync()`. Users never call this directly.\n */\nexport function createStratalAcPlugin(_options: AccessControlOptions): BetterAuthPlugin {\n return {\n id: 'stratal-ac',\n schema: {\n user: {\n fields: {\n role: {\n type: 'string',\n required: false,\n input: false,\n defaultValue: 'user',\n },\n },\n },\n },\n }\n}\n","/** Token for AuthService - core authentication service */\nexport const AUTH_SERVICE = Symbol.for('stratal:auth:service')\n\n/** Token for Better Auth options configuration */\nexport const AUTH_OPTIONS = Symbol.for('stratal:auth:options')\n","import { DI_TOKENS, inject, Request } from 'stratal/di'\nimport { AUTH_SERVICE } from '../../auth/auth.tokens'\nimport type { AuthService } from '../../auth/services/auth.service'\nimport type { AuthContext } from '../../context/auth-context'\nimport { AC_TOKENS } from '../tokens'\nimport type { AccessControlOptions } from '../types'\n\nfunction parseRoles(role: string | null | undefined): string[] {\n if (!role) return []\n return role.split(',').map(r => r.trim()).filter(Boolean)\n}\n\n/**\n * AccessService\n *\n * Request-scoped service for role and permission management.\n *\n * Roles for the current user are read from AuthContext (populated by\n * SessionVerificationMiddleware — no DB hit). Other users are resolved\n * from the database.\n *\n * Permission checks use Better Auth's `role.authorize()` locally with\n * OR logic — access is granted if any of the user's roles allows it.\n *\n * @example\n * ```typescript\n * // Check current user\n * await accessService.currentUserHasPermission({ posts: ['update'] })\n *\n * // Check arbitrary user (e.g. from an admin action)\n * await accessService.hasPermission(userId, { admin: ['access'] })\n *\n * // Assign a role\n * await accessService.setUserRole(userId, 'admin')\n *\n * // Assign multiple roles\n * await accessService.setUserRole(userId, ['editor', 'reviewer'])\n * ```\n */\n@Request(AC_TOKENS.AccessService)\nexport class AccessService {\n constructor(\n @inject(DI_TOKENS.AuthContext)\n private readonly authContext: AuthContext,\n @inject(AUTH_SERVICE)\n private readonly authService: AuthService,\n @inject(AC_TOKENS.Options)\n private readonly options: AccessControlOptions\n ) { }\n\n /**\n * Get all roles for a user.\n *\n * Uses AuthContext for the current user (no DB hit).\n * Falls back to DB for other users.\n */\n async getUserRoles(userId: string): Promise<string[]> {\n if (userId === this.authContext.getUserId()) {\n const roles = this.authContext.getRoles()\n if (roles.length > 0) return roles\n }\n const ctx = await this.authService.auth.$context\n const user = await ctx.internalAdapter.findUserById(userId)\n return parseRoles((user as { role?: string | null } | null)?.role)\n }\n\n /**\n * Assign one or more roles to a user.\n *\n * Multiple roles are stored as a comma-separated string in `user.role`.\n */\n async setUserRole(userId: string, role: string | string[]): Promise<void> {\n const roleStr = Array.isArray(role) ? role.join(',') : role\n const ctx = await this.authService.auth.$context\n await ctx.internalAdapter.updateUser(\n userId,\n { role: roleStr } as Parameters<typeof ctx.internalAdapter.updateUser>[1]\n )\n }\n\n /**\n * Check if a user has the required permissions.\n *\n * Returns true if any of the user's roles grants all of the requested permissions.\n */\n async hasPermission(userId: string, permissions: Record<string, string[]>): Promise<boolean> {\n const roles = await this.getUserRoles(userId)\n return this.checkPermissions(roles, permissions)\n }\n\n /**\n * Get the merged permission set for a user across all their roles.\n * Useful for sending to the frontend.\n */\n async getPermissionsForUser(userId: string): Promise<Record<string, string[]>> {\n const roles = await this.getUserRoles(userId)\n return this.mergePermissions(roles)\n }\n\n /**\n * Get all roles for the currently authenticated user.\n * Reads from AuthContext — no DB hit.\n */\n getCurrentUserRoles(): string[] {\n return this.authContext.getRoles()\n }\n\n /**\n * Check if the currently authenticated user has the required permissions.\n * Reads roles from AuthContext — no DB hit.\n */\n currentUserHasPermission(permissions: Record<string, string[]>): boolean {\n const roles = this.authContext.getRoles()\n if (roles.length === 0) return false\n return this.checkPermissions(roles, permissions)\n }\n\n /**\n * Get merged permissions for the currently authenticated user.\n * Reads roles from AuthContext — no DB hit.\n */\n getCurrentUserPermissions(): Record<string, string[]> {\n const roles = this.authContext.getRoles()\n return this.mergePermissions(roles)\n }\n\n private checkPermissions(roles: string[], permissions: Record<string, string[]>): boolean {\n return roles.some(roleName => {\n const roleObj = this.options.roles[roleName]\n if (!roleObj) return false\n\n const specific: Record<string, string[]> = {}\n\n for (const [resource, actions] of Object.entries(permissions)) {\n if (actions.includes('*')) {\n // Wildcard: role must have at least one action defined for this resource\n const roleActions = (roleObj.statements as Record<string, readonly string[]>)[resource]\n if (!roleActions?.length) return false\n } else {\n specific[resource] = actions\n }\n }\n\n return Object.keys(specific).length === 0 || roleObj.authorize(specific).success\n })\n }\n\n private mergePermissions(roles: string[]): Record<string, string[]> {\n const result: Record<string, string[]> = {}\n for (const roleName of roles) {\n const roleObj = this.options.roles[roleName]\n if (!roleObj) continue\n for (const [resource, actions] of Object.entries(roleObj.statements)) {\n result[resource] ??= []\n for (const action of actions as string[]) {\n if (!result[resource].includes(action)) {\n result[resource].push(action)\n }\n }\n }\n }\n return result\n }\n}\n"],"mappings":";;;;AAsCO,IAAM,wBAAN,MAAM,sBAA4C;CAGpC;CAFnB,YACE,QAEA;EADiB,KAAA,SAAA;CACf;CAEJ,MAAM,OAAO,KAAoB,MAA2B;EAC1D,MAAM,SAAS,KAAK;EACpB,MAAM,UAAU;EAEhB,IACE,UACG,OAAO,QAAQ,UAAU,cACzB,OAAO,QAAQ,WAAW,YAE7B,QAAQ,MAAM,UAAU,QAAQ,cAAc;GAC5C,OAAO,OAAO,oBAAoB;GAClC,aAAa,OAAO,0BAA0B;EAChD,EAAE,CAAC;EAGL,MAAM,KAAK;CACb;AACF;AAxBC,wBAAA,WAAA,CAAA,UAAU,GAAA,gBAAA,GAGN,OAAO,UAAU,eAAe,EAAE,YAAY,KAAK,CAAC,CAAA,CAAA,GAAA,qBAAA;;;;;;;;;;;;AC5BzD,SAAgB,sBAAsB,UAAkD;CACtF,OAAO;EACL,IAAI;EACJ,QAAQ,EACN,MAAM,EACJ,QAAQ,EACN,MAAM;GACJ,MAAM;GACN,UAAU;GACV,OAAO;GACP,cAAc;EAChB,EACF,EACF,EACF;CACF;AACF;;;;AC3BA,MAAa,eAAe,OAAO,IAAI,sBAAsB;;AAG7D,MAAa,eAAe,OAAO,IAAI,sBAAsB;;;ACG7D,SAAS,WAAW,MAA2C;CAC7D,IAAI,CAAC,MAAM,OAAO,CAAC;CACnB,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO;AAC1D;AA8BO,IAAM,gBAAN,MAAM,cAAc;CAGN;CAEA;CAEA;CANnB,YACE,aAEA,aAEA,SAEA;EALiB,KAAA,cAAA;EAEA,KAAA,cAAA;EAEA,KAAA,UAAA;CACf;;;;;;;CAQJ,MAAM,aAAa,QAAmC;EACpD,IAAI,WAAW,KAAK,YAAY,UAAU,GAAG;GAC3C,MAAM,QAAQ,KAAK,YAAY,SAAS;GACxC,IAAI,MAAM,SAAS,GAAG,OAAO;EAC/B;EAGA,OAAO,YAAY,OADA,MADD,KAAK,YAAY,KAAK,SAAA,CACjB,gBAAgB,aAAa,MAAM,EAAA,EACG,IAAI;CACnE;;;;;;CAOA,MAAM,YAAY,QAAgB,MAAwC;EACxE,MAAM,UAAU,MAAM,QAAQ,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI;EAEvD,OAAM,MADY,KAAK,YAAY,KAAK,SAAA,CAC9B,gBAAgB,WACxB,QACA,EAAE,MAAM,QAAQ,CAClB;CACF;;;;;;CAOA,MAAM,cAAc,QAAgB,aAAyD;EAC3F,MAAM,QAAQ,MAAM,KAAK,aAAa,MAAM;EAC5C,OAAO,KAAK,iBAAiB,OAAO,WAAW;CACjD;;;;;CAMA,MAAM,sBAAsB,QAAmD;EAC7E,MAAM,QAAQ,MAAM,KAAK,aAAa,MAAM;EAC5C,OAAO,KAAK,iBAAiB,KAAK;CACpC;;;;;CAMA,sBAAgC;EAC9B,OAAO,KAAK,YAAY,SAAS;CACnC;;;;;CAMA,yBAAyB,aAAgD;EACvE,MAAM,QAAQ,KAAK,YAAY,SAAS;EACxC,IAAI,MAAM,WAAW,GAAG,OAAO;EAC/B,OAAO,KAAK,iBAAiB,OAAO,WAAW;CACjD;;;;;CAMA,4BAAsD;EACpD,MAAM,QAAQ,KAAK,YAAY,SAAS;EACxC,OAAO,KAAK,iBAAiB,KAAK;CACpC;CAEA,iBAAyB,OAAiB,aAAgD;EACxF,OAAO,MAAM,MAAK,aAAY;GAC5B,MAAM,UAAU,KAAK,QAAQ,MAAM;GACnC,IAAI,CAAC,SAAS,OAAO;GAErB,MAAM,WAAqC,CAAC;GAE5C,KAAK,MAAM,CAAC,UAAU,YAAY,OAAO,QAAQ,WAAW,GAC1D,IAAI,QAAQ,SAAS,GAAG,GAGlB;QAAA,CADiB,QAAQ,WAAiD,SAC9D,EAAE,QAAQ,OAAO;GAAA,OAEjC,SAAS,YAAY;GAIzB,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,WAAW,KAAK,QAAQ,UAAU,QAAQ,CAAC,CAAC;EAC3E,CAAC;CACH;CAEA,iBAAyB,OAA2C;EAClE,MAAM,SAAmC,CAAC;EAC1C,KAAK,MAAM,YAAY,OAAO;GAC5B,MAAM,UAAU,KAAK,QAAQ,MAAM;GACnC,IAAI,CAAC,SAAS;GACd,KAAK,MAAM,CAAC,UAAU,YAAY,OAAO,QAAQ,QAAQ,UAAU,GAAG;IACpE,OAAO,cAAc,CAAC;IACtB,KAAK,MAAM,UAAU,SACnB,IAAI,CAAC,OAAO,SAAS,CAAC,SAAS,MAAM,GACnC,OAAO,SAAS,CAAC,KAAK,MAAM;GAGlC;EACF;EACA,OAAO;CACT;AACF;;CA5HC,QAAQ,UAAU,aAAa;CAG3B,gBAAA,GAAA,OAAO,UAAU,WAAW,CAAA;CAE5B,gBAAA,GAAA,OAAO,YAAY,CAAA;CAEnB,gBAAA,GAAA,OAAO,UAAU,OAAO,CAAA"}
@@ -1,12 +1,11 @@
1
- import { t as AccessControlOptions } from "../types-DabF8LGz.mjs";
2
- import { r as AuthUser } from "../auth-context-CGVbiSX3.mjs";
1
+ import { n as AccessControlOptions, t as AuthService } from "../auth.service-Onf3JkyL.mjs";
2
+ import { r as AuthUser } from "../auth-context-C1om3Zsr.mjs";
3
3
  import { AsyncModuleOptions, DynamicModule } from "stratal/module";
4
4
  import { ApplicationError, HttpException } from "stratal/errors";
5
5
  import { Middleware, Next, RouteConfigurable, Router, RouterContext } from "stratal/router";
6
6
  import { LoggerService } from "stratal/logger";
7
7
  import { APIError } from "better-auth/api";
8
- import { Auth, BetterAuthOptions } from "better-auth";
9
-
8
+ import { BetterAuthOptions } from "better-auth";
10
9
  //#region src/context/router-context.augment.d.ts
11
10
  declare module 'stratal/router' {
12
11
  interface RouterContext {
@@ -18,7 +17,7 @@ declare module 'stratal/router' {
18
17
  */
19
18
  user(): AuthUser;
20
19
  }
21
- } //# sourceMappingURL=router-context.augment.d.ts.map
20
+ }
22
21
  //#endregion
23
22
  //#region src/auth/auth.module.d.ts
24
23
  interface AuthModuleAsyncOptions<TOptions extends BetterAuthOptions = BetterAuthOptions> extends AsyncModuleOptions<TOptions> {
@@ -34,6 +33,10 @@ declare class AuthModule implements RouteConfigurable {
34
33
  *
35
34
  * SessionVerificationMiddleware verifies the session and populates the
36
35
  * request-scoped AuthContext with the authenticated user.
36
+ *
37
+ * AccessShareMiddleware then shares the resulting roles and permissions to
38
+ * Inertia. Order matters: it reads what session verification wrote. Both
39
+ * no-op when their dependencies are absent.
37
40
  */
38
41
  configureRoutes(router: Router): void;
39
42
  /**
@@ -49,6 +52,56 @@ declare class AuthModule implements RouteConfigurable {
49
52
  static forRootAsync<TOptions extends BetterAuthOptions>(options: AuthModuleAsyncOptions<TOptions>): DynamicModule;
50
53
  }
51
54
  //#endregion
55
+ //#region src/auth/middleware/session-verification.middleware.d.ts
56
+ /**
57
+ * Session Verification Middleware
58
+ *
59
+ * Verifies user session via Better Auth and populates AuthContext with
60
+ * the authenticated user.
61
+ *
62
+ * **Responsibilities:**
63
+ * - Calls Better Auth's getSession() API
64
+ * - Populates AuthContext with the user record if the session is valid
65
+ * - Continues request chain regardless of session status
66
+ */
67
+ declare class SessionVerificationMiddleware implements Middleware {
68
+ private readonly authService;
69
+ private logger;
70
+ constructor(authService: AuthService, logger: LoggerService);
71
+ handle(ctx: RouterContext, next: Next): Promise<Response | void>;
72
+ }
73
+ //#endregion
74
+ //#region src/auth/auth.primers.d.ts
75
+ /**
76
+ * Middleware the response-cache gateway must run before resolving partitions.
77
+ *
78
+ * `ctx.user()` reads the request-scoped `AuthContext`, which
79
+ * `SessionVerificationMiddleware` populates. The gateway runs outside the
80
+ * app's middleware chain, so without this a partition resolver calling
81
+ * `ctx.user()` would throw `UserNotAuthenticatedError` on every request.
82
+ *
83
+ * Pass it alongside `gateway: { entrypoint }` — `primers` without a configured
84
+ * gateway is a boot error, because nothing would ever run the middleware
85
+ * listed here.
86
+ *
87
+ * The cost lands in the primer, not the accessor: `ctx.user()` is a memory
88
+ * read, while `SessionVerificationMiddleware` calls
89
+ * `authService.auth.api.getSession()`. On a cache **miss** that call happens
90
+ * twice — once in the gateway to resolve the partition, once in the app's own
91
+ * chain, since each runs in its own request scope. On a **hit** the app never
92
+ * runs, so only the gateway's single call is paid.
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * ResponseCacheModule.forRoot({
97
+ * gateway: { entrypoint: 'Cached' },
98
+ * primers: AUTH_GATEWAY_PRIMERS,
99
+ * partitions: { user: (ctx) => ctx.user().id },
100
+ * })
101
+ * ```
102
+ */
103
+ declare const AUTH_GATEWAY_PRIMERS: readonly [typeof SessionVerificationMiddleware];
104
+ //#endregion
52
105
  //#region src/auth/auth.tokens.d.ts
53
106
  /** Token for AuthService - core authentication service */
54
107
  declare const AUTH_SERVICE: unique symbol;
@@ -183,58 +236,6 @@ declare class TokenRequiredError extends HttpException {
183
236
  constructor();
184
237
  }
185
238
  //#endregion
186
- //#region src/auth/services/auth.service.d.ts
187
- /**
188
- * AuthService
189
- *
190
- * Base authentication service using Better Auth.
191
- * Configured via AuthModule.forRootAsync() from the application layer.
192
- *
193
- * **Extensibility:**
194
- * Extend this class to add custom methods. Subclasses inherit
195
- * `@Request(AUTH_SERVICE)` scope automatically — no decorator needed.
196
- *
197
- * @example
198
- * ```typescript
199
- * @Request(AUTH_SERVICE)
200
- * export class AppAuthService extends AuthService<AuthOptions> {
201
- * async signInMagicLink(email: string) {
202
- * return wrapBetterAuth(async () => {
203
- * return this.auth.api.signInMagicLink({ body: { email }, headers: new Headers() })
204
- * })
205
- * }
206
- * }
207
- * ```
208
- */
209
- declare class AuthService<TOptions extends BetterAuthOptions = BetterAuthOptions> {
210
- protected readonly options: TOptions;
211
- private _authInstance?;
212
- constructor(options: TOptions);
213
- /**
214
- * Get the Better Auth instance.
215
- */
216
- get auth(): Auth<TOptions>;
217
- }
218
- //#endregion
219
- //#region src/auth/middleware/session-verification.middleware.d.ts
220
- /**
221
- * Session Verification Middleware
222
- *
223
- * Verifies user session via Better Auth and populates AuthContext with
224
- * the authenticated user.
225
- *
226
- * **Responsibilities:**
227
- * - Calls Better Auth's getSession() API
228
- * - Populates AuthContext with the user record if the session is valid
229
- * - Continues request chain regardless of session status
230
- */
231
- declare class SessionVerificationMiddleware implements Middleware {
232
- private readonly authService;
233
- private logger;
234
- constructor(authService: AuthService, logger: LoggerService);
235
- handle(ctx: RouterContext, next: Next): Promise<void>;
236
- }
237
- //#endregion
238
239
  //#region src/auth/utils/auth-helpers.d.ts
239
240
  /**
240
241
  * Get shared Better Auth error handler configuration.
@@ -258,5 +259,5 @@ declare function mapBetterAuthError(error: APIError): ApplicationError;
258
259
  */
259
260
  declare function isAPIError(error: unknown): error is APIError;
260
261
  //#endregion
261
- export { AUTH_OPTIONS, AUTH_SERVICE, AccountAlreadyExistsError, AccountNotFoundError, AuthModule, AuthModuleAsyncOptions, AuthService, AuthValidationFailedError, CannotUnlinkLastAccountError, CredentialAccountNotFoundError, EmailAlreadyVerifiedError, EmailCannotBeUpdatedError, EmailMismatchError, EmailNotVerifiedError, FreshSessionRequiredError, IdTokenNotSupportedError, InvalidCallbackUrlError, InvalidCredentialsError, InvalidEmailError, InvalidOriginError, InvalidPasswordError, InvalidTokenError, OrganizationConflictError, OrganizationInvitationNotFoundError, OrganizationInvitationRecipientMismatchError, OrganizationLimitReachedError, OrganizationMemberNotFoundError, OrganizationMembershipError, OrganizationNotFoundError, OrganizationPermissionDeniedError, OrganizationRoleNotFoundError, OrganizationTeamNotFoundError, PasswordTooLongError, PasswordTooShortError, ProviderNotFoundError, SessionExpiredError, SessionVerificationMiddleware, SocialAccountLinkedError, TokenExpiredError, TokenRequiredError, UserAlreadyHasPasswordError, UserEmailNotFoundError, UserNotFoundError, getErrorHandlerConfig, isAPIError, mapBetterAuthError, wrapBetterAuth };
262
+ export { AUTH_GATEWAY_PRIMERS, AUTH_OPTIONS, AUTH_SERVICE, AccountAlreadyExistsError, AccountNotFoundError, AuthModule, AuthModuleAsyncOptions, AuthService, AuthValidationFailedError, CannotUnlinkLastAccountError, CredentialAccountNotFoundError, EmailAlreadyVerifiedError, EmailCannotBeUpdatedError, EmailMismatchError, EmailNotVerifiedError, FreshSessionRequiredError, IdTokenNotSupportedError, InvalidCallbackUrlError, InvalidCredentialsError, InvalidEmailError, InvalidOriginError, InvalidPasswordError, InvalidTokenError, OrganizationConflictError, OrganizationInvitationNotFoundError, OrganizationInvitationRecipientMismatchError, OrganizationLimitReachedError, OrganizationMemberNotFoundError, OrganizationMembershipError, OrganizationNotFoundError, OrganizationPermissionDeniedError, OrganizationRoleNotFoundError, OrganizationTeamNotFoundError, PasswordTooLongError, PasswordTooShortError, ProviderNotFoundError, SessionExpiredError, SessionVerificationMiddleware, SocialAccountLinkedError, TokenExpiredError, TokenRequiredError, UserAlreadyHasPasswordError, UserEmailNotFoundError, UserNotFoundError, getErrorHandlerConfig, isAPIError, mapBetterAuthError, wrapBetterAuth };
262
263
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/context/router-context.augment.ts","../../src/auth/auth.module.ts","../../src/auth/auth.tokens.ts","../../src/auth/errors/auth-errors.ts","../../src/auth/errors/invalid-token.error.ts","../../src/auth/errors/organization-errors.ts","../../src/auth/errors/token-required.error.ts","../../src/auth/services/auth.service.ts","../../src/auth/middleware/session-verification.middleware.ts","../../src/auth/utils/auth-helpers.ts","../../src/auth/utils/better-auth-error-handler.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/context/router-context.augment.ts","../../src/auth/auth.module.ts","../../src/auth/middleware/session-verification.middleware.ts","../../src/auth/auth.primers.ts","../../src/auth/auth.tokens.ts","../../src/auth/errors/auth-errors.ts","../../src/auth/errors/invalid-token.error.ts","../../src/auth/errors/organization-errors.ts","../../src/auth/errors/token-required.error.ts","../../src/auth/utils/auth-helpers.ts","../../src/auth/utils/better-auth-error-handler.ts"],"mappings":";;;;;;;;;;YAaY;;;;;;;IAOR,QAAQ;;;;;UCsDK,uBAAuB,iBAAiB,oBAAoB,2BACnE,mBAAmB;;;;;EAK3B,gBAAgB;;cAML,sBAAsB;;;;;;;;;;;EAWjC,gBAAgB,QAAQ;;;;;;;;;;;SAejB,aAAa,iBAAiB,mBACnC,SAAS,uBAAuB,YAC/B;;;;;;;;;;;;;;;cC/FQ,yCAAyC;mBAGjC;UAC4B;EAH/C,YAEmB,aAAa,aACe,QAAQ;EAGjD,OAAO,KAAK,eAAe,MAAM,OAAO,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCI3C,uCAAoB;;;;cC7BpB;;cAGA;;;cCFA,0BAA0B;WACT;EAA5B,YAA4B;;cAKjB,gCAAgC;EAC3C;;cAGW,6BAA6B;EACxC;;cAGW,0BAA0B;WACT;EAA5B,YAA4B;;cAKjB,4BAA4B;EACvC;;cAGW,kCAAkC;EAC7C;;cAGW,8BAA8B;WACb;EAA5B,YAA4B;;cAKjB,8BAA8B;WACb;EAA5B,YAA4B;;cAKjB,6BAA6B;WACZ;EAA5B,YAA4B;;cAKjB,kCAAkC;WACjB;EAA5B,YAA4B;;cAKjB,iCAAiC;WAChB;EAA5B,YAA4B;;cAKjB,qCAAqC;EAChD;;cAGW,8BAA8B;WACb;EAA5B,YAA4B;;cAKjB,+BAA+B;EAC1C;;cAGW,6BAA6B;EACxC;;cAGW,uCAAuC;EAClD;;cAGW,oCAAoC;EAC/C;;cAGW,kCAAkC;WACjB;EAA5B,YAA4B;;cAKjB,iCAAiC;EAC5C;;cAGW,0BAA0B;EACrC;;cAGW,gCAAgC;EAC3C;;cAGW,2BAA2B;EACtC;;cAGW,kCAAkC;EAC7C;;cAGW,kCAAkC;EAC7C;;cAGW,2BAA2B;EACtC;;;;cCnHW,0BAA0B;EACrC;;;;cCDW,kCAAkC;EAC7C;;cAEW,wCAAwC;EACnD;;cAEW,4CAA4C;EACvD;;cAEW,0CAA0C;EACrD;;cAEW,qDAAqD;EAChE;;cAEW,kCAAkC;EAC7C;;cAEW,sCAAsC;EACjD;;cAEW,oCAAoC;EAC/C;;cAEW,sCAAsC;EACjD;;cAEW,sCAAsC;EACjD;;;;cC5BW,2BAA2B;EACtC;;;;;;;;iBCIc,yBAAyB;;;;cAe5B,iBAAwB,GAAC,UAAY,QAAQ,OAAK,QAAQ;;;;;;iBCuBvD,mBAAmB,OAAO,WAAW;;;;;;iBAkNrC,WAAW,iBAAiB,SAAS"}
@@ -1,7 +1,7 @@
1
- import { n as createStratalAcPlugin, t as AccessService } from "../access.service-BmDhE-re.mjs";
2
- import { n as AC_TOKENS, t as __decorateParam } from "../decorateParam-DwV9LSPl.mjs";
3
- import { t as __decorate } from "../decorate-B7nr7eBl.mjs";
4
- import { t as AuthContext } from "../auth-context-C8NBfiMa.mjs";
1
+ import { n as AC_TOKENS, t as __decorateParam } from "../decorateParam-DQ95ttaa.mjs";
2
+ import { t as __decorate } from "../decorate-ZDdbRmsv.mjs";
3
+ import { a as AccessShareMiddleware, i as createStratalAcPlugin, n as AUTH_OPTIONS, r as AUTH_SERVICE, t as AccessService } from "../access.service-rsEreT-4.mjs";
4
+ import { t as AuthContext } from "../auth-context-CE_-TV27.mjs";
5
5
  import { CONTAINER_TOKEN, DI_TOKENS, Request, Transient, inject } from "stratal/di";
6
6
  import { Module } from "stratal/module";
7
7
  import { RATE_LIMITER_TOKENS, RateLimiterRegistry } from "stratal/rate-limiter";
@@ -23,12 +23,6 @@ RouterContext.macro("user", function() {
23
23
  return this.getContainer().resolve(DI_TOKENS.AuthContext).requireUser();
24
24
  });
25
25
  //#endregion
26
- //#region src/auth/auth.tokens.ts
27
- /** Token for AuthService - core authentication service */
28
- const AUTH_SERVICE = Symbol.for("stratal:auth:service");
29
- /** Token for Better Auth options configuration */
30
- const AUTH_OPTIONS = Symbol.for("stratal:auth:options");
31
- //#endregion
32
26
  //#region src/auth/middleware/session-verification.middleware.ts
33
27
  let SessionVerificationMiddleware = class SessionVerificationMiddleware {
34
28
  authService;
@@ -471,9 +465,14 @@ let AuthModule = _AuthModule = class AuthModule {
471
465
  *
472
466
  * SessionVerificationMiddleware verifies the session and populates the
473
467
  * request-scoped AuthContext with the authenticated user.
468
+ *
469
+ * AccessShareMiddleware then shares the resulting roles and permissions to
470
+ * Inertia. Order matters: it reads what session verification wrote. Both
471
+ * no-op when their dependencies are absent.
474
472
  */
475
473
  configureRoutes(router) {
476
474
  router.use(SessionVerificationMiddleware);
475
+ router.use(AccessShareMiddleware);
477
476
  }
478
477
  /**
479
478
  * Configure AuthModule with async options factory.
@@ -538,6 +537,37 @@ let AuthModule = _AuthModule = class AuthModule {
538
537
  };
539
538
  AuthModule = _AuthModule = __decorate([Module({ providers: [AuthContext] })], AuthModule);
540
539
  //#endregion
541
- export { AUTH_OPTIONS, AUTH_SERVICE, AccountAlreadyExistsError, AccountNotFoundError, AuthModule, AuthService, AuthValidationFailedError, CannotUnlinkLastAccountError, CredentialAccountNotFoundError, EmailAlreadyVerifiedError, EmailCannotBeUpdatedError, EmailMismatchError, EmailNotVerifiedError, FreshSessionRequiredError, IdTokenNotSupportedError, InvalidCallbackUrlError, InvalidCredentialsError, InvalidEmailError, InvalidOriginError, InvalidPasswordError, InvalidTokenError, OrganizationConflictError, OrganizationInvitationNotFoundError, OrganizationInvitationRecipientMismatchError, OrganizationLimitReachedError, OrganizationMemberNotFoundError, OrganizationMembershipError, OrganizationNotFoundError, OrganizationPermissionDeniedError, OrganizationRoleNotFoundError, OrganizationTeamNotFoundError, PasswordTooLongError, PasswordTooShortError, ProviderNotFoundError, SessionExpiredError, SessionVerificationMiddleware, SocialAccountLinkedError, TokenExpiredError, TokenRequiredError, UserAlreadyHasPasswordError, UserEmailNotFoundError, UserNotFoundError, getErrorHandlerConfig, isAPIError, mapBetterAuthError, wrapBetterAuth };
540
+ //#region src/auth/auth.primers.ts
541
+ /**
542
+ * Middleware the response-cache gateway must run before resolving partitions.
543
+ *
544
+ * `ctx.user()` reads the request-scoped `AuthContext`, which
545
+ * `SessionVerificationMiddleware` populates. The gateway runs outside the
546
+ * app's middleware chain, so without this a partition resolver calling
547
+ * `ctx.user()` would throw `UserNotAuthenticatedError` on every request.
548
+ *
549
+ * Pass it alongside `gateway: { entrypoint }` — `primers` without a configured
550
+ * gateway is a boot error, because nothing would ever run the middleware
551
+ * listed here.
552
+ *
553
+ * The cost lands in the primer, not the accessor: `ctx.user()` is a memory
554
+ * read, while `SessionVerificationMiddleware` calls
555
+ * `authService.auth.api.getSession()`. On a cache **miss** that call happens
556
+ * twice — once in the gateway to resolve the partition, once in the app's own
557
+ * chain, since each runs in its own request scope. On a **hit** the app never
558
+ * runs, so only the gateway's single call is paid.
559
+ *
560
+ * @example
561
+ * ```typescript
562
+ * ResponseCacheModule.forRoot({
563
+ * gateway: { entrypoint: 'Cached' },
564
+ * primers: AUTH_GATEWAY_PRIMERS,
565
+ * partitions: { user: (ctx) => ctx.user().id },
566
+ * })
567
+ * ```
568
+ */
569
+ const AUTH_GATEWAY_PRIMERS = [SessionVerificationMiddleware];
570
+ //#endregion
571
+ export { AUTH_GATEWAY_PRIMERS, AUTH_OPTIONS, AUTH_SERVICE, AccountAlreadyExistsError, AccountNotFoundError, AuthModule, AuthService, AuthValidationFailedError, CannotUnlinkLastAccountError, CredentialAccountNotFoundError, EmailAlreadyVerifiedError, EmailCannotBeUpdatedError, EmailMismatchError, EmailNotVerifiedError, FreshSessionRequiredError, IdTokenNotSupportedError, InvalidCallbackUrlError, InvalidCredentialsError, InvalidEmailError, InvalidOriginError, InvalidPasswordError, InvalidTokenError, OrganizationConflictError, OrganizationInvitationNotFoundError, OrganizationInvitationRecipientMismatchError, OrganizationLimitReachedError, OrganizationMemberNotFoundError, OrganizationMembershipError, OrganizationNotFoundError, OrganizationPermissionDeniedError, OrganizationRoleNotFoundError, OrganizationTeamNotFoundError, PasswordTooLongError, PasswordTooShortError, ProviderNotFoundError, SessionExpiredError, SessionVerificationMiddleware, SocialAccountLinkedError, TokenExpiredError, TokenRequiredError, UserAlreadyHasPasswordError, UserEmailNotFoundError, UserNotFoundError, getErrorHandlerConfig, isAPIError, mapBetterAuthError, wrapBetterAuth };
542
572
 
543
573
  //# sourceMappingURL=index.mjs.map