@stratal/framework 0.0.21 → 0.0.23

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 (51) hide show
  1. package/dist/access-control/index.d.mts +8 -14
  2. package/dist/access-control/index.d.mts.map +1 -1
  3. package/dist/access-control/index.mjs +3 -3
  4. package/dist/access-control/index.mjs.map +1 -1
  5. package/dist/{access.service-Cb99esfz.mjs → access.service-BmDhE-re.mjs} +6 -12
  6. package/dist/access.service-BmDhE-re.mjs.map +1 -0
  7. package/dist/auth/index.d.mts +80 -151
  8. package/dist/auth/index.d.mts.map +1 -1
  9. package/dist/auth/index.mjs +137 -215
  10. package/dist/auth/index.mjs.map +1 -1
  11. package/dist/{auth-context-HLwuOl51.mjs → auth-context-C8NBfiMa.mjs} +7 -6
  12. package/dist/auth-context-C8NBfiMa.mjs.map +1 -0
  13. package/dist/{auth-context-DXSTlnQH.d.mts → auth-context-CGVbiSX3.d.mts} +1 -1
  14. package/dist/auth-context-CGVbiSX3.d.mts.map +1 -0
  15. package/dist/context/index.d.mts +5 -10
  16. package/dist/context/index.d.mts.map +1 -1
  17. package/dist/context/index.mjs +3 -3
  18. package/dist/database/index.d.mts +3 -3
  19. package/dist/database/index.mjs +78 -181
  20. package/dist/database/index.mjs.map +1 -1
  21. package/dist/{decorate-DViXs-0l.mjs → decorate-B7nr7eBl.mjs} +1 -1
  22. package/dist/{decorateParam-C_dJ_dIO.mjs → decorateParam-DwV9LSPl.mjs} +2 -2
  23. package/dist/{decorateParam-C_dJ_dIO.mjs.map → decorateParam-DwV9LSPl.mjs.map} +1 -1
  24. package/dist/errors-BvJSaUTW.mjs +18 -0
  25. package/dist/errors-BvJSaUTW.mjs.map +1 -0
  26. package/dist/factory/index.d.mts +1 -1
  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.map +1 -1
  30. package/dist/guards/index.mjs +9 -16
  31. package/dist/guards/index.mjs.map +1 -1
  32. package/dist/{index-CCDPF-1Y.d.mts → index-jILx9QXw.d.mts} +12 -94
  33. package/dist/index-jILx9QXw.d.mts.map +1 -0
  34. package/dist/index.d.mts +2 -2
  35. package/dist/insufficient-permissions.error-DeEyZRgy.mjs +16 -0
  36. package/dist/insufficient-permissions.error-DeEyZRgy.mjs.map +1 -0
  37. package/dist/{types-BZlcRR2M.d.mts → types-CWZ9q74G.d.mts} +1 -1
  38. package/dist/types-CWZ9q74G.d.mts.map +1 -0
  39. package/dist/{types-BLyu9dAd.d.mts → types-DabF8LGz.d.mts} +1 -1
  40. package/dist/{types-BLyu9dAd.d.mts.map → types-DabF8LGz.d.mts.map} +1 -1
  41. package/package.json +27 -24
  42. package/dist/access.service-Cb99esfz.mjs.map +0 -1
  43. package/dist/auth-context-DXSTlnQH.d.mts.map +0 -1
  44. package/dist/auth-context-HLwuOl51.mjs.map +0 -1
  45. package/dist/decorateMetadata-D5WUsc6Y.mjs +0 -6
  46. package/dist/errors-B1vVXc1T.mjs +0 -25
  47. package/dist/errors-B1vVXc1T.mjs.map +0 -1
  48. package/dist/index-CCDPF-1Y.d.mts.map +0 -1
  49. package/dist/insufficient-permissions.error-CRnOHYvq.mjs +0 -23
  50. package/dist/insufficient-permissions.error-CRnOHYvq.mjs.map +0 -1
  51. package/dist/types-BZlcRR2M.d.mts.map +0 -1
