@stratal/framework 0.0.17 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-control/index.d.mts +180 -0
- package/dist/access-control/index.d.mts.map +1 -0
- package/dist/access-control/index.mjs +71 -0
- package/dist/access-control/index.mjs.map +1 -0
- package/dist/access.service-BjYVtUJw.mjs +145 -0
- package/dist/access.service-BjYVtUJw.mjs.map +1 -0
- package/dist/auth/index.d.mts +134 -13
- package/dist/auth/index.d.mts.map +1 -1
- package/dist/auth/index.mjs +262 -75
- package/dist/auth/index.mjs.map +1 -1
- package/dist/{auth-context-BD2ApWg1.d.mts → auth-context-BXSkiJ56.d.mts} +14 -1
- package/dist/auth-context-BXSkiJ56.d.mts.map +1 -0
- package/dist/{auth-context-CV3Ko1ew.mjs → auth-context-BberoPal.mjs} +25 -4
- package/dist/auth-context-BberoPal.mjs.map +1 -0
- package/dist/context/index.d.mts +1 -1
- package/dist/context/index.mjs +2 -2
- package/dist/database/index.d.mts +3 -3
- package/dist/database/index.mjs +49 -43
- package/dist/database/index.mjs.map +1 -1
- package/dist/{decorate-RSane8dy.mjs → decorate-CdfCRvAc.mjs} +1 -1
- package/dist/{decorateMetadata-CETItPez.mjs → decorateMetadata-CqtSx3_1.mjs} +1 -1
- package/dist/decorateParam-Dc5DGEpb.mjs +18 -0
- package/dist/decorateParam-Dc5DGEpb.mjs.map +1 -0
- package/dist/{errors-C_KIIU1v.mjs → errors-B1vVXc1T.mjs} +1 -1
- package/dist/{errors-C_KIIU1v.mjs.map → errors-B1vVXc1T.mjs.map} +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/guards/index.d.mts +7 -6
- package/dist/guards/index.d.mts.map +1 -1
- package/dist/guards/index.mjs +39 -30
- package/dist/guards/index.mjs.map +1 -1
- package/dist/{index-eukGTmI8.d.mts → index-CpFBG0Ws.d.mts} +26 -45
- package/dist/index-CpFBG0Ws.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/insufficient-permissions.error-CRnOHYvq.mjs +23 -0
- package/dist/insufficient-permissions.error-CRnOHYvq.mjs.map +1 -0
- package/dist/types-BLyu9dAd.d.mts +11 -0
- package/dist/types-BLyu9dAd.d.mts.map +1 -0
- package/dist/types-BZlcRR2M.d.mts +92 -0
- package/dist/types-BZlcRR2M.d.mts.map +1 -0
- package/package.json +25 -25
- package/dist/auth-context-BD2ApWg1.d.mts.map +0 -1
- package/dist/auth-context-CV3Ko1ew.mjs.map +0 -1
- package/dist/decorateParam-CcTvpNsw.mjs +0 -8
- package/dist/index-eukGTmI8.d.mts.map +0 -1
- package/dist/rbac/index.d.mts +0 -206
- package/dist/rbac/index.d.mts.map +0 -1
- package/dist/rbac/index.mjs +0 -346
- package/dist/rbac/index.mjs.map +0 -1
- package/dist/tokens-Di1ofovy.mjs +0 -32
- package/dist/tokens-Di1ofovy.mjs.map +0 -1
- package/dist/types-Gjk0d2qB.d.mts +0 -47
- package/dist/types-Gjk0d2qB.d.mts.map +0 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/access-control/tokens.ts
|
|
2
|
+
const AC_TOKENS = {
|
|
3
|
+
/** Request-scoped access service */
|
|
4
|
+
AccessService: Symbol.for("stratal:ac:service"),
|
|
5
|
+
/** Access control module options (ac, roles) */
|
|
6
|
+
Options: Symbol.for("stratal:ac:options")
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/decorateParam.js
|
|
10
|
+
function __decorateParam(paramIndex, decorator) {
|
|
11
|
+
return function(target, key) {
|
|
12
|
+
decorator(target, key, paramIndex);
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { AC_TOKENS as n, __decorateParam as t };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=decorateParam-Dc5DGEpb.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorateParam-Dc5DGEpb.mjs","names":[],"sources":["../src/access-control/tokens.ts"],"sourcesContent":["export const AC_TOKENS = {\n /** Request-scoped access service */\n AccessService: Symbol.for('stratal:ac:service'),\n /** Access control module options (ac, roles) */\n Options: Symbol.for('stratal:ac:options'),\n} as const\n"],"mappings":";AAAA,MAAa,YAAY;;CAEvB,eAAe,OAAO,IAAI,qBAAqB;;CAE/C,SAAS,OAAO,IAAI,qBAAqB;CAC1C"}
|
|
@@ -22,4 +22,4 @@ var UserNotAuthorizedError = class extends ApplicationError {
|
|
|
22
22
|
//#endregion
|
|
23
23
|
export { UserNotAuthenticatedError as n, ContextNotInitializedError as r, UserNotAuthorizedError as t };
|
|
24
24
|
|
|
25
|
-
//# sourceMappingURL=errors-
|
|
25
|
+
//# sourceMappingURL=errors-B1vVXc1T.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors-
|
|
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;AACnC,QACE,gCACA,YAAY,KAAK,yBACjB,EAAE,aAAa,CAChB;;;;;ACNL,IAAa,4BAAb,cAA+C,iBAAiB;CAC9D,cAAc;AACZ,QACE,+BACA,YAAY,KAAK,uBAClB;;;;;ACLL,IAAa,yBAAb,cAA4C,iBAAiB;CAC3D,cAAc;AACZ,QACE,uBACA,YAAY,MAAM,UACnB"}
|
package/dist/factory/index.d.mts
CHANGED
package/dist/guards/index.d.mts
CHANGED
|
@@ -6,17 +6,17 @@ import { AuthGuardOptions, AuthGuardOptions as AuthGuardOptions$1, CanActivate,
|
|
|
6
6
|
*
|
|
7
7
|
* Creates a guard class that enforces authentication and optional authorization.
|
|
8
8
|
*
|
|
9
|
-
* **Authentication (no
|
|
9
|
+
* **Authentication (no permissions):**
|
|
10
10
|
* - Checks if user is authenticated via AuthContext.isAuthenticated()
|
|
11
11
|
* - Throws UserNotAuthenticatedError (401) if not authenticated
|
|
12
12
|
*
|
|
13
|
-
* **Authorization (with
|
|
13
|
+
* **Authorization (with permissions):**
|
|
14
14
|
* - First verifies authentication
|
|
15
|
-
* - Then checks permissions via
|
|
15
|
+
* - Then checks permissions via AccessService (reads from AuthContext — no DB hit)
|
|
16
16
|
* - Throws InsufficientPermissionsError (403) if unauthorized
|
|
17
17
|
*
|
|
18
18
|
* @param options - Configuration options
|
|
19
|
-
* @param options.
|
|
19
|
+
* @param options.permissions - Required permissions keyed by resource
|
|
20
20
|
* @returns Guard class for use with @UseGuards decorator
|
|
21
21
|
*
|
|
22
22
|
* @example Authentication only
|
|
@@ -27,8 +27,9 @@ import { AuthGuardOptions, AuthGuardOptions as AuthGuardOptions$1, CanActivate,
|
|
|
27
27
|
*
|
|
28
28
|
* @example Authentication with permissions
|
|
29
29
|
* ```typescript
|
|
30
|
-
* @UseGuards(AuthGuard({
|
|
31
|
-
*
|
|
30
|
+
* @UseGuards(AuthGuard({ permissions: 'posts:update' }))
|
|
31
|
+
* @UseGuards(AuthGuard({ permissions: ['posts:update', 'posts:delete'] }))
|
|
32
|
+
* export class PostsController { }
|
|
32
33
|
* ```
|
|
33
34
|
*/
|
|
34
35
|
declare function AuthGuard(options?: AuthGuardOptions$1): GuardClass$1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/guards/auth.guard.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/guards/auth.guard.ts"],"mappings":";;;;;AAsDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,SAAA,CAAU,OAAA,GAAU,kBAAA,GAAmB,YAAA"}
|
package/dist/guards/index.mjs
CHANGED
|
@@ -1,29 +1,38 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { t as
|
|
3
|
-
import { t as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { n as AC_TOKENS, t as __decorateParam } from "../decorateParam-Dc5DGEpb.mjs";
|
|
2
|
+
import { t as __decorateMetadata } from "../decorateMetadata-CqtSx3_1.mjs";
|
|
3
|
+
import { t as __decorate } from "../decorate-CdfCRvAc.mjs";
|
|
4
|
+
import { n as UserNotAuthenticatedError } from "../errors-B1vVXc1T.mjs";
|
|
5
|
+
import { t as InsufficientPermissionsError } from "../insufficient-permissions.error-CRnOHYvq.mjs";
|
|
6
6
|
import { DI_TOKENS, Transient } from "stratal/di";
|
|
7
|
-
import { inject } from "tsyringe";
|
|
8
|
-
import { GUARD_METADATA_KEY, GuardExecutionService, UseGuards, getControllerGuards, getMethodGuards } from "stratal/guards";
|
|
9
7
|
import { LOGGER_TOKENS } from "stratal/logger";
|
|
8
|
+
import { inject as inject$1 } from "tsyringe";
|
|
9
|
+
import { GUARD_METADATA_KEY, GuardExecutionService, UseGuards, getControllerGuards, getMethodGuards } from "stratal/guards";
|
|
10
10
|
//#region src/guards/auth.guard.ts
|
|
11
|
+
function parsePermissions(raw) {
|
|
12
|
+
return (Array.isArray(raw) ? raw : [raw]).reduce((acc, perm) => {
|
|
13
|
+
const colon = perm.indexOf(":");
|
|
14
|
+
const resource = colon === -1 ? perm : perm.slice(0, colon);
|
|
15
|
+
const action = colon === -1 ? "*" : perm.slice(colon + 1);
|
|
16
|
+
(acc[resource] ??= []).push(action);
|
|
17
|
+
return acc;
|
|
18
|
+
}, {});
|
|
19
|
+
}
|
|
11
20
|
/**
|
|
12
21
|
* AuthGuard Factory
|
|
13
22
|
*
|
|
14
23
|
* Creates a guard class that enforces authentication and optional authorization.
|
|
15
24
|
*
|
|
16
|
-
* **Authentication (no
|
|
25
|
+
* **Authentication (no permissions):**
|
|
17
26
|
* - Checks if user is authenticated via AuthContext.isAuthenticated()
|
|
18
27
|
* - Throws UserNotAuthenticatedError (401) if not authenticated
|
|
19
28
|
*
|
|
20
|
-
* **Authorization (with
|
|
29
|
+
* **Authorization (with permissions):**
|
|
21
30
|
* - First verifies authentication
|
|
22
|
-
* - Then checks permissions via
|
|
31
|
+
* - Then checks permissions via AccessService (reads from AuthContext — no DB hit)
|
|
23
32
|
* - Throws InsufficientPermissionsError (403) if unauthorized
|
|
24
33
|
*
|
|
25
34
|
* @param options - Configuration options
|
|
26
|
-
* @param options.
|
|
35
|
+
* @param options.permissions - Required permissions keyed by resource
|
|
27
36
|
* @returns Guard class for use with @UseGuards decorator
|
|
28
37
|
*
|
|
29
38
|
* @example Authentication only
|
|
@@ -34,51 +43,51 @@ import { LOGGER_TOKENS } from "stratal/logger";
|
|
|
34
43
|
*
|
|
35
44
|
* @example Authentication with permissions
|
|
36
45
|
* ```typescript
|
|
37
|
-
* @UseGuards(AuthGuard({
|
|
38
|
-
*
|
|
46
|
+
* @UseGuards(AuthGuard({ permissions: 'posts:update' }))
|
|
47
|
+
* @UseGuards(AuthGuard({ permissions: ['posts:update', 'posts:delete'] }))
|
|
48
|
+
* export class PostsController { }
|
|
39
49
|
* ```
|
|
40
50
|
*/
|
|
41
51
|
function AuthGuard(options) {
|
|
42
|
-
const
|
|
52
|
+
const rawPermissions = options?.permissions;
|
|
53
|
+
const permissions = rawPermissions ? parsePermissions(rawPermissions) : void 0;
|
|
43
54
|
let ConfiguredAuthGuard = class ConfiguredAuthGuard {
|
|
44
|
-
constructor(authContext, logger,
|
|
55
|
+
constructor(authContext, logger, accessService) {
|
|
45
56
|
this.authContext = authContext;
|
|
46
57
|
this.logger = logger;
|
|
47
|
-
this.
|
|
58
|
+
this.accessService = accessService;
|
|
48
59
|
}
|
|
49
|
-
async canActivate(
|
|
60
|
+
async canActivate(_context) {
|
|
50
61
|
if (!this.authContext.isAuthenticated()) {
|
|
51
62
|
this.logger.debug("Auth guard: User not authenticated");
|
|
52
63
|
throw new UserNotAuthenticatedError();
|
|
53
64
|
}
|
|
54
|
-
if (!
|
|
55
|
-
this.logger.debug("Auth guard: Authentication passed (no
|
|
65
|
+
if (!permissions || Object.keys(permissions).length === 0) {
|
|
66
|
+
this.logger.debug("Auth guard: Authentication passed (no permissions required)");
|
|
56
67
|
return true;
|
|
57
68
|
}
|
|
58
69
|
const userId = this.authContext.getUserId();
|
|
59
70
|
if (!userId) {
|
|
60
71
|
this.logger.debug("Auth guard: No user ID in context");
|
|
61
|
-
throw new InsufficientPermissionsError(
|
|
72
|
+
throw new InsufficientPermissionsError(rawPermissions, void 0);
|
|
62
73
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const hasPermission = await this.casbinService.hasAnyPermission(userId, scopes, httpMethod);
|
|
74
|
+
if (this.accessService) {
|
|
75
|
+
const allowed = await this.accessService.hasPermission(userId, permissions);
|
|
66
76
|
this.logger.debug("Auth guard: Authorization check", {
|
|
67
77
|
userId,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
hasPermission
|
|
78
|
+
permissions,
|
|
79
|
+
allowed
|
|
71
80
|
});
|
|
72
|
-
if (!
|
|
81
|
+
if (!allowed) throw new InsufficientPermissionsError(rawPermissions, userId);
|
|
73
82
|
}
|
|
74
83
|
return true;
|
|
75
84
|
}
|
|
76
85
|
};
|
|
77
86
|
ConfiguredAuthGuard = __decorate([
|
|
78
87
|
Transient(),
|
|
79
|
-
__decorateParam(0, inject(DI_TOKENS.AuthContext)),
|
|
80
|
-
__decorateParam(1, inject(LOGGER_TOKENS.LoggerService)),
|
|
81
|
-
__decorateParam(2, inject(
|
|
88
|
+
__decorateParam(0, inject$1(DI_TOKENS.AuthContext)),
|
|
89
|
+
__decorateParam(1, inject$1(LOGGER_TOKENS.LoggerService)),
|
|
90
|
+
__decorateParam(2, inject$1(AC_TOKENS.AccessService, { isOptional: true })),
|
|
82
91
|
__decorateMetadata("design:paramtypes", [
|
|
83
92
|
Object,
|
|
84
93
|
Object,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"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
|
|
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;AAE1E,SADa,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;AACxD,GAAC,IAAI,cAAc,EAAE,EAAE,KAAK,OAAO;AACpC,SAAO;IACN,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCR,SAAgB,UAAU,SAAwC;CAChE,MAAM,iBAAiB,SAAS;CAChC,MAAM,cAAc,iBAAiB,iBAAiB,eAAe,GAAG,KAAA;CAExE,IAAA,sBAAA,MACM,oBAA2C;EAC/C,YACE,aACA,QACA,eACA;AAHgD,QAAA,cAAA;AACM,QAAA,SAAA;AACkB,QAAA,gBAAA;;EAG1E,MAAM,YAAY,UAA2C;AAC3D,OAAI,CAAC,KAAK,YAAY,iBAAiB,EAAE;AACvC,SAAK,OAAO,MAAM,qCAAqC;AACvD,UAAM,IAAI,2BAA2B;;AAGvC,OAAI,CAAC,eAAe,OAAO,KAAK,YAAY,CAAC,WAAW,GAAG;AACzD,SAAK,OAAO,MAAM,8DAA8D;AAChF,WAAO;;GAGT,MAAM,SAAS,KAAK,YAAY,WAAW;AAC3C,OAAI,CAAC,QAAQ;AACX,SAAK,OAAO,MAAM,oCAAoC;AACtD,UAAM,IAAI,6BAA6B,gBAAiB,KAAA,EAAU;;AAGpE,OAAI,KAAK,eAAe;IACtB,MAAM,UAAU,MAAM,KAAK,cAAc,cAAc,QAAQ,YAAY;AAE3E,SAAK,OAAO,MAAM,mCAAmC;KACnD;KACA;KACA;KACD,CAAC;AAEF,QAAI,CAAC,QACH,OAAM,IAAI,6BAA6B,gBAAiB,OAAO;;AAInE,UAAO;;;;EAvCV,WAAW;qBAGPA,SAAO,UAAU,YAAY,CAAA;qBAC7BA,SAAO,cAAc,cAAc,CAAA;qBACnCA,SAAO,UAAU,eAAe,EAAE,YAAY,MAAM,CAAC,CAAA;;;;;;;AAsC1D,QAAO"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
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";
|
|
2
3
|
import { AsyncModuleOptions, DynamicModule, ModuleContext, OnInitialize, OnShutdown } from "stratal/module";
|
|
3
4
|
import { ApplicationError, ErrorCode } from "stratal/errors";
|
|
4
5
|
import { Command } from "stratal/quarry";
|
|
5
6
|
import { AggregateArgs, AllCrudOperations, AnyPlugin, ClientContract, ClientOptions, CountArgs, CreateArgs, CreateManyArgs, DeleteArgs, DeleteManyArgs, FindFirstArgs, FindManyArgs, FindUniqueArgs, GroupByArgs, ModelResult, RuntimePlugin, UpdateArgs, UpdateManyArgs, UpsertArgs } from "@zenstackhq/orm";
|
|
6
7
|
import { SchemaDef } from "@zenstackhq/schema";
|
|
7
|
-
import { Dialect } from "kysely";
|
|
8
|
-
import { MessageKeys } from "stratal/i18n";
|
|
9
8
|
import { SchemaDef as SchemaDef$1 } from "@zenstackhq/orm/schema";
|
|
10
9
|
import { IEventRegistry } from "stratal/events";
|
|
11
10
|
|
|
@@ -13,7 +12,7 @@ import { IEventRegistry } from "stratal/events";
|
|
|
13
12
|
interface DatabaseConnectionConfig<Schema extends SchemaDef = SchemaDef, Name extends ConnectionName = ConnectionName> {
|
|
14
13
|
name: Name;
|
|
15
14
|
schema: Schema;
|
|
16
|
-
dialect: () =>
|
|
15
|
+
dialect: () => ClientOptions<SchemaDef>['dialect'];
|
|
17
16
|
plugins?: AnyPlugin[];
|
|
18
17
|
}
|
|
19
18
|
interface DatabaseModuleConfig {
|
|
@@ -31,18 +30,19 @@ declare class DatabaseModule implements OnInitialize, OnShutdown {
|
|
|
31
30
|
/**
|
|
32
31
|
* DatabaseService type
|
|
33
32
|
*
|
|
34
|
-
* Each connection has its own schema
|
|
33
|
+
* Each connection has its own schema and plugin extensions.
|
|
34
|
+
* Plugin extension types are automatically inferred from `StratalDatabase.plugins`.
|
|
35
35
|
*
|
|
36
36
|
* @example
|
|
37
37
|
* ```typescript
|
|
38
|
-
* // Typed to default connection
|
|
38
|
+
* // Typed to default connection (includes plugin extensions)
|
|
39
39
|
* constructor(@inject(DI_TOKENS.Database) private db: DatabaseService) {}
|
|
40
40
|
*
|
|
41
41
|
* // Typed to a specific named connection
|
|
42
42
|
* constructor(@InjectDB('analytics') private analytics: DatabaseService<'analytics'>) {}
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
|
-
type DatabaseService<K extends ConnectionName = DefaultConnectionName> = ClientContract<InferConnectionSchema<K>, ClientOptions<InferConnectionSchema<K
|
|
45
|
+
type DatabaseService<K extends ConnectionName = DefaultConnectionName> = ClientContract<InferConnectionSchema<K>, ClientOptions<InferConnectionSchema<K>>, InferConnectionExtensions<K>['extQueryArgs'], InferConnectionExtensions<K>['extClientMembers'], InferConnectionExtensions<K>['extResult']>;
|
|
46
46
|
//#endregion
|
|
47
47
|
//#region src/database/database.tokens.d.ts
|
|
48
48
|
declare const DATABASE_TOKENS: {
|
|
@@ -286,8 +286,8 @@ declare module 'stratal/events' {
|
|
|
286
286
|
}
|
|
287
287
|
//#endregion
|
|
288
288
|
//#region src/database/i18n/en.d.ts
|
|
289
|
-
declare const
|
|
290
|
-
readonly
|
|
289
|
+
declare const databaseMessages: {
|
|
290
|
+
readonly en: {
|
|
291
291
|
readonly connectionNameRequired: "Connection name is required";
|
|
292
292
|
readonly defaultConnectionRequired: "Default connection name is required";
|
|
293
293
|
readonly connectionRequired: "At least one connection is required";
|
|
@@ -296,8 +296,8 @@ declare const databaseI18n: {
|
|
|
296
296
|
};
|
|
297
297
|
};
|
|
298
298
|
declare module 'stratal/i18n' {
|
|
299
|
-
interface
|
|
300
|
-
database: typeof
|
|
299
|
+
interface AppMessageNamespaces {
|
|
300
|
+
database: typeof databaseMessages['en'];
|
|
301
301
|
}
|
|
302
302
|
} //# sourceMappingURL=en.d.ts.map
|
|
303
303
|
//#endregion
|
|
@@ -313,7 +313,7 @@ declare module 'stratal/i18n' {
|
|
|
313
313
|
* })
|
|
314
314
|
* ```
|
|
315
315
|
*/
|
|
316
|
-
declare class ErrorHandlerPlugin implements RuntimePlugin<SchemaDef$1, Record<string, unknown>, Record<string, unknown
|
|
316
|
+
declare class ErrorHandlerPlugin implements RuntimePlugin<SchemaDef$1, Record<string, unknown>, Record<string, unknown>, {}> {
|
|
317
317
|
readonly id = "error-handler";
|
|
318
318
|
onQuery: ({
|
|
319
319
|
args,
|
|
@@ -347,7 +347,7 @@ interface EventEmitterPluginOptions {
|
|
|
347
347
|
* })
|
|
348
348
|
* ```
|
|
349
349
|
*/
|
|
350
|
-
declare class EventEmitterPlugin implements RuntimePlugin<SchemaDef$1, Record<string, unknown>, Record<string, unknown
|
|
350
|
+
declare class EventEmitterPlugin implements RuntimePlugin<SchemaDef$1, Record<string, unknown>, Record<string, unknown>, {}> {
|
|
351
351
|
private options;
|
|
352
352
|
readonly id = "event-emitter";
|
|
353
353
|
constructor(options: EventEmitterPluginOptions);
|
|
@@ -364,39 +364,20 @@ declare class EventEmitterPlugin implements RuntimePlugin<SchemaDef$1, Record<st
|
|
|
364
364
|
}) => Promise<unknown>;
|
|
365
365
|
}
|
|
366
366
|
//#endregion
|
|
367
|
-
//#region src/database/plugins/schema-switcher.
|
|
368
|
-
interface SchemaSwitcherPluginOptions {
|
|
369
|
-
schemaName: string;
|
|
370
|
-
}
|
|
367
|
+
//#region src/database/plugins/schema-switcher.d.ts
|
|
371
368
|
/**
|
|
372
|
-
*
|
|
373
|
-
*
|
|
369
|
+
* Switches the active schema on a ZenStack/Kysely database client by mutating
|
|
370
|
+
* `$schema.provider.defaultSchema`. This causes ZenStack's QueryNameMapper to
|
|
371
|
+
* generate fully-qualified table references (e.g. `"tenant_123"."User"`).
|
|
374
372
|
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
* new SchemaSwitcherPlugin({ schemaName: `tenant_${tenantId}` })
|
|
381
|
-
* ]
|
|
382
|
-
* })
|
|
383
|
-
* ```
|
|
373
|
+
* Must be called BEFORE any queries are made on the client.
|
|
374
|
+
*
|
|
375
|
+
* Note: The ZenStack RuntimePlugin `onQuery` hook fires after table names are
|
|
376
|
+
* already resolved, so a plugin-based approach cannot set the schema prefix.
|
|
377
|
+
* Direct client mutation is the only supported method.
|
|
384
378
|
*/
|
|
385
|
-
declare class
|
|
386
|
-
|
|
387
|
-
readonly id = "schema-switcher";
|
|
388
|
-
constructor(options: SchemaSwitcherPluginOptions);
|
|
389
|
-
onQuery: ({
|
|
390
|
-
args,
|
|
391
|
-
proceed,
|
|
392
|
-
client
|
|
393
|
-
}: {
|
|
394
|
-
args: Record<string, unknown> | undefined;
|
|
395
|
-
proceed: (args: Record<string, unknown> | undefined) => Promise<unknown>;
|
|
396
|
-
client: {
|
|
397
|
-
$executeRawUnsafe: (sql: string) => Promise<unknown>;
|
|
398
|
-
};
|
|
399
|
-
}) => Promise<unknown>;
|
|
379
|
+
declare class SchemaSwitcher {
|
|
380
|
+
static apply<T>(client: T, schemaName: string): T;
|
|
400
381
|
}
|
|
401
382
|
//#endregion
|
|
402
383
|
//#region src/database/commands/zenstack.command.d.ts
|
|
@@ -457,5 +438,5 @@ declare class MigrateStatusCommand extends ZenStackCommand {
|
|
|
457
438
|
handle(): Promise<number>;
|
|
458
439
|
}
|
|
459
440
|
//#endregion
|
|
460
|
-
export {
|
|
461
|
-
//# sourceMappingURL=index-
|
|
441
|
+
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 };
|
|
442
|
+
//# sourceMappingURL=index-CpFBG0Ws.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-CpFBG0Ws.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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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as InferConnectionSchema, i as InferConnectionExtensions, n as DefaultConnectionName, r as InferAnySchema, s as StratalDatabase, t as ConnectionName } from "./types-BZlcRR2M.mjs";
|
|
2
2
|
import { CustomEventRegistry, EventName } from "stratal/events";
|
|
3
|
-
export { type ConnectionName, type CustomEventRegistry, type DefaultConnectionName, type EventName, type InferAnySchema, type InferConnectionSchema, type StratalDatabase };
|
|
3
|
+
export { type ConnectionName, type CustomEventRegistry, type DefaultConnectionName, type EventName, type InferAnySchema, type InferConnectionExtensions, type InferConnectionSchema, type StratalDatabase };
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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;AACJ,QAAM,kCAAkC,YAAY,MAAM,0BAA0B;GAClF,qBAAqB;GACrB,QAAQ,UAAU;GACnB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AccessControl, Role, Statements } from "better-auth/plugins/access";
|
|
2
|
+
|
|
3
|
+
//#region src/access-control/types.d.ts
|
|
4
|
+
type RolePermissions<TStatements extends Statements> = { [K in keyof TStatements]?: readonly TStatements[K][number][] };
|
|
5
|
+
interface AccessControlOptions<TStatements extends Statements = Statements, TRoles extends Record<string, RolePermissions<TStatements>> = Record<string, RolePermissions<TStatements>>> {
|
|
6
|
+
ac: AccessControl;
|
|
7
|
+
roles: { [K in keyof TRoles]: Role };
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { RolePermissions as n, AccessControlOptions as t };
|
|
11
|
+
//# sourceMappingURL=types-BLyu9dAd.d.mts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { RuntimePlugin } from "@zenstackhq/orm";
|
|
2
|
+
import { SchemaDef } from "@zenstackhq/schema";
|
|
3
|
+
|
|
4
|
+
//#region src/database/types.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Augment with per-connection schemas, default connection, and plugin types.
|
|
7
|
+
*
|
|
8
|
+
* Each property can be augmented in a separate file — TypeScript merges them.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // db/schema.ts
|
|
13
|
+
* declare module '@stratal/framework/database' {
|
|
14
|
+
* interface StratalDatabase {
|
|
15
|
+
* schemas: {
|
|
16
|
+
* main: typeof schema
|
|
17
|
+
* tenant: typeof tenantSchema
|
|
18
|
+
* }
|
|
19
|
+
* defaultConnection: 'main'
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* // db/plugins.ts
|
|
24
|
+
* declare module '@stratal/framework/database' {
|
|
25
|
+
* interface StratalDatabase {
|
|
26
|
+
* plugins: {
|
|
27
|
+
* main: [typeof queryResultPlugin, typeof cachePlugin]
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
interface StratalDatabase {}
|
|
34
|
+
/** Extract `ExtQueryArgs` from a `RuntimePlugin` */
|
|
35
|
+
type ExtractPluginQueryArgs<P> = P extends RuntimePlugin<infer _S, infer Q, infer _M, infer _R> ? Q : {};
|
|
36
|
+
/** Extract `ExtClientMembers` from a `RuntimePlugin` */
|
|
37
|
+
type ExtractPluginClientMembers<P> = P extends RuntimePlugin<infer _S, infer _Q, infer M, infer _R> ? M : {};
|
|
38
|
+
/** Extract `ExtResult` from a `RuntimePlugin` */
|
|
39
|
+
type ExtractPluginResult<P> = P extends RuntimePlugin<infer _S, infer _Q, infer _M, infer R> ? R : {};
|
|
40
|
+
/** Recursively intersect extension types from a tuple of plugins */
|
|
41
|
+
type MergePlugins<Plugins extends unknown[]> = Plugins extends [infer P, ...infer Rest] ? {
|
|
42
|
+
extQueryArgs: ExtractPluginQueryArgs<P> & MergePlugins<Rest>['extQueryArgs'];
|
|
43
|
+
extClientMembers: ExtractPluginClientMembers<P> & MergePlugins<Rest>['extClientMembers'];
|
|
44
|
+
extResult: ExtractPluginResult<P> & MergePlugins<Rest>['extResult'];
|
|
45
|
+
} : {
|
|
46
|
+
extQueryArgs: {};
|
|
47
|
+
extClientMembers: {};
|
|
48
|
+
extResult: {};
|
|
49
|
+
};
|
|
50
|
+
/** Infer merged plugin extensions for a connection */
|
|
51
|
+
type InferConnectionExtensions<K extends string> = StratalDatabase extends {
|
|
52
|
+
plugins: infer P;
|
|
53
|
+
} ? K extends keyof P ? P[K] extends unknown[] ? MergePlugins<P[K]> : {
|
|
54
|
+
extQueryArgs: {};
|
|
55
|
+
extClientMembers: {};
|
|
56
|
+
extResult: {};
|
|
57
|
+
} : {
|
|
58
|
+
extQueryArgs: {};
|
|
59
|
+
extClientMembers: {};
|
|
60
|
+
extResult: {};
|
|
61
|
+
} : {
|
|
62
|
+
extQueryArgs: {};
|
|
63
|
+
extClientMembers: {};
|
|
64
|
+
extResult: {};
|
|
65
|
+
};
|
|
66
|
+
/** Infer schema type for a specific connection */
|
|
67
|
+
type InferConnectionSchema<K extends string> = StratalDatabase extends {
|
|
68
|
+
schemas: infer R;
|
|
69
|
+
} ? K extends keyof R ? R[K] extends SchemaDef ? R[K] : SchemaDef : SchemaDef : SchemaDef;
|
|
70
|
+
/** Union of ALL schemas across connections (for events) */
|
|
71
|
+
type InferAnySchema = StratalDatabase extends {
|
|
72
|
+
schemas: infer R;
|
|
73
|
+
} ? R[keyof R] extends SchemaDef ? R[keyof R] : SchemaDef : SchemaDef;
|
|
74
|
+
/** Connection name — derived from schemas keys */
|
|
75
|
+
type ConnectionName = StratalDatabase extends {
|
|
76
|
+
schemas: infer R;
|
|
77
|
+
} ? keyof R extends never ? string : Extract<keyof R, string> : string;
|
|
78
|
+
/** Default connection name */
|
|
79
|
+
type DefaultConnectionName = StratalDatabase extends {
|
|
80
|
+
defaultConnection: infer N extends string;
|
|
81
|
+
} ? N : string;
|
|
82
|
+
/**
|
|
83
|
+
* Internal context used by database service for dynamic event emission
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
interface InternalDatabaseEventContext {
|
|
87
|
+
data: unknown;
|
|
88
|
+
result?: unknown;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|