@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,11 +1,9 @@
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 { n as UserNotAuthenticatedError } from "../errors-B1vVXc1T.mjs";
5
- import { t as InsufficientPermissionsError } from "../insufficient-permissions.error-CRnOHYvq.mjs";
6
- import { DI_TOKENS, Transient } 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 { n as UserNotAuthenticatedError } from "../errors-BvJSaUTW.mjs";
4
+ import { t as InsufficientPermissionsError } from "../insufficient-permissions.error-DeEyZRgy.mjs";
5
+ import { DI_TOKENS, Transient, inject } from "stratal/di";
7
6
  import { LOGGER_TOKENS } from "stratal/logger";
8
- import { inject as inject$1 } from "tsyringe";
9
7
  import { GUARD_METADATA_KEY, GuardExecutionService, UseGuards, getControllerGuards, getMethodGuards } from "stratal/guards";
10
8
  //#region src/guards/auth.guard.ts
11
9
  function parsePermissions(raw) {
@@ -72,7 +70,7 @@ function AuthGuard(options) {
72
70
  const userId = this.authContext.getUserId();
73
71
  if (!userId) {
74
72
  this.logger.debug("Auth guard: No user ID in context");
75
- throw new InsufficientPermissionsError(rawPermissions, void 0);
73
+ throw new InsufficientPermissionsError(rawPermissions);
76
74
  }
77
75
  if (this.accessService) {
78
76
  const allowed = await this.accessService.hasPermission(userId, permissions);
@@ -88,14 +86,9 @@ function AuthGuard(options) {
88
86
  };
89
87
  ConfiguredAuthGuard = __decorate([
90
88
  Transient(),
91
- __decorateParam(0, inject$1(DI_TOKENS.AuthContext)),
92
- __decorateParam(1, inject$1(LOGGER_TOKENS.LoggerService)),
93
- __decorateParam(2, inject$1(AC_TOKENS.AccessService, { isOptional: true })),
94
- __decorateMetadata("design:paramtypes", [
95
- Object,
96
- Object,
97
- Object
98
- ])
89
+ __decorateParam(0, inject(DI_TOKENS.AuthContext)),
90
+ __decorateParam(1, inject(LOGGER_TOKENS.LoggerService)),
91
+ __decorateParam(2, inject(AC_TOKENS.AccessService, { isOptional: true }))
99
92
  ], ConfiguredAuthGuard);
100
93
  return ConfiguredAuthGuard;
101
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["inject"],"sources":["../../src/guards/auth.guard.ts"],"sourcesContent":["import { DI_TOKENS, Transient } from 'stratal/di'\nimport type { AuthGuardOptions, CanActivate, GuardClass } from 'stratal/guards'\nimport { LOGGER_TOKENS, type LoggerService } from 'stratal/logger'\nimport type { RouterContext } from 'stratal/router'\nimport { inject } from 'tsyringe'\nimport { InsufficientPermissionsError } from '../access-control/errors/insufficient-permissions.error'\nimport type { AccessService } from '../access-control/services/access.service'\nimport { AC_TOKENS } from '../access-control/tokens'\nimport type { AuthContext } from '../context/auth-context'\nimport { UserNotAuthenticatedError } from '../context/errors'\n\nfunction parsePermissions(raw: string | string[]): Record<string, string[]> {\n const list = Array.isArray(raw) ? raw : [raw]\n return list.reduce<Record<string, string[]>>((acc, perm) => {\n const colon = perm.indexOf(':')\n const resource = colon === -1 ? perm : perm.slice(0, colon)\n const action = colon === -1 ? '*' : perm.slice(colon + 1)\n ;(acc[resource] ??= []).push(action)\n return acc\n }, {})\n}\n\n\n/**\n * AuthGuard Factory\n *\n * Creates a guard class that enforces authentication and optional authorization.\n *\n * **Authentication (no permissions):**\n * - Checks if user is authenticated via AuthContext.isAuthenticated()\n * - Throws UserNotAuthenticatedError (401) if not authenticated\n *\n * **Authorization (with permissions):**\n * - First verifies authentication\n * - Then checks permissions via AccessService (reads from AuthContext — no DB hit)\n * - Throws InsufficientPermissionsError (403) if unauthorized\n *\n * @param options - Configuration options\n * @param options.permissions - Required permissions keyed by resource\n * @returns Guard class for use with @UseGuards decorator\n *\n * @example Authentication only\n * ```typescript\n * @UseGuards(AuthGuard())\n * export class ProfileController { }\n * ```\n *\n * @example Authentication with permissions\n * ```typescript\n * @UseGuards(AuthGuard({ permissions: 'posts:update' }))\n * @UseGuards(AuthGuard({ permissions: ['posts:update', 'posts:delete'] }))\n * export class PostsController { }\n * ```\n */\nexport function AuthGuard(options?: AuthGuardOptions): GuardClass {\n const rawPermissions = options?.permissions\n const permissions = rawPermissions ? parsePermissions(rawPermissions) : undefined\n\n @Transient()\n class ConfiguredAuthGuard implements CanActivate {\n constructor(\n @inject(DI_TOKENS.AuthContext) private readonly authContext: AuthContext,\n @inject(LOGGER_TOKENS.LoggerService) private readonly logger: LoggerService,\n @inject(AC_TOKENS.AccessService, { isOptional: true }) private readonly accessService?: AccessService\n ) { }\n\n async canActivate(_context: RouterContext): Promise<boolean> {\n if (!this.authContext.isAuthenticated()) {\n this.logger.debug('Auth guard: User not authenticated')\n throw new UserNotAuthenticatedError()\n }\n\n if (!permissions || Object.keys(permissions).length === 0) {\n this.logger.debug('Auth guard: Authentication passed (no permissions required)')\n return true\n }\n\n const userId = this.authContext.getUserId()\n if (!userId) {\n this.logger.debug('Auth guard: No user ID in context')\n throw new InsufficientPermissionsError(rawPermissions!, undefined)\n }\n\n if (this.accessService) {\n const allowed = await this.accessService.hasPermission(userId, permissions)\n\n this.logger.debug('Auth guard: Authorization check', {\n userId,\n permissions,\n allowed,\n })\n\n if (!allowed) {\n throw new InsufficientPermissionsError(rawPermissions!, userId)\n }\n }\n\n return true\n }\n }\n\n return ConfiguredAuthGuard\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAS,iBAAiB,KAAkD;CAE1E,QADa,MAAM,QAAQ,IAAI,GAAG,MAAM,CAAC,IAAI,EACjC,QAAkC,KAAK,SAAS;EAC1D,MAAM,QAAQ,KAAK,QAAQ,IAAI;EAC/B,MAAM,WAAW,UAAU,KAAK,OAAO,KAAK,MAAM,GAAG,MAAM;EAC3D,MAAM,SAAS,UAAU,KAAK,MAAM,KAAK,MAAM,QAAQ,EAAE;EACxD,CAAC,IAAI,cAAc,EAAE,EAAE,KAAK,OAAO;EACpC,OAAO;IACN,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCR,SAAgB,UAAU,SAAwC;CAChE,MAAM,iBAAiB,SAAS;CAChC,MAAM,cAAc,iBAAiB,iBAAiB,eAAe,GAAG,KAAA;CAExE,IAAA,sBAAA,MACM,oBAA2C;EAEG;EACM;EACkB;EAH1E,YACE,aACA,QACA,eACA;GAHgD,KAAA,cAAA;GACM,KAAA,SAAA;GACkB,KAAA,gBAAA;;EAG1E,MAAM,YAAY,UAA2C;GAC3D,IAAI,CAAC,KAAK,YAAY,iBAAiB,EAAE;IACvC,KAAK,OAAO,MAAM,qCAAqC;IACvD,MAAM,IAAI,2BAA2B;;GAGvC,IAAI,CAAC,eAAe,OAAO,KAAK,YAAY,CAAC,WAAW,GAAG;IACzD,KAAK,OAAO,MAAM,8DAA8D;IAChF,OAAO;;GAGT,MAAM,SAAS,KAAK,YAAY,WAAW;GAC3C,IAAI,CAAC,QAAQ;IACX,KAAK,OAAO,MAAM,oCAAoC;IACtD,MAAM,IAAI,6BAA6B,gBAAiB,KAAA,EAAU;;GAGpE,IAAI,KAAK,eAAe;IACtB,MAAM,UAAU,MAAM,KAAK,cAAc,cAAc,QAAQ,YAAY;IAE3E,KAAK,OAAO,MAAM,mCAAmC;KACnD;KACA;KACA;KACD,CAAC;IAEF,IAAI,CAAC,SACH,MAAM,IAAI,6BAA6B,gBAAiB,OAAO;;GAInE,OAAO;;;;EAvCV,WAAW;qBAGPA,SAAO,UAAU,YAAY,CAAA;qBAC7BA,SAAO,cAAc,cAAc,CAAA;qBACnCA,SAAO,UAAU,eAAe,EAAE,YAAY,MAAM,CAAC,CAAA;;;;;;;CAsC1D,OAAO"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/guards/auth.guard.ts"],"sourcesContent":["import { DI_TOKENS, inject, Transient } from 'stratal/di'\nimport type { AuthGuardOptions, CanActivate, GuardClass } from 'stratal/guards'\nimport { LOGGER_TOKENS, type LoggerService } from 'stratal/logger'\nimport type { RouterContext } from 'stratal/router'\nimport { InsufficientPermissionsError } from '../access-control/errors/insufficient-permissions.error'\nimport type { AccessService } from '../access-control/services/access.service'\nimport { AC_TOKENS } from '../access-control/tokens'\nimport type { AuthContext } from '../context/auth-context'\nimport { UserNotAuthenticatedError } from '../context/errors'\n\nfunction parsePermissions(raw: string | string[]): Record<string, string[]> {\n const list = Array.isArray(raw) ? raw : [raw]\n return list.reduce<Record<string, string[]>>((acc, perm) => {\n const colon = perm.indexOf(':')\n const resource = colon === -1 ? perm : perm.slice(0, colon)\n const action = colon === -1 ? '*' : perm.slice(colon + 1)\n ;(acc[resource] ??= []).push(action)\n return acc\n }, {})\n}\n\n\n/**\n * AuthGuard Factory\n *\n * Creates a guard class that enforces authentication and optional authorization.\n *\n * **Authentication (no permissions):**\n * - Checks if user is authenticated via AuthContext.isAuthenticated()\n * - Throws UserNotAuthenticatedError (401) if not authenticated\n *\n * **Authorization (with permissions):**\n * - First verifies authentication\n * - Then checks permissions via AccessService (reads from AuthContext — no DB hit)\n * - Throws InsufficientPermissionsError (403) if unauthorized\n *\n * @param options - Configuration options\n * @param options.permissions - Required permissions keyed by resource\n * @returns Guard class for use with @UseGuards decorator\n *\n * @example Authentication only\n * ```typescript\n * @UseGuards(AuthGuard())\n * export class ProfileController { }\n * ```\n *\n * @example Authentication with permissions\n * ```typescript\n * @UseGuards(AuthGuard({ permissions: 'posts:update' }))\n * @UseGuards(AuthGuard({ permissions: ['posts:update', 'posts:delete'] }))\n * export class PostsController { }\n * ```\n */\nexport function AuthGuard(options?: AuthGuardOptions): GuardClass {\n const rawPermissions = options?.permissions\n const permissions = rawPermissions ? parsePermissions(rawPermissions) : undefined\n\n @Transient()\n class ConfiguredAuthGuard implements CanActivate {\n constructor(\n @inject(DI_TOKENS.AuthContext) private readonly authContext: AuthContext,\n @inject(LOGGER_TOKENS.LoggerService) private readonly logger: LoggerService,\n @inject(AC_TOKENS.AccessService, { isOptional: true }) private readonly accessService?: AccessService\n ) { }\n\n async canActivate(_context: RouterContext): Promise<boolean> {\n if (!this.authContext.isAuthenticated()) {\n this.logger.debug('Auth guard: User not authenticated')\n throw new UserNotAuthenticatedError()\n }\n\n if (!permissions || Object.keys(permissions).length === 0) {\n this.logger.debug('Auth guard: Authentication passed (no permissions required)')\n return true\n }\n\n const userId = this.authContext.getUserId()\n if (!userId) {\n this.logger.debug('Auth guard: No user ID in context')\n throw new InsufficientPermissionsError(rawPermissions!)\n }\n\n if (this.accessService) {\n const allowed = await this.accessService.hasPermission(userId, permissions)\n\n this.logger.debug('Auth guard: Authorization check', {\n userId,\n permissions,\n allowed,\n })\n\n if (!allowed) {\n throw new InsufficientPermissionsError(rawPermissions!, userId)\n }\n }\n\n return true\n }\n }\n\n return ConfiguredAuthGuard\n}\n"],"mappings":";;;;;;;;AAUA,SAAS,iBAAiB,KAAkD;CAE1E,QADa,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG,GAChC,QAAkC,KAAK,SAAS;EAC1D,MAAM,QAAQ,KAAK,QAAQ,GAAG;EAC9B,MAAM,WAAW,UAAU,KAAK,OAAO,KAAK,MAAM,GAAG,KAAK;EAC1D,MAAM,SAAS,UAAU,KAAK,MAAM,KAAK,MAAM,QAAQ,CAAC;EACvD,CAAC,IAAI,cAAc,CAAC,GAAG,KAAK,MAAM;EACnC,OAAO;CACT,GAAG,CAAC,CAAC;AACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,UAAU,SAAwC;CAChE,MAAM,iBAAiB,SAAS;CAChC,MAAM,cAAc,iBAAiB,iBAAiB,cAAc,IAAI,KAAA;CAExE,IAAA,sBAAA,MACM,oBAA2C;EAEG;EACM;EACkB;EAH1E,YACE,aACA,QACA,eACA;GAHgD,KAAA,cAAA;GACM,KAAA,SAAA;GACkB,KAAA,gBAAA;EACtE;EAEJ,MAAM,YAAY,UAA2C;GAC3D,IAAI,CAAC,KAAK,YAAY,gBAAgB,GAAG;IACvC,KAAK,OAAO,MAAM,oCAAoC;IACtD,MAAM,IAAI,0BAA0B;GACtC;GAEA,IAAI,CAAC,eAAe,OAAO,KAAK,WAAW,EAAE,WAAW,GAAG;IACzD,KAAK,OAAO,MAAM,6DAA6D;IAC/E,OAAO;GACT;GAEA,MAAM,SAAS,KAAK,YAAY,UAAU;GAC1C,IAAI,CAAC,QAAQ;IACX,KAAK,OAAO,MAAM,mCAAmC;IACrD,MAAM,IAAI,6BAA6B,cAAe;GACxD;GAEA,IAAI,KAAK,eAAe;IACtB,MAAM,UAAU,MAAM,KAAK,cAAc,cAAc,QAAQ,WAAW;IAE1E,KAAK,OAAO,MAAM,mCAAmC;KACnD;KACA;KACA;IACF,CAAC;IAED,IAAI,CAAC,SACH,MAAM,IAAI,6BAA6B,gBAAiB,MAAM;GAElE;GAEA,OAAO;EACT;CACF;;EAzCC,UAAU;qBAGN,OAAO,UAAU,WAAW,CAAA;qBAC5B,OAAO,cAAc,aAAa,CAAA;qBAClC,OAAO,UAAU,eAAe,EAAE,YAAY,KAAK,CAAC,CAAA;;CAsCzD,OAAO;AACT"}
@@ -1,7 +1,6 @@
1
- import { a as InferConnectionSchema, i as InferConnectionExtensions, n as DefaultConnectionName, r as InferAnySchema, t as ConnectionName } from "./types-BZlcRR2M.mjs";
2
- import { MessageKeys } from "stratal/i18n";
1
+ import { a as InferConnectionSchema, i as InferConnectionExtensions, n as DefaultConnectionName, r as InferAnySchema, t as ConnectionName } from "./types-CWZ9q74G.mjs";
3
2
  import { AsyncModuleOptions, DynamicModule, ModuleContext, OnInitialize, OnShutdown } from "stratal/module";
4
- import { ApplicationError, ErrorCode } from "stratal/errors";
3
+ import { ApplicationError, HttpException } from "stratal/errors";
5
4
  import { Command } from "stratal/quarry";
6
5
  import { AggregateArgs, AllCrudOperations, AnyPlugin, ClientContract, ClientOptions, ComputedFieldsOptions, CountArgs, CreateArgs, CreateManyArgs, DeleteArgs, DeleteManyArgs, FindFirstArgs, FindManyArgs, FindUniqueArgs, GroupByArgs, ModelResult, RuntimePlugin, UpdateArgs, UpdateManyArgs, UpsertArgs } from "@zenstackhq/orm";
7
6
  import { SchemaDef } from "@zenstackhq/schema";
@@ -28,7 +27,7 @@ interface DatabaseModuleConfig {
28
27
  declare class DatabaseModule implements OnInitialize, OnShutdown {
29
28
  static forRoot(config: DatabaseModuleConfig): DynamicModule;
30
29
  static forRootAsync(options: AsyncModuleOptions<DatabaseModuleConfig>): DynamicModule;
31
- onInitialize(context: ModuleContext): void;
30
+ onInitialize(context: ModuleContext): Promise<void>;
32
31
  onShutdown(context: ModuleContext): void;
33
32
  }
34
33
  //#endregion
@@ -60,101 +59,20 @@ declare function connectionSymbol(name: ConnectionName): symbol;
60
59
  //#region src/database/decorators/inject-db.decorator.d.ts
61
60
  declare function InjectDB(name: ConnectionName): ParameterDecorator;
62
61
  //#endregion
63
- //#region src/database/errors/database-error.d.ts
64
- /**
65
- * DatabaseError
66
- *
67
- * Generic database error thrown when a database operation fails
68
- * and doesn't fit into a more specific error category.
69
- *
70
- * This is the base class for all database-related errors.
71
- */
72
- declare class DatabaseError extends ApplicationError {
73
- constructor(messageKey?: MessageKeys, code?: ErrorCode, metadata?: Record<string, unknown>);
74
- }
75
- //#endregion
76
- //#region src/database/errors/database-config.error.d.ts
77
- declare class DatabaseConfigError extends DatabaseError {
78
- constructor(details: string);
79
- }
80
- //#endregion
81
- //#region src/database/errors/foreign-key-constraint.error.d.ts
82
- /**
83
- * ForeignKeyConstraintError
84
- *
85
- * Thrown when a database foreign key constraint is violated.
86
- * This typically occurs when:
87
- * - Trying to insert a record with a foreign key that doesn't exist
88
- * - Trying to delete a record that is referenced by other records
89
- * - Trying to update a foreign key to a non-existent value
90
- */
91
- declare class ForeignKeyConstraintError extends DatabaseError {
92
- constructor(field?: string);
93
- }
94
- //#endregion
95
- //#region src/database/errors/invalid-error-code-range.error.d.ts
96
- /**
97
- * InvalidErrorCodeRangeError
98
- *
99
- * Thrown when a DatabaseError subclass is constructed with an error code
100
- * outside the valid database error range (2000-2999).
101
- * This is a developer-facing error to enforce error code conventions.
102
- */
103
- declare class InvalidErrorCodeRangeError extends ApplicationError {
104
- constructor(code: number, expectedRange: string);
105
- }
106
- //#endregion
107
62
  //#region src/database/errors/record-not-found.error.d.ts
108
- /**
109
- * RecordNotFoundError
110
- *
111
- * Generic error thrown when a database record is not found.
112
- * This is typically thrown when a findUnique or findFirst operation
113
- * returns null, or when a required record doesn't exist.
114
- *
115
- * Services should catch this and optionally refine it to a more specific
116
- * domain error (e.g., NoteNotFoundError, UserNotFoundError).
117
- */
118
- declare class RecordNotFoundError extends DatabaseError {
119
- constructor(details?: string);
63
+ declare class RecordNotFoundError extends HttpException {
64
+ readonly details?: string | undefined;
65
+ constructor(details?: string | undefined, cause?: unknown);
120
66
  }
121
67
  //#endregion
122
68
  //#region src/database/errors/unique-constraint.error.d.ts
123
- /**
124
- * UniqueConstraintError
125
- *
126
- * Thrown when a database unique constraint is violated.
127
- * This typically occurs when trying to insert or update a record
128
- * with a value that already exists in a unique column.
129
- *
130
- * Services should catch this and optionally refine it to a more specific
131
- * domain error (e.g., UserEmailAlreadyExistsError).
132
- */
133
- declare class UniqueConstraintError extends DatabaseError {
134
- constructor(fields?: string[]);
69
+ declare class UniqueConstraintError extends HttpException {
70
+ readonly fields?: string[] | undefined;
71
+ constructor(fields?: string[] | undefined, cause?: unknown);
135
72
  }
136
73
  //#endregion
137
74
  //#region src/database/errors/from-zenstack-error.d.ts
138
- /**
139
- * Transform ZenStack ORM errors into ApplicationError instances
140
- *
141
- * This function maps ORMError codes to generic database error classes.
142
- * Services can catch these generic errors and optionally refine them to
143
- * more specific domain errors if needed.
144
- *
145
- * @param error - The error thrown by ZenStack ORM
146
- * @returns An ApplicationError instance
147
- *
148
- * @example
149
- * ```typescript
150
- * try {
151
- * await db.user.create({ data: { email: 'existing@example.com' } })
152
- * } catch (error) {
153
- * throw fromZenStackError(error) // Becomes UniqueConstraintError or other
154
- * }
155
- * ```
156
- */
157
- declare function fromZenStackError(error: unknown): DatabaseError;
75
+ declare function fromZenStackError(error: unknown): ApplicationError;
158
76
  //#endregion
159
77
  //#region src/database/event-types.d.ts
160
78
  /**
@@ -444,5 +362,5 @@ declare class MigrateStatusCommand extends ZenStackCommand {
444
362
  handle(): Promise<number>;
445
363
  }
446
364
  //#endregion
447
- export { DATABASE_TOKENS as A, UniqueConstraintError as C, DatabaseConfigError as D, ForeignKeyConstraintError as E, DatabaseModuleConfig as F, DatabaseService as M, DatabaseConnectionConfig as N, DatabaseError as O, DatabaseModule as P, fromZenStackError as S, InvalidErrorCodeRangeError as T, EventPhase as _, DbPushCommand as a, ModelName as b, ZenStackCommand as c, EventEmitterPluginOptions as d, ErrorHandlerPlugin as f, DatabaseOperation as g, DatabaseEvents as h, MigrateDeployCommand as i, connectionSymbol as j, InjectDB as k, SchemaSwitcher as l, DatabaseEventName as m, MigrateResetCommand as n, DbPullCommand as o, databaseMessages as p, MigrateDevCommand as r, DbGenerateCommand as s, MigrateStatusCommand as t, EventEmitterPlugin as u, GetData as v, RecordNotFoundError as w, ParseEvent as x, GetResult as y };
448
- //# sourceMappingURL=index-CCDPF-1Y.d.mts.map
365
+ export { DatabaseModule as A, UniqueConstraintError as C, connectionSymbol as D, DATABASE_TOKENS as E, DatabaseService as O, fromZenStackError as S, InjectDB as T, EventPhase as _, DbPushCommand as a, ModelName as b, ZenStackCommand as c, EventEmitterPluginOptions as d, ErrorHandlerPlugin as f, DatabaseOperation as g, DatabaseEvents as h, MigrateDeployCommand as i, DatabaseModuleConfig as j, DatabaseConnectionConfig as k, SchemaSwitcher as l, DatabaseEventName as m, MigrateResetCommand as n, DbPullCommand as o, databaseMessages as p, MigrateDevCommand as r, DbGenerateCommand as s, MigrateStatusCommand as t, EventEmitterPlugin as u, GetData as v, RecordNotFoundError as w, ParseEvent as x, GetResult as y };
366
+ //# sourceMappingURL=index-jILx9QXw.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-jILx9QXw.d.mts","names":[],"sources":["../src/database/database.module.ts","../src/database/database.service.ts","../src/database/database.tokens.ts","../src/database/decorators/inject-db.decorator.ts","../src/database/errors/record-not-found.error.ts","../src/database/errors/unique-constraint.error.ts","../src/database/errors/from-zenstack-error.ts","../src/database/event-types.ts","../src/database/i18n/en.ts","../src/database/plugins/error-handler.plugin.ts","../src/database/plugins/event-emitter.plugin.ts","../src/database/plugins/schema-switcher.ts","../src/database/commands/zenstack.command.ts","../src/database/commands/db-generate.command.ts","../src/database/commands/db-pull.command.ts","../src/database/commands/db-push.command.ts","../src/database/commands/migrate-deploy.command.ts","../src/database/commands/migrate-dev.command.ts","../src/database/commands/migrate-reset.command.ts","../src/database/commands/migrate-status.command.ts"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { a as InferConnectionSchema, i as InferConnectionExtensions, n as DefaultConnectionName, r as InferAnySchema, s as StratalDatabase, t as ConnectionName } from "./types-BZlcRR2M.mjs";
1
+ import { a as InferConnectionSchema, i as InferConnectionExtensions, n as DefaultConnectionName, r as InferAnySchema, s as StratalDatabase, t as ConnectionName } from "./types-CWZ9q74G.mjs";
2
2
  import { CustomEventRegistry, EventName } from "stratal/events";
3
- export { type ConnectionName, type CustomEventRegistry, type DefaultConnectionName, type EventName, type InferAnySchema, type InferConnectionExtensions, type InferConnectionSchema, type StratalDatabase };
3
+ export type { ConnectionName, CustomEventRegistry, DefaultConnectionName, EventName, InferAnySchema, InferConnectionExtensions, InferConnectionSchema, StratalDatabase };
@@ -0,0 +1,16 @@
1
+ import { HttpException } from "stratal/errors";
2
+ //#region src/access-control/errors/insufficient-permissions.error.ts
3
+ var InsufficientPermissionsError = class extends HttpException {
4
+ requiredPermissions;
5
+ userId;
6
+ constructor(requiredPermissions, userId) {
7
+ const summary = Array.isArray(requiredPermissions) ? requiredPermissions.join(", ") : requiredPermissions;
8
+ super(403, "Insufficient permissions");
9
+ this.requiredPermissions = summary;
10
+ this.userId = userId;
11
+ }
12
+ };
13
+ //#endregion
14
+ export { InsufficientPermissionsError as t };
15
+
16
+ //# sourceMappingURL=insufficient-permissions.error-DeEyZRgy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insufficient-permissions.error-DeEyZRgy.mjs","names":[],"sources":["../src/access-control/errors/insufficient-permissions.error.ts"],"sourcesContent":["import { HttpException } from 'stratal/errors'\n\nexport class InsufficientPermissionsError extends HttpException {\n public readonly requiredPermissions: string\n public readonly userId?: string\n\n constructor(requiredPermissions: string | string[], userId?: string) {\n const summary = Array.isArray(requiredPermissions) ? requiredPermissions.join(', ') : requiredPermissions\n super(403, 'Insufficient permissions')\n this.requiredPermissions = summary\n this.userId = userId\n }\n}\n"],"mappings":";;AAEA,IAAa,+BAAb,cAAkD,cAAc;CAC9D;CACA;CAEA,YAAY,qBAAwC,QAAiB;EACnE,MAAM,UAAU,MAAM,QAAQ,mBAAmB,IAAI,oBAAoB,KAAK,IAAI,IAAI;EACtF,MAAM,KAAK,0BAA0B;EACrC,KAAK,sBAAsB;EAC3B,KAAK,SAAS;CAChB;AACF"}
@@ -89,4 +89,4 @@ interface InternalDatabaseEventContext {
89
89
  }
90
90
  //#endregion
91
91
  export { InferConnectionSchema as a, InferConnectionExtensions as i, DefaultConnectionName as n, InternalDatabaseEventContext as o, InferAnySchema as r, StratalDatabase as s, ConnectionName as t };
92
- //# sourceMappingURL=types-BZlcRR2M.d.mts.map
92
+ //# sourceMappingURL=types-CWZ9q74G.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-CWZ9q74G.d.mts","names":[],"sources":["../src/database/types.ts"],"mappings":";;;;;;AA+BA;;;;AAAgC;AAAG;;;;;;;;;;;;;AAIiC;AAAA;;;;;;;UAJnD,eAAA;;KAGZ,sBAAA,MACH,CAAA,SAAU,aAAa,0CAA0C,CAAA;;KAG9D,0BAAA,MACH,CAAA,SAAU,aAAa,0CAA0C,CAAA;AAAC;AAAA,KAG/D,mBAAA,MACH,CAAA,SAAU,aAAa,0CAA0C,CAAA;;KAG9D,YAAA,8BACH,OAAA;EAEM,YAAA,EAAc,sBAAA,CAAuB,CAAA,IAAK,YAAA,CAAa,IAAA;EACvD,gBAAA,EAAkB,0BAAA,CAA2B,CAAA,IAAK,YAAA,CAAa,IAAA;EAC/D,SAAA,EAAW,mBAAA,CAAoB,CAAA,IAAK,YAAA,CAAa,IAAA;AAAA;EAEjD,YAAA;EAAkB,gBAAA;EAAsB,SAAA;AAAA;;KAGpC,yBAAA,qBACV,eAAA;EAA0B,OAAA;AAAA,IACtB,CAAA,eAAgB,CAAA,GACd,CAAA,CAAE,CAAA,sBACA,YAAA,CAAa,CAAA,CAAE,CAAA;EACb,YAAA;EAAkB,gBAAA;EAAsB,SAAA;AAAA;EAC1C,YAAA;EAAkB,gBAAA;EAAsB,SAAA;AAAA;EAC1C,YAAA;EAAkB,gBAAA;EAAsB,SAAA;AAAA;;KAGpC,qBAAA,qBACV,eAAA;EAA0B,OAAA;AAAA,IACtB,CAAA,eAAgB,CAAA,GAAI,CAAA,CAAE,CAAA,UAAW,SAAA,GAAY,CAAA,CAAE,CAAA,IAAK,SAAA,GAAY,SAAA,GAChE,SAAA;;KAGM,cAAA,GACV,eAAA;EAA0B,OAAA;AAAA,IACtB,CAAA,OAAQ,CAAA,UAAW,SAAA,GAAY,CAAA,OAAQ,CAAA,IAAK,SAAA,GAC5C,SAAA;;KAGM,cAAA,GACV,eAAA;EAA0B,OAAA;AAAA,UAChB,CAAA,0BAA2B,OAAA,OAAc,CAAA;;KAIzC,qBAAA,GACV,eAAe;EAAW,iBAAA;AAAA,IAA8C,CAAA;;;;;UAMzD,4BAAA;EACf,IAAA;EACA,MAAM;AAAA"}
@@ -8,4 +8,4 @@ interface AccessControlOptions<TStatements extends Statements = Statements, TRol
8
8
  }
9
9
  //#endregion
10
10
  export { RolePermissions as n, AccessControlOptions as t };
11
- //# sourceMappingURL=types-BLyu9dAd.d.mts.map
11
+ //# sourceMappingURL=types-DabF8LGz.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types-BLyu9dAd.d.mts","names":[],"sources":["../src/access-control/types.ts"],"mappings":";;;KAEY,eAAA,qBAAoC,UAAA,kBAClC,WAAA,aAAwB,WAAA,CAAY,CAAA;AAAA,UAGjC,oBAAA,qBAAyC,UAAA,GAAa,UAAA,iBAA2B,MAAA,SAAe,eAAA,CAAgB,WAAA,KAAgB,MAAA,SAAe,eAAA,CAAgB,WAAA;EAC9K,EAAA,EAAI,aAAA;EACJ,KAAA,gBAAqB,MAAA,GAAS,IAAA;AAAA"}
1
+ {"version":3,"file":"types-DabF8LGz.d.mts","names":[],"sources":["../src/access-control/types.ts"],"mappings":";;;KAEY,eAAA,qBAAoC,UAAA,kBAClC,WAAA,aAAwB,WAAA,CAAY,CAAA;AAAA,UAGjC,oBAAA,qBAAyC,UAAA,GAAa,UAAA,iBAA2B,MAAA,SAAe,eAAA,CAAgB,WAAA,KAAgB,MAAA,SAAe,eAAA,CAAgB,WAAA;EAC9K,EAAA,EAAI,aAAA;EACJ,KAAA,gBAAqB,MAAA,GAAS,IAAA;AAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stratal/framework",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Temitayo Fadojutimi",
@@ -57,46 +57,49 @@
57
57
  "generate": "zenstack generate --schema=test/schema.zmodel -o test/zenstack",
58
58
  "generate:types": "wrangler types -c test/wrangler.jsonc",
59
59
  "pretest": "npx dotenv -- yarn generate && yarn generate:types",
60
- "test": "vitest run",
61
- "test:watch": "vitest",
62
- "test:e2e": "vitest run --project e2e",
63
- "test:coverage": "vitest run --coverage",
60
+ "test": "npx dotenv -- vitest run",
61
+ "test:watch": "npx dotenv -- vitest",
62
+ "test:e2e": "npx dotenv -- vitest run --project e2e",
63
+ "test:coverage": "npx dotenv -- vitest run --coverage",
64
64
  "test:db": "docker compose -f test/docker-compose.yml up -d",
65
65
  "typecheck": "yarn tsc --noEmit",
66
66
  "lint": "npx oxlint .",
67
67
  "lint:fix": "npx oxlint --fix ."
68
68
  },
69
69
  "dependencies": {
70
- "@better-auth/core": "^1.6.10",
71
70
  "@faker-js/faker": "^10.4.0",
72
- "@zenstackhq/cli": "^3.6.4",
73
- "@zenstackhq/orm": "^3.6.4",
74
- "better-auth": "^1.6.10",
75
- "better-call": "2.0.3",
71
+ "better-call": "1.3.5",
76
72
  "postgres-array": "^3.0.4"
77
73
  },
78
74
  "peerDependencies": {
75
+ "@better-auth/core": ">=1.6",
76
+ "@zenstackhq/orm": ">=3.6",
77
+ "@zenstackhq/schema": ">=3.6",
78
+ "better-auth": ">=1.6",
79
79
  "pg": "^8.0.0",
80
- "reflect-metadata": "^0.2.2",
81
- "stratal": "^0.0.21"
80
+ "stratal": "^0.0.23"
82
81
  },
83
82
  "devDependencies": {
84
- "@cloudflare/vitest-pool-workers": "^0.16.3",
85
- "@cloudflare/workers-types": "4.20260510.1",
83
+ "@better-auth/core": "^1.6.14",
84
+ "@cloudflare/vitest-pool-workers": "^0.16.12",
85
+ "@cloudflare/workers-types": "4.20260603.1",
86
86
  "@stratal/testing": "workspace:^",
87
- "@types/node": "^25.6.2",
87
+ "@types/node": "^25.9.1",
88
88
  "@types/pg": "^8.20.0",
89
- "@vitest/coverage-istanbul": "~4.1.5",
90
- "@vitest/runner": "~4.1.5",
91
- "@vitest/snapshot": "~4.1.5",
92
- "@zenstackhq/better-auth": "^3.6.4",
89
+ "@vitest/coverage-istanbul": "~4.1.8",
90
+ "@vitest/runner": "~4.1.8",
91
+ "@vitest/snapshot": "~4.1.8",
92
+ "@zenstackhq/better-auth": "^3.7.2",
93
+ "@zenstackhq/cli": "^3.7.2",
94
+ "@zenstackhq/orm": "^3.7.2",
95
+ "@zenstackhq/schema": "^3.7.2",
96
+ "better-auth": "^1.6.14",
93
97
  "dotenv-cli": "^11.0.0",
94
- "pg": "^8.20.0",
95
- "reflect-metadata": "^0.2.2",
98
+ "pg": "^8.21.0",
96
99
  "stratal": "workspace:*",
97
- "tsdown": "^0.22.0",
100
+ "tsdown": "^0.22.1",
98
101
  "typescript": "^6.0.3",
99
- "vitest": "~4.1.5",
100
- "wrangler": "^4.90.0"
102
+ "vitest": "~4.1.8",
103
+ "wrangler": "^4.97.0"
101
104
  }
102
105
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"access.service-Cb99esfz.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, Transient } 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@Transient(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":";;;;;;;;;;;;;;AAYA,SAAgB,sBAAsB,UAAkD;CACtF,OAAO;EACL,IAAI;EACJ,QAAQ,EACN,MAAM,EACJ,QAAQ,EACN,MAAM;GACJ,MAAM;GACN,UAAU;GACV,OAAO;GACP,cAAc;GACf,EACF,EACF,EACF;EACF;;;;ACrBH,SAAS,WAAW,MAA2C;CAC7D,IAAI,CAAC,MAAM,OAAO,EAAE;CACpB,OAAO,KAAK,MAAM,IAAI,CAAC,KAAI,MAAK,EAAE,MAAM,CAAC,CAAC,OAAO,QAAQ;;AA+BpD,IAAA,gBAAA,MAAM,cAAc;CAGN;CAEA;CAEA;CANnB,YACE,aAEA,IAEA,SAEA;EALiB,KAAA,cAAA;EAEA,KAAA,KAAA;EAEA,KAAA,UAAA;;;;;;;;CASnB,MAAM,aAAa,QAAmC;EACpD,IAAI,WAAW,KAAK,YAAY,WAAW,EAAE;GAC3C,MAAM,QAAQ,KAAK,YAAY,UAAU;GACzC,IAAI,MAAM,SAAS,GAAG,OAAO;;EAM/B,OAAO,YAAW,MAJE,KAAK,GAAI,KAAK,WAAW;GAC3C,OAAO,EAAE,IAAI,QAAQ;GACrB,QAAQ,EAAE,MAAM,MAAM;GACvB,CAAC,GACsB,KAAK;;;;;;;CAQ/B,MAAM,YAAY,QAAgB,MAAwC;EACxE,MAAM,UAAU,MAAM,QAAQ,KAAK,GAAG,KAAK,KAAK,IAAI,GAAG;EACvD,MAAM,KAAK,GAAG,KAAK,OAAO;GACxB,OAAO,EAAE,IAAI,QAAQ;GACrB,MAAM,EAAE,MAAM,SAAS;GACxB,CAAC;;;;;;;CAQJ,MAAM,cAAc,QAAgB,aAAyD;EAC3F,MAAM,QAAQ,MAAM,KAAK,aAAa,OAAO;EAC7C,OAAO,KAAK,iBAAiB,OAAO,YAAY;;;;;;CAOlD,MAAM,sBAAsB,QAAmD;EAC7E,MAAM,QAAQ,MAAM,KAAK,aAAa,OAAO;EAC7C,OAAO,KAAK,iBAAiB,MAAM;;;;;;CAOrC,sBAAgC;EAC9B,OAAO,KAAK,YAAY,UAAU;;;;;;CAOpC,yBAAyB,aAAgD;EACvE,MAAM,QAAQ,KAAK,YAAY,UAAU;EACzC,IAAI,MAAM,WAAW,GAAG,OAAO;EAC/B,OAAO,KAAK,iBAAiB,OAAO,YAAY;;;;;;CAOlD,4BAAsD;EACpD,MAAM,QAAQ,KAAK,YAAY,UAAU;EACzC,OAAO,KAAK,iBAAiB,MAAM;;CAGrC,iBAAyB,OAAiB,aAAgD;EACxF,OAAO,MAAM,MAAK,aAAY;GAC5B,MAAM,UAAU,KAAK,QAAQ,MAAM;GACnC,IAAI,CAAC,SAAS,OAAO;GAErB,MAAM,WAAqC,EAAE;GAE7C,KAAK,MAAM,CAAC,UAAU,YAAY,OAAO,QAAQ,YAAY,EAC3D,IAAI,QAAQ,SAAS,IAAI;QAGnB,CADiB,QAAQ,WAAiD,WAC5D,QAAQ,OAAO;UAEjC,SAAS,YAAY;GAIzB,OAAO,OAAO,KAAK,SAAS,CAAC,WAAW,KAAK,QAAQ,UAAU,SAAS,CAAC;IACzE;;CAGJ,iBAAyB,OAA2C;EAClE,MAAM,SAAmC,EAAE;EAC3C,KAAK,MAAM,YAAY,OAAO;GAC5B,MAAM,UAAU,KAAK,QAAQ,MAAM;GACnC,IAAI,CAAC,SAAS;GACd,KAAK,MAAM,CAAC,UAAU,YAAY,OAAO,QAAQ,QAAQ,WAAW,EAAE;IACpE,OAAO,cAAc,EAAE;IACvB,KAAK,MAAM,UAAU,SACnB,IAAI,CAAC,OAAO,UAAU,SAAS,OAAO,EACpC,OAAO,UAAU,KAAK,OAAO;;;EAKrC,OAAO;;;;CA3HV,UAAU,UAAU,cAAc;oBAG9B,OAAO,UAAU,YAAY,CAAA;oBAE7B,OAAO,UAAU,SAAS,CAAA;oBAE1B,OAAO,UAAU,QAAQ,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-context-DXSTlnQH.d.mts","names":[],"sources":["../src/context/auth-context.ts"],"mappings":";;;;;AA8BA;;;;;AAEA;;;;;AAIA;;;;;;;;;;;UANiB,QAAA,SAAiB,QAAA;AAAA,UAEjB,QAAA;EACf,IAAA,EAAM,QAAA;AAAA;AAAA,cAIK,WAAA;EAAA,UACD,IAAA,GAAO,QAAA;EAqBF;;;;EAff,cAAA,CAAe,IAAA,EAAM,QAAA;EAsDrB;;;;EA9CA,OAAA,CAAA,GAAW,QAAA;EAuEK;;;EAhEhB,WAAA,CAAA,GAAe,QAAA;;;;;EAWf,SAAA,CAAA;;;;;EAQA,aAAA,CAAA;;;;EAOA,WAAA,CAAA,GAAe,QAAA;;;;;;;EAaf,OAAA,CAAA;;;;;EAQA,QAAA,CAAA;;;;EASA,eAAA,CAAA;;;;;EAQA,gBAAA,CAAA;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-context-HLwuOl51.mjs","names":[],"sources":["../src/context/auth-context.ts"],"sourcesContent":["import type { BaseUser } from '@better-auth/core/db'\nimport { Transient, DI_TOKENS } from 'stratal/di'\nimport {\n ContextNotInitializedError,\n UserNotAuthenticatedError\n} from './errors'\n\n/**\n * Authenticated user shape stored in {@link AuthContext}.\n *\n * Inherits Better Auth's base user fields. Apps whose schema stores\n * `firstName`/`lastName` instead of a `name` column should expose a `name`\n * via a ZenStack result extension (see\n * https://zenstack.dev/docs/orm/plugins/extending-orm-client#adding-fields-to-query-results)\n * so reads return a populated `name` for free.\n *\n * Augment via TypeScript module declaration to add app-specific fields. Match\n * the augmentation to whatever your Better Auth `user.additionalFields` /\n * plugins are configured to return:\n *\n * @example\n * ```ts\n * declare module '@stratal/framework/context' {\n * interface AuthUser {\n * role: string\n * locale: string\n * }\n * }\n * ```\n */\nexport interface AuthUser extends BaseUser {}\n\nexport interface AuthInfo {\n user: AuthUser\n}\n\n@Transient(DI_TOKENS.AuthContext)\nexport class AuthContext {\n protected user?: AuthUser\n\n /**\n * Set authentication context.\n * This should be called once per request with the authenticated user.\n */\n setAuthContext(info: AuthInfo): void {\n this.user = info.user\n }\n\n /**\n * Get the authenticated user if available.\n * Returns undefined if no user is authenticated.\n */\n getUser(): AuthUser | undefined {\n return this.user\n }\n\n /**\n * Get the authenticated user or throw if not authenticated.\n */\n requireUser(): AuthUser {\n if (!this.user) {\n throw new UserNotAuthenticatedError()\n }\n return this.user\n }\n\n /**\n * Get user ID if available.\n * Returns undefined if no user is authenticated.\n */\n getUserId(): string | undefined {\n return this.user?.id\n }\n\n /**\n * Get user ID or throw if not authenticated.\n * Use this when authentication is required.\n */\n requireUserId(): string {\n return this.requireUser().id\n }\n\n /**\n * Get full authentication context or throw if not initialized.\n */\n getAuthInfo(): AuthInfo {\n if (!this.user) {\n throw new ContextNotInitializedError('Authentication')\n }\n return { user: this.user }\n }\n\n /**\n * Get the raw role string from the authenticated user.\n *\n * Reads from `user.role` — apps that use roles should augment {@link AuthUser}\n * with `role: string` (or similar) so this returns a typed value.\n */\n getRole(): string | undefined {\n return (this.user as { role?: string } | undefined)?.role\n }\n\n /**\n * Get the user's roles as an array.\n * Returns an empty array if no role is set or user is not authenticated.\n */\n getRoles(): string[] {\n const role = this.getRole()\n if (!role) return []\n return role.split(',').map(r => r.trim()).filter(Boolean)\n }\n\n /**\n * Check if user is authenticated.\n */\n isAuthenticated(): boolean {\n return !!this.user\n }\n\n /**\n * Clear authentication context.\n * Useful for testing or cleanup.\n */\n clearAuthContext(): void {\n this.user = undefined\n }\n}\n"],"mappings":";;;;AAqCO,IAAA,cAAA,MAAM,YAAY;CACvB;;;;;CAMA,eAAe,MAAsB;EACnC,KAAK,OAAO,KAAK;;;;;;CAOnB,UAAgC;EAC9B,OAAO,KAAK;;;;;CAMd,cAAwB;EACtB,IAAI,CAAC,KAAK,MACR,MAAM,IAAI,2BAA2B;EAEvC,OAAO,KAAK;;;;;;CAOd,YAAgC;EAC9B,OAAO,KAAK,MAAM;;;;;;CAOpB,gBAAwB;EACtB,OAAO,KAAK,aAAa,CAAC;;;;;CAM5B,cAAwB;EACtB,IAAI,CAAC,KAAK,MACR,MAAM,IAAI,2BAA2B,iBAAiB;EAExD,OAAO,EAAE,MAAM,KAAK,MAAM;;;;;;;;CAS5B,UAA8B;EAC5B,OAAQ,KAAK,MAAwC;;;;;;CAOvD,WAAqB;EACnB,MAAM,OAAO,KAAK,SAAS;EAC3B,IAAI,CAAC,MAAM,OAAO,EAAE;EACpB,OAAO,KAAK,MAAM,IAAI,CAAC,KAAI,MAAK,EAAE,MAAM,CAAC,CAAC,OAAO,QAAQ;;;;;CAM3D,kBAA2B;EACzB,OAAO,CAAC,CAAC,KAAK;;;;;;CAOhB,mBAAyB;EACvB,KAAK,OAAO,KAAA;;;0BAxFf,UAAU,UAAU,YAAY,CAAA,EAAA,YAAA"}
@@ -1,6 +0,0 @@
1
- //#region \0@oxc-project+runtime@0.129.0/helpers/decorateMetadata.js
2
- function __decorateMetadata(k, v) {
3
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4
- }
5
- //#endregion
6
- export { __decorateMetadata as t };
@@ -1,25 +0,0 @@
1
- import { ApplicationError, ERROR_CODES } from "stratal/errors";
2
- //#region src/context/errors/context-not-initialized.error.ts
3
- var ContextNotInitializedError = class extends ApplicationError {
4
- constructor(contextType = "Context") {
5
- super("errors.contextNotInitialized", ERROR_CODES.AUTH.CONTEXT_NOT_INITIALIZED, { contextType });
6
- }
7
- };
8
- //#endregion
9
- //#region src/context/errors/user-not-authenticated.error.ts
10
- var UserNotAuthenticatedError = class extends ApplicationError {
11
- constructor() {
12
- super("errors.userNotAuthenticated", ERROR_CODES.AUTH.USER_NOT_AUTHENTICATED);
13
- }
14
- };
15
- //#endregion
16
- //#region src/context/errors/user-not-authorized.error.ts
17
- var UserNotAuthorizedError = class extends ApplicationError {
18
- constructor() {
19
- super("errors.unauthorized", ERROR_CODES.AUTHZ.FORBIDDEN);
20
- }
21
- };
22
- //#endregion
23
- export { UserNotAuthenticatedError as n, ContextNotInitializedError as r, UserNotAuthorizedError as t };
24
-
25
- //# sourceMappingURL=errors-B1vVXc1T.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors-B1vVXc1T.mjs","names":[],"sources":["../src/context/errors/context-not-initialized.error.ts","../src/context/errors/user-not-authenticated.error.ts","../src/context/errors/user-not-authorized.error.ts"],"sourcesContent":["import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class ContextNotInitializedError extends ApplicationError {\n constructor(contextType = 'Context') {\n super(\n 'errors.contextNotInitialized',\n ERROR_CODES.AUTH.CONTEXT_NOT_INITIALIZED,\n { contextType }\n )\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class UserNotAuthenticatedError extends ApplicationError {\n constructor() {\n super(\n 'errors.userNotAuthenticated',\n ERROR_CODES.AUTH.USER_NOT_AUTHENTICATED\n )\n }\n}\n","import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\nexport class UserNotAuthorizedError extends ApplicationError {\n constructor() {\n super(\n 'errors.unauthorized',\n ERROR_CODES.AUTHZ.FORBIDDEN\n )\n }\n}\n"],"mappings":";;AAEA,IAAa,6BAAb,cAAgD,iBAAiB;CAC/D,YAAY,cAAc,WAAW;EACnC,MACE,gCACA,YAAY,KAAK,yBACjB,EAAE,aAAa,CAChB;;;;;ACNL,IAAa,4BAAb,cAA+C,iBAAiB;CAC9D,cAAc;EACZ,MACE,+BACA,YAAY,KAAK,uBAClB;;;;;ACLL,IAAa,yBAAb,cAA4C,iBAAiB;CAC3D,cAAc;EACZ,MACE,uBACA,YAAY,MAAM,UACnB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CCDPF-1Y.d.mts","names":[],"sources":["../src/database/database.module.ts","../src/database/database.service.ts","../src/database/database.tokens.ts","../src/database/decorators/inject-db.decorator.ts","../src/database/errors/database-error.ts","../src/database/errors/database-config.error.ts","../src/database/errors/foreign-key-constraint.error.ts","../src/database/errors/invalid-error-code-range.error.ts","../src/database/errors/record-not-found.error.ts","../src/database/errors/unique-constraint.error.ts","../src/database/errors/from-zenstack-error.ts","../src/database/event-types.ts","../src/database/i18n/en.ts","../src/database/plugins/error-handler.plugin.ts","../src/database/plugins/event-emitter.plugin.ts","../src/database/plugins/schema-switcher.ts","../src/database/commands/zenstack.command.ts","../src/database/commands/db-generate.command.ts","../src/database/commands/db-pull.command.ts","../src/database/commands/db-push.command.ts","../src/database/commands/migrate-deploy.command.ts","../src/database/commands/migrate-dev.command.ts","../src/database/commands/migrate-reset.command.ts","../src/database/commands/migrate-status.command.ts"],"mappings":"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"}
@@ -1,23 +0,0 @@
1
- import { ApplicationError, ERROR_CODES } from "stratal/errors";
2
- //#region src/access-control/errors/insufficient-permissions.error.ts
3
- /**
4
- * InsufficientPermissionsError
5
- *
6
- * Thrown when a user attempts to perform an action without the required permissions.
7
- * Used by AuthGuard after an authorization check fails.
8
- *
9
- * HTTP Status: 403 Forbidden
10
- */
11
- var InsufficientPermissionsError = class extends ApplicationError {
12
- constructor(requiredPermissions, userId) {
13
- const summary = Array.isArray(requiredPermissions) ? requiredPermissions.join(", ") : requiredPermissions;
14
- super("errors.insufficientPermissions", ERROR_CODES.AUTHZ.INSUFFICIENT_PERMISSIONS, {
15
- requiredPermissions: summary,
16
- userId: userId ?? "unknown"
17
- });
18
- }
19
- };
20
- //#endregion
21
- export { InsufficientPermissionsError as t };
22
-
23
- //# sourceMappingURL=insufficient-permissions.error-CRnOHYvq.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"insufficient-permissions.error-CRnOHYvq.mjs","names":[],"sources":["../src/access-control/errors/insufficient-permissions.error.ts"],"sourcesContent":["import { ApplicationError, ERROR_CODES } from 'stratal/errors'\n\n/**\n * InsufficientPermissionsError\n *\n * Thrown when a user attempts to perform an action without the required permissions.\n * Used by AuthGuard after an authorization check fails.\n *\n * HTTP Status: 403 Forbidden\n */\nexport class InsufficientPermissionsError extends ApplicationError {\n constructor(requiredPermissions: string | string[], userId?: string) {\n const summary = Array.isArray(requiredPermissions)\n ? requiredPermissions.join(', ')\n : requiredPermissions\n super('errors.insufficientPermissions', ERROR_CODES.AUTHZ.INSUFFICIENT_PERMISSIONS, {\n requiredPermissions: summary,\n userId: userId ?? 'unknown',\n })\n }\n}\n"],"mappings":";;;;;;;;;;AAUA,IAAa,+BAAb,cAAkD,iBAAiB;CACjE,YAAY,qBAAwC,QAAiB;EACnE,MAAM,UAAU,MAAM,QAAQ,oBAAoB,GAC9C,oBAAoB,KAAK,KAAK,GAC9B;EACJ,MAAM,kCAAkC,YAAY,MAAM,0BAA0B;GAClF,qBAAqB;GACrB,QAAQ,UAAU;GACnB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-BZlcRR2M.d.mts","names":[],"sources":["../src/database/types.ts"],"mappings":";;;;;;AA+BA;;;;;AAAmC;;;;;;;;;;;;;;AAIiC;;;;;;;UAJnD,eAAA;;KAGZ,sBAAA,MACH,CAAA,SAAU,aAAA,0CAAuD,CAAA;;KAG9D,0BAAA,MACH,CAAA,SAAU,aAAA,0CAAuD,CAAA;;KAG9D,mBAAA,MACH,CAAA,SAAU,aAAA,0CAAuD,CAAA;;KAG9D,YAAA,8BACH,OAAA;EAEM,YAAA,EAAc,sBAAA,CAAuB,CAAA,IAAK,YAAA,CAAa,IAAA;EACvD,gBAAA,EAAkB,0BAAA,CAA2B,CAAA,IAAK,YAAA,CAAa,IAAA;EAC/D,SAAA,EAAW,mBAAA,CAAoB,CAAA,IAAK,YAAA,CAAa,IAAA;AAAA;EAEjD,YAAA;EAAkB,gBAAA;EAAsB,SAAA;AAAA;;KAGpC,yBAAA,qBACV,eAAA;EAA0B,OAAA;AAAA,IACtB,CAAA,eAAgB,CAAA,GACd,CAAA,CAAE,CAAA,sBACA,YAAA,CAAa,CAAA,CAAE,CAAA;EACb,YAAA;EAAkB,gBAAA;EAAsB,SAAA;AAAA;EAC1C,YAAA;EAAkB,gBAAA;EAAsB,SAAA;AAAA;EAC1C,YAAA;EAAkB,gBAAA;EAAsB,SAAA;AAAA;;KAGpC,qBAAA,qBACV,eAAA;EAA0B,OAAA;AAAA,IACtB,CAAA,eAAgB,CAAA,GAAI,CAAA,CAAE,CAAA,UAAW,SAAA,GAAY,CAAA,CAAE,CAAA,IAAK,SAAA,GAAY,SAAA,GAChE,SAAA;;KAGM,cAAA,GACV,eAAA;EAA0B,OAAA;AAAA,IACtB,CAAA,OAAQ,CAAA,UAAW,SAAA,GAAY,CAAA,OAAQ,CAAA,IAAK,SAAA,GAC5C,SAAA;;KAGM,cAAA,GACV,eAAA;EAA0B,OAAA;AAAA,UAChB,CAAA,0BAA2B,OAAA,OAAc,CAAA;;KAIzC,qBAAA,GACV,eAAA;EAA0B,iBAAA;AAAA,IAA8C,CAAA;;;;;UAMzD,4BAAA;EACf,IAAA;EACA,MAAA;AAAA"}