@@ -1,9 +1,9 @@
1
- import { n as RolePermissions, t as AccessControlOptions } from "../types-BLyu9dAd.mjs";
2
- import { M as DatabaseService } from "../index-CCDPF-1Y.mjs";
3
- import { t as AuthContext } from "../auth-context-DXSTlnQH.mjs";
4
- import { ApplicationError } from "stratal/errors";
5
- import { BetterAuthPlugin } from "better-auth";
1
+ import { n as RolePermissions, t as AccessControlOptions } from "../types-DabF8LGz.mjs";
2
+ import { O as DatabaseService } from "../index-jILx9QXw.mjs";
3
+ import { t as AuthContext } from "../auth-context-CGVbiSX3.mjs";
4
+ import { HttpException } from "stratal/errors";
6
5
  import { AccessControl, Role, Statements } from "better-auth/plugins/access";
6
+ import { BetterAuthPlugin } from "better-auth";
7
7
 
8
8
  //#region src/access-control/tokens.d.ts
9
9
  declare const AC_TOKENS: {
@@ -164,15 +164,9 @@ declare class AccessService {
164
164
  }
165
165
  //#endregion
166
166
  //#region src/access-control/errors/insufficient-permissions.error.d.ts
167
- /**
168
- * InsufficientPermissionsError
169
- *
170
- * Thrown when a user attempts to perform an action without the required permissions.
171
- * Used by AuthGuard after an authorization check fails.
172
- *
173
- * HTTP Status: 403 Forbidden
174
- */
175
- declare class InsufficientPermissionsError extends ApplicationError {
167
+ declare class InsufficientPermissionsError extends HttpException {
168
+ readonly requiredPermissions: string;
169
+ readonly userId?: string;
176
170
  constructor(requiredPermissions: string | string[], userId?: string);
177
171
  }
178
172
  //#endregion
@@ -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,GAAA,CAC9C,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,6BAAA,CAEvB,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,gBAAA;;;;;;;;AHZvE;;;;;;;;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;;;;;EGoCjB,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,CAAA;EFpFyC;;;;EE4FzC,wBAAA,CAAyB,WAAA,EAAa,MAAA;EF1FpB;;;;EEoGlB,yBAAA,CAAA,GAA6B,MAAA;EAAA,QAKrB,gBAAA;EAAA,QAqBA,gBAAA;AAAA;;;;;;;;;;AJnJV;cKUa,4BAAA,SAAqC,gBAAA;cACpC,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/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,6 +1,6 @@
1
- import { n as createStratalAcPlugin, t as AccessService } from "../access.service-Cb99esfz.mjs";
2
- import { n as AC_TOKENS } from "../decorateParam-C_dJ_dIO.mjs";
3
- import { t as InsufficientPermissionsError } from "../insufficient-permissions.error-CRnOHYvq.mjs";
1
+ import { n as createStratalAcPlugin, t as AccessService } from "../access.service-BmDhE-re.mjs";
2
+ import { n as AC_TOKENS } from "../decorateParam-DwV9LSPl.mjs";
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
6
6
  /**
@@ -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,UAAU;CAIvC,OAAO;EAAE;EAAI,OAHC,OAAO,YACnB,OAAO,QAAQ,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,WAAW,CAAC,MAAM,GAAG,QAAQ,MAA+B,CAAC,CAAC,CAEvF;EAAE;;;;;;;;;;;;;;;;;;;;;ACEtB,SAAgB,WAId,IACA,QACA,OACwC;CACxC,MAAM,SAAmC,EAAE;CAE3C,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,OAAO,WAAW,EAC5D,OAAO,OAAO,CAAC,GAAI,QAAqB;CAG1C,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,MAAM,EAAE;EAClD,IAAI,CAAC,SAAS;EACd,IAAI,OAAO,QACT,OAAO,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,OAAO,MAAM,GAAG,QAAQ,CAAC,CAAC;OAExD,OAAO,OAAO,CAAC,GAAG,QAAQ;;CAI9B,OAAO,GAAG,QAAQ,OAAO"}
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,7 +1,6 @@
1
- import { n as AC_TOKENS, t as __decorateParam } from "./decorateParam-C_dJ_dIO.mjs";
2
- import { t as __decorateMetadata } from "./decorateMetadata-D5WUsc6Y.mjs";
3
- import { t as __decorate } from "./decorate-DViXs-0l.mjs";
4
- import { DI_TOKENS, Transient, inject } from "stratal/di";
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";
5
4
  //#region src/access-control/plugin.ts
6
5
  /**
7
6
  * Creates the Stratal access control Better Auth plugin.
@@ -132,17 +131,12 @@ let AccessService = class AccessService {
132
131
  }
133
132
  };
134
133
  AccessService = __decorate([
135
- Transient(AC_TOKENS.AccessService),
134
+ Request(AC_TOKENS.AccessService),
136
135
  __decorateParam(0, inject(DI_TOKENS.AuthContext)),
137
136
  __decorateParam(1, inject(DI_TOKENS.Database)),
138
- __decorateParam(2, inject(AC_TOKENS.Options)),
139
- __decorateMetadata("design:paramtypes", [
140
- Object,
141
- Object,
142
- Object
143
- ])
137
+ __decorateParam(2, inject(AC_TOKENS.Options))
144
138
  ], AccessService);
145
139
  //#endregion
146
140
  export { createStratalAcPlugin as n, AccessService as t };
147
141
 
148
- //# sourceMappingURL=access.service-Cb99esfz.mjs.map
142
+ //# sourceMappingURL=access.service-BmDhE-re.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.service-BmDhE-re.mjs","names":[],"sources":["../src/access-control/plugin.ts","../src/access-control/services/access.service.ts"],"sourcesContent":["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","import type { DatabaseService } from '@stratal/framework/database'\nimport { DI_TOKENS, inject, Request } from 'stratal/di'\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(DI_TOKENS.Database)\n private readonly db: DatabaseService,\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 user = await (this.db).user.findUnique({\n where: { id: userId },\n select: { role: true },\n })\n return parseRoles(user?.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 await this.db.user.update({\n where: { id: userId },\n data: { role: roleStr },\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":"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"}
@@ -1,11 +1,25 @@
1
- import { t as AccessControlOptions } from "../types-BLyu9dAd.mjs";
1
+ import { t as AccessControlOptions } from "../types-DabF8LGz.mjs";
2
+ import { r as AuthUser } from "../auth-context-CGVbiSX3.mjs";
2
3
  import { AsyncModuleOptions, DynamicModule } from "stratal/module";
3
- import { ApplicationError } from "stratal/errors";
4
+ import { ApplicationError, HttpException } from "stratal/errors";
5
+ import { Middleware, Next, RouteConfigurable, Router, RouterContext } from "stratal/router";
4
6
  import { LoggerService } from "stratal/logger";
5
- import { Auth, BetterAuthOptions } from "better-auth";
6
7
  import { APIError } from "better-auth/api";
7
- import { Middleware, Next, RouteConfigurable, Router, RouterContext } from "stratal/router";
8
+ import { Auth, BetterAuthOptions } from "better-auth";
8
9
 
10
+ //#region src/context/router-context.augment.d.ts
11
+ declare module 'stratal/router' {
12
+ interface RouterContext {
13
+ /**
14
+ * The authenticated user for the current request.
15
+ *
16
+ * Throws `UserNotAuthenticatedError` if the request is unauthenticated.
17
+ * Provided by `@stratal/framework`'s `AuthModule` via {@link AuthContext}.
18
+ */
19
+ user(): AuthUser;
20
+ }
21
+ } //# sourceMappingURL=router-context.augment.d.ts.map
22
+ //#endregion
9
23
  //#region src/auth/auth.module.d.ts
10
24
  interface AuthModuleAsyncOptions<TOptions extends BetterAuthOptions = BetterAuthOptions> extends AsyncModuleOptions<TOptions> {
11
25
  /**
@@ -18,9 +32,8 @@ declare class AuthModule implements RouteConfigurable {
18
32
  /**
19
33
  * Configure auth middleware globally.
20
34
  *
21
- * Registers middlewares in order:
22
- * 1. AuthContextMiddleware - Creates and registers AuthContext in request container
23
- * 2. SessionVerificationMiddleware - Verifies session and populates AuthContext with userId + role
35
+ * SessionVerificationMiddleware verifies the session and populates the
36
+ * request-scoped AuthContext with the authenticated user.
24
37
  */
25
38
  configureRoutes(router: Router): void;
26
39
  /**
@@ -43,215 +56,130 @@ declare const AUTH_SERVICE: unique symbol;
43
56
  declare const AUTH_OPTIONS: unique symbol;
44
57
  //#endregion
45
58
  //#region src/auth/errors/auth-errors.d.ts
46
- declare class UserNotFoundError extends ApplicationError {
47
- constructor(email?: string);
59
+ declare class UserNotFoundError extends HttpException {
60
+ readonly email?: string | undefined;
61
+ constructor(email?: string | undefined);
48
62
  }
49
- declare class InvalidCredentialsError extends ApplicationError {
63
+ declare class InvalidCredentialsError extends HttpException {
50
64
  constructor();
51
65
  }
52
- declare class InvalidPasswordError extends ApplicationError {
66
+ declare class InvalidPasswordError extends HttpException {
53
67
  constructor();
54
68
  }
55
- declare class InvalidEmailError extends ApplicationError {
56
- constructor(email?: string);
69
+ declare class InvalidEmailError extends HttpException {
70
+ readonly email?: string | undefined;
71
+ constructor(email?: string | undefined);
57
72
  }
58
- declare class SessionExpiredError extends ApplicationError {
73
+ declare class SessionExpiredError extends HttpException {
59
74
  constructor();
60
75
  }
61
- declare class EmailNotVerifiedError extends ApplicationError {
62
- constructor(email?: string);
76
+ declare class EmailNotVerifiedError extends HttpException {
77
+ readonly email?: string | undefined;
78
+ constructor(email?: string | undefined);
63
79
  }
64
- declare class PasswordTooShortError extends ApplicationError {
65
- constructor(minLength: number);
80
+ declare class PasswordTooShortError extends HttpException {
81
+ readonly minLength?: number | undefined;
82
+ constructor(minLength?: number | undefined);
66
83
  }
67
- declare class PasswordTooLongError extends ApplicationError {
68
- constructor(maxLength: number);
84
+ declare class PasswordTooLongError extends HttpException {
85
+ readonly maxLength?: number | undefined;
86
+ constructor(maxLength?: number | undefined);
69
87
  }
70
- declare class AccountAlreadyExistsError extends ApplicationError {
71
- constructor(email?: string);
88
+ declare class AccountAlreadyExistsError extends HttpException {
89
+ readonly email?: string | undefined;
90
+ constructor(email?: string | undefined);
72
91
  }
73
- declare class FailedToCreateUserError extends ApplicationError {
74
- constructor(reason?: string);
92
+ declare class SocialAccountLinkedError extends HttpException {
93
+ readonly provider?: string | undefined;
94
+ constructor(provider?: string | undefined);
75
95
  }
76
- declare class FailedToCreateSessionError extends ApplicationError {
77
- constructor(reason?: string);
78
- }
79
- declare class FailedToUpdateUserError extends ApplicationError {
80
- constructor(reason?: string);
81
- }
82
- declare class SocialAccountLinkedError extends ApplicationError {
83
- constructor(provider?: string);
84
- }
85
- declare class CannotUnlinkLastAccountError extends ApplicationError {
96
+ declare class CannotUnlinkLastAccountError extends HttpException {
86
97
  constructor();
87
98
  }
88
- declare class ProviderNotFoundError extends ApplicationError {
89
- constructor(provider?: string);
99
+ declare class ProviderNotFoundError extends HttpException {
100
+ readonly provider?: string | undefined;
101
+ constructor(provider?: string | undefined);
90
102
  }
91
- declare class UserEmailNotFoundError extends ApplicationError {
103
+ declare class UserEmailNotFoundError extends HttpException {
92
104
  constructor();
93
105
  }
94
- declare class AccountNotFoundError extends ApplicationError {
106
+ declare class AccountNotFoundError extends HttpException {
95
107
  constructor();
96
108
  }
97
- declare class CredentialAccountNotFoundError extends ApplicationError {
109
+ declare class CredentialAccountNotFoundError extends HttpException {
98
110
  constructor();
99
111
  }
100
- declare class UserAlreadyHasPasswordError extends ApplicationError {
112
+ declare class UserAlreadyHasPasswordError extends HttpException {
101
113
  constructor();
102
114
  }
103
- declare class EmailCannotBeUpdatedError extends ApplicationError {
104
- constructor(reason?: string);
115
+ declare class EmailCannotBeUpdatedError extends HttpException {
116
+ readonly reason?: string | undefined;
117
+ constructor(reason?: string | undefined);
105
118
  }
106
- declare class FailedToGetSessionError extends ApplicationError {
107
- constructor(reason?: string);
108
- }
109
- declare class FailedToGetUserInfoError extends ApplicationError {
110
- constructor(reason?: string);
111
- }
112
- declare class IdTokenNotSupportedError extends ApplicationError {
119
+ declare class IdTokenNotSupportedError extends HttpException {
113
120
  constructor();
114
121
  }
115
- declare class TokenExpiredError extends ApplicationError {
122
+ declare class TokenExpiredError extends HttpException {
116
123
  constructor();
117
124
  }
118
- declare class InvalidCallbackUrlError extends ApplicationError {
125
+ declare class InvalidCallbackUrlError extends HttpException {
119
126
  constructor();
120
127
  }
121
- declare class InvalidOriginError extends ApplicationError {
128
+ declare class InvalidOriginError extends HttpException {
122
129
  constructor();
123
130
  }
124
- declare class AuthValidationFailedError extends ApplicationError {
131
+ declare class AuthValidationFailedError extends HttpException {
125
132
  constructor();
126
133
  }
127
- declare class EmailAlreadyVerifiedError extends ApplicationError {
134
+ declare class EmailAlreadyVerifiedError extends HttpException {
128
135
  constructor();
129
136
  }
130
- declare class EmailMismatchError extends ApplicationError {
137
+ declare class EmailMismatchError extends HttpException {
131
138
  constructor();
132
139
  }
133
- declare class BetterAuthUnknownError extends ApplicationError {
134
- constructor(errorCode?: string);
135
- }
136
140
  //#endregion
137
141
  //#region src/auth/errors/invalid-token.error.d.ts
138
- declare class InvalidTokenError extends ApplicationError {
142
+ declare class InvalidTokenError extends HttpException {
139
143
  constructor();
140
144
  }
141
145
  //#endregion
142
146
  //#region src/auth/errors/organization-errors.d.ts
143
- declare class OrganizationNotFoundError extends ApplicationError {
147
+ declare class OrganizationNotFoundError extends HttpException {
144
148
  constructor();
145
149
  }
146
- declare class OrganizationMemberNotFoundError extends ApplicationError {
150
+ declare class OrganizationMemberNotFoundError extends HttpException {
147
151
  constructor();
148
152
  }
149
- declare class OrganizationInvitationNotFoundError extends ApplicationError {
153
+ declare class OrganizationInvitationNotFoundError extends HttpException {
150
154
  constructor();
151
155
  }
152
- declare class OrganizationPermissionDeniedError extends ApplicationError {
156
+ declare class OrganizationPermissionDeniedError extends HttpException {
153
157
  constructor();
154
158
  }
155
- declare class OrganizationInvitationRecipientMismatchError extends ApplicationError {
159
+ declare class OrganizationInvitationRecipientMismatchError extends HttpException {
156
160
  constructor();
157
161
  }
158
- declare class OrganizationConflictError extends ApplicationError {
162
+ declare class OrganizationConflictError extends HttpException {
159
163
  constructor();
160
164
  }
161
- declare class OrganizationLimitReachedError extends ApplicationError {
165
+ declare class OrganizationLimitReachedError extends HttpException {
162
166
  constructor();
163
167
  }
164
- declare class OrganizationMembershipError extends ApplicationError {
168
+ declare class OrganizationMembershipError extends HttpException {
165
169
  constructor();
166
170
  }
167
- declare class OrganizationTeamNotFoundError extends ApplicationError {
171
+ declare class OrganizationTeamNotFoundError extends HttpException {
168
172
  constructor();
169
173
  }
170
- declare class OrganizationRoleNotFoundError extends ApplicationError {
174
+ declare class OrganizationRoleNotFoundError extends HttpException {
171
175
  constructor();
172
176
  }
173
177
  //#endregion
174
178
  //#region src/auth/errors/token-required.error.d.ts
175
- declare class TokenRequiredError extends ApplicationError {
179
+ declare class TokenRequiredError extends HttpException {
176
180
  constructor();
177
181
  }
178
182
  //#endregion
179
- //#region src/auth/errors/verification-failed.error.d.ts
180
- declare class VerificationFailedError extends ApplicationError {
181
- constructor();
182
- }
183
- //#endregion
184
- //#region src/auth/i18n/en.d.ts
185
- declare const authMessages: {
186
- readonly en: {
187
- readonly auth: {
188
- readonly errors: {
189
- readonly tokenRequired: "Verification token is required";
190
- readonly invalidToken: "Invalid or expired verification token";
191
- readonly verificationFailed: "Verification failed. Please try again.";
192
- readonly userNotFound: "User not found. Please check your credentials.";
193
- readonly invalidCredentials: "Invalid email or password";
194
- readonly invalidPassword: "Invalid password";
195
- readonly invalidEmail: "Invalid email address";
196
- readonly sessionExpired: "Your session has expired. Please sign in again.";
197
- readonly emailNotVerified: "Please verify your email address before signing in";
198
- readonly passwordTooShort: "Password must be at least {minLength} characters";
199
- readonly passwordTooLong: "Password must be at most {maxLength} characters";
200
- readonly accountAlreadyExists: "An account with this email already exists";
201
- readonly failedToCreateUser: "Failed to create user account. Please try again.";
202
- readonly failedToCreateSession: "Failed to create session. Please try again.";
203
- readonly failedToGetSession: "Failed to retrieve session. Please try again.";
204
- readonly failedToUpdateUser: "Failed to update user information. Please try again.";
205
- readonly failedToGetUserInfo: "Failed to retrieve user information. Please try again.";
206
- readonly socialAccountLinked: "This social account is already linked to another user";
207
- readonly providerNotFound: "Authentication provider not found";
208
- readonly userEmailNotFound: "User email address not found";
209
- readonly accountNotFound: "Account not found";
210
- readonly credentialAccountNotFound: "Credential account not found";
211
- readonly cannotUnlinkLastAccount: "Cannot unlink your last account";
212
- readonly userAlreadyHasPassword: "User already has a password set";
213
- readonly emailCannotBeUpdated: "Email address cannot be updated at this time";
214
- readonly tokenExpired: "The verification token has expired. Please request a new verification email.";
215
- readonly invalidCallbackUrl: "Invalid callback URL";
216
- readonly invalidOrigin: "Request origin is not allowed";
217
- readonly validationFailed: "Authentication validation failed";
218
- readonly emailAlreadyVerified: "Email address is already verified";
219
- readonly emailMismatch: "Email address does not match";
220
- readonly unknownError: "An authentication error occurred";
221
- };
222
- readonly org: {
223
- readonly organizationNotFound: "Organization not found";
224
- readonly memberNotFound: "Member not found";
225
- readonly invitationNotFound: "Invitation not found";
226
- readonly permissionDenied: "You do not have permission to perform this action";
227
- readonly invitationRecipientMismatch: "You are not the recipient of this invitation";
228
- readonly conflict: "A resource with this identifier already exists";
229
- readonly limitReached: "The maximum limit has been reached";
230
- readonly membershipError: "This action cannot be performed due to membership constraints";
231
- readonly teamNotFound: "Team not found";
232
- readonly roleNotFound: "Role not found";
233
- };
234
- };
235
- };
236
- };
237
- declare module 'stratal/i18n' {
238
- interface AppMessageNamespaces {
239
- auth: typeof authMessages['en']['auth'];
240
- }
241
- } //# sourceMappingURL=en.d.ts.map
242
- //#endregion
243
- //#region src/auth/middleware/auth-context.middleware.d.ts
244
- /**
245
- * Auth Context Middleware
246
- *
247
- * Registers AuthContext in the request container at the start of each request.
248
- * This MUST run before SessionVerificationMiddleware and any other middleware
249
- * that depends on AuthContext.
250
- */
251
- declare class AuthContextMiddleware implements Middleware {
252
- handle(ctx: RouterContext, next: Next): Promise<void>;
253
- }
254
- //#endregion
255
183
  //#region src/auth/services/auth.service.d.ts
256
184
  /**
257
185
  * AuthService
@@ -260,11 +188,12 @@ declare class AuthContextMiddleware implements Middleware {
260
188
  * Configured via AuthModule.forRootAsync() from the application layer.
261
189
  *
262
190
  * **Extensibility:**
263
- * Extend this class in application layer to add custom methods.
191
+ * Extend this class to add custom methods. Subclasses inherit
192
+ * `@Request(AUTH_SERVICE)` scope automatically — no decorator needed.
264
193
  *
265
194
  * @example
266
195
  * ```typescript
267
- * @Transient(AUTH_SERVICE)
196
+ * @Request(AUTH_SERVICE)
268
197
  * export class AppAuthService extends AuthService<AuthOptions> {
269
198
  * async signInMagicLink(email: string) {
270
199
  * return wrapBetterAuth(async () => {
@@ -276,10 +205,10 @@ declare class AuthContextMiddleware implements Middleware {
276
205
  */
277
206
  declare class AuthService<TOptions extends BetterAuthOptions = BetterAuthOptions> {
278
207
  protected readonly options: TOptions;
279
- private authInstance;
208
+ private _authInstance?;
280
209
  constructor(options: TOptions);
281
210
  /**
282
- * Get the Better Auth instance
211
+ * Get the Better Auth instance.
283
212
  */
284
213
  get auth(): Auth<TOptions>;
285
214
  }
@@ -326,5 +255,5 @@ declare function mapBetterAuthError(error: APIError): ApplicationError;
326
255
  */
327
256
  declare function isAPIError(error: unknown): error is APIError;
328
257
  //#endregion
329
- export { AUTH_OPTIONS, AUTH_SERVICE, AccountAlreadyExistsError, AccountNotFoundError, AuthContextMiddleware, AuthModule, AuthModuleAsyncOptions, AuthService, AuthValidationFailedError, BetterAuthUnknownError, CannotUnlinkLastAccountError, CredentialAccountNotFoundError, EmailAlreadyVerifiedError, EmailCannotBeUpdatedError, EmailMismatchError, EmailNotVerifiedError, FailedToCreateSessionError, FailedToCreateUserError, FailedToGetSessionError, FailedToGetUserInfoError, FailedToUpdateUserError, 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, VerificationFailedError, authMessages, getErrorHandlerConfig, isAPIError, mapBetterAuthError, wrapBetterAuth };
258
+ export { AUTH_OPTIONS, AUTH_SERVICE, AccountAlreadyExistsError, AccountNotFoundError, AuthModule, AuthModuleAsyncOptions, AuthService, AuthValidationFailedError, CannotUnlinkLastAccountError, CredentialAccountNotFoundError, EmailAlreadyVerifiedError, EmailCannotBeUpdatedError, EmailMismatchError, EmailNotVerifiedError, 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 };
330
259
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../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/errors/verification-failed.error.ts","../../src/auth/i18n/en.ts","../../src/auth/middleware/auth-context.middleware.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/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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"}