@grantjs/server 1.0.0 → 1.1.0

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 (63) hide show
  1. package/README.md +1 -1
  2. package/dist/debug-DICR8lwQ.js +15 -0
  3. package/dist/debug-DICR8lwQ.js.map +1 -0
  4. package/dist/debug-DInHA4QB.cjs +20 -0
  5. package/dist/debug-DInHA4QB.cjs.map +1 -0
  6. package/dist/errors-BUeTn_3G.cjs +91 -0
  7. package/dist/errors-BUeTn_3G.cjs.map +1 -0
  8. package/dist/errors-CSC_Z_KP.js +62 -0
  9. package/dist/errors-CSC_Z_KP.js.map +1 -0
  10. package/dist/express/index.d.ts +3 -3
  11. package/dist/express/index.d.ts.map +1 -1
  12. package/dist/express/middleware.d.ts +2 -2
  13. package/dist/express/middleware.d.ts.map +1 -1
  14. package/dist/express.cjs +106 -95
  15. package/dist/express.cjs.map +1 -1
  16. package/dist/express.mjs +101 -99
  17. package/dist/express.mjs.map +1 -1
  18. package/dist/fastify/index.d.ts +4 -4
  19. package/dist/fastify/index.d.ts.map +1 -1
  20. package/dist/fastify/plugin.d.ts +2 -2
  21. package/dist/fastify/plugin.d.ts.map +1 -1
  22. package/dist/fastify.cjs +133 -97
  23. package/dist/fastify.cjs.map +1 -1
  24. package/dist/fastify.mjs +128 -101
  25. package/dist/fastify.mjs.map +1 -1
  26. package/dist/grant-client-f6IKMyk5.cjs +228 -0
  27. package/dist/grant-client-f6IKMyk5.cjs.map +1 -0
  28. package/dist/grant-client-t3KadxFo.js +205 -0
  29. package/dist/grant-client-t3KadxFo.js.map +1 -0
  30. package/dist/grant-client.d.ts +1 -1
  31. package/dist/grant-client.d.ts.map +1 -1
  32. package/dist/index.cjs +10 -49
  33. package/dist/index.d.ts +4 -4
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.mjs +3 -50
  36. package/dist/nest/grant.guard.d.ts +1 -1
  37. package/dist/nest/grant.guard.d.ts.map +1 -1
  38. package/dist/nest/grant.module.d.ts.map +1 -1
  39. package/dist/nest/index.d.ts +6 -6
  40. package/dist/nest/index.d.ts.map +1 -1
  41. package/dist/nest.cjs +163 -143
  42. package/dist/nest.cjs.map +1 -1
  43. package/dist/nest.mjs +150 -149
  44. package/dist/nest.mjs.map +1 -1
  45. package/dist/next/index.d.ts +4 -4
  46. package/dist/next/index.d.ts.map +1 -1
  47. package/dist/next/with-grant.d.ts +1 -1
  48. package/dist/next/with-grant.d.ts.map +1 -1
  49. package/dist/next.cjs +75 -58
  50. package/dist/next.cjs.map +1 -1
  51. package/dist/next.mjs +70 -60
  52. package/dist/next.mjs.map +1 -1
  53. package/package.json +17 -17
  54. package/dist/debug-C8ibbrE5.js +0 -9
  55. package/dist/debug-C8ibbrE5.js.map +0 -1
  56. package/dist/debug-Crb5gNDM.cjs +0 -8
  57. package/dist/debug-Crb5gNDM.cjs.map +0 -1
  58. package/dist/grant-client-D1LZI2f4.js +0 -180
  59. package/dist/grant-client-D1LZI2f4.js.map +0 -1
  60. package/dist/grant-client-DywfJN5P.cjs +0 -179
  61. package/dist/grant-client-DywfJN5P.cjs.map +0 -1
  62. package/dist/index.cjs.map +0 -1
  63. package/dist/index.mjs.map +0 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Server SDK for Grant authorization platform. Provides middleware and guards for **Express**, **Fastify**, **NestJS**, and **Next.js** applications.
4
4
 
5
- **Documentation:** [Server SDK](https://github.com/logusgraphics/grant/blob/main/docs/integration/server-sdk.md) in the official docs.
5
+ **Documentation:** [Server SDK](https://github.com/grant-js/grant/blob/main/docs/integration/server-sdk.md) in the official docs.
6
6
 
7
7
  ## Features
8
8
 
@@ -0,0 +1,15 @@
1
+ //#region src/utils/debug.ts
2
+ var DEBUG_GRANT_ENV = "DEBUG_GRANT";
3
+ /**
4
+ * Log Grant integration debug info when DEBUG_GRANT=1.
5
+ * Used by Express middleware, Fastify grant hook, Next withGrant, and Nest GrantGuard.
6
+ * Set DEBUG_GRANT=1 in .env or the environment to see resource, action, and outcome in development.
7
+ */
8
+ function debugGrant(integration, data) {
9
+ if (process.env[DEBUG_GRANT_ENV] !== "1") return;
10
+ console.debug(`[Grant ${integration}]`, data);
11
+ }
12
+ //#endregion
13
+ export { debugGrant as t };
14
+
15
+ //# sourceMappingURL=debug-DICR8lwQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-DICR8lwQ.js","names":[],"sources":["../src/utils/debug.ts"],"sourcesContent":["const DEBUG_GRANT_ENV = 'DEBUG_GRANT';\n\n/** Whether Grant debug logging is enabled (set DEBUG_GRANT=1 in development). */\nexport function isDebugGrant(): boolean {\n return process.env[DEBUG_GRANT_ENV] === '1';\n}\n\n/**\n * Log Grant integration debug info when DEBUG_GRANT=1.\n * Used by Express middleware, Fastify grant hook, Next withGrant, and Nest GrantGuard.\n * Set DEBUG_GRANT=1 in .env or the environment to see resource, action, and outcome in development.\n */\nexport function debugGrant(integration: string, data: Record<string, unknown>): void {\n if (process.env[DEBUG_GRANT_ENV] !== '1') return;\n console.debug(`[Grant ${integration}]`, data);\n}\n"],"mappings":";AAAA,IAAM,kBAAkB;;;;;;AAYxB,SAAgB,WAAW,aAAqB,MAAqC;AACnF,KAAI,QAAQ,IAAI,qBAAqB,IAAK;AAC1C,SAAQ,MAAM,UAAU,YAAY,IAAI,KAAK"}
@@ -0,0 +1,20 @@
1
+ //#region src/utils/debug.ts
2
+ var DEBUG_GRANT_ENV = "DEBUG_GRANT";
3
+ /**
4
+ * Log Grant integration debug info when DEBUG_GRANT=1.
5
+ * Used by Express middleware, Fastify grant hook, Next withGrant, and Nest GrantGuard.
6
+ * Set DEBUG_GRANT=1 in .env or the environment to see resource, action, and outcome in development.
7
+ */
8
+ function debugGrant(integration, data) {
9
+ if (process.env[DEBUG_GRANT_ENV] !== "1") return;
10
+ console.debug(`[Grant ${integration}]`, data);
11
+ }
12
+ //#endregion
13
+ Object.defineProperty(exports, "debugGrant", {
14
+ enumerable: true,
15
+ get: function() {
16
+ return debugGrant;
17
+ }
18
+ });
19
+
20
+ //# sourceMappingURL=debug-DInHA4QB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-DInHA4QB.cjs","names":[],"sources":["../src/utils/debug.ts"],"sourcesContent":["const DEBUG_GRANT_ENV = 'DEBUG_GRANT';\n\n/** Whether Grant debug logging is enabled (set DEBUG_GRANT=1 in development). */\nexport function isDebugGrant(): boolean {\n return process.env[DEBUG_GRANT_ENV] === '1';\n}\n\n/**\n * Log Grant integration debug info when DEBUG_GRANT=1.\n * Used by Express middleware, Fastify grant hook, Next withGrant, and Nest GrantGuard.\n * Set DEBUG_GRANT=1 in .env or the environment to see resource, action, and outcome in development.\n */\nexport function debugGrant(integration: string, data: Record<string, unknown>): void {\n if (process.env[DEBUG_GRANT_ENV] !== '1') return;\n console.debug(`[Grant ${integration}]`, data);\n}\n"],"mappings":";AAAA,IAAM,kBAAkB;;;;;;AAYxB,SAAgB,WAAW,aAAqB,MAAqC;AACnF,KAAI,QAAQ,IAAI,qBAAqB,IAAK;AAC1C,SAAQ,MAAM,UAAU,YAAY,IAAI,KAAK"}
@@ -0,0 +1,91 @@
1
+ //#region src/errors.ts
2
+ /**
3
+ * Base error class for Grant server errors
4
+ */
5
+ var GrantServerError = class GrantServerError extends Error {
6
+ constructor(message, code, statusCode = 500) {
7
+ super(message);
8
+ this.code = code;
9
+ this.statusCode = statusCode;
10
+ this.name = "GrantServerError";
11
+ Object.setPrototypeOf(this, GrantServerError.prototype);
12
+ }
13
+ };
14
+ /**
15
+ * Authentication error (401)
16
+ * Thrown when user is not authenticated
17
+ */
18
+ var AuthenticationError = class AuthenticationError extends GrantServerError {
19
+ constructor(message = "Unauthorized", code = "UNAUTHENTICATED") {
20
+ super(message, code, 401);
21
+ this.name = "AuthenticationError";
22
+ Object.setPrototypeOf(this, AuthenticationError.prototype);
23
+ }
24
+ };
25
+ /**
26
+ * Authorization error (403)
27
+ * Thrown when user is authenticated but lacks required permission
28
+ */
29
+ var AuthorizationError = class AuthorizationError extends GrantServerError {
30
+ constructor(message = "Forbidden", code = "FORBIDDEN", reason) {
31
+ super(message, code, 403);
32
+ this.reason = reason;
33
+ this.name = "AuthorizationError";
34
+ Object.setPrototypeOf(this, AuthorizationError.prototype);
35
+ }
36
+ };
37
+ /**
38
+ * Bad request error (400)
39
+ * Thrown when request is malformed or missing required data
40
+ */
41
+ var BadRequestError = class BadRequestError extends GrantServerError {
42
+ constructor(message = "Bad Request", code = "BAD_REQUEST") {
43
+ super(message, code, 400);
44
+ this.name = "BadRequestError";
45
+ Object.setPrototypeOf(this, BadRequestError.prototype);
46
+ }
47
+ };
48
+ /**
49
+ * Not found error (404)
50
+ * Thrown when resource is not found
51
+ */
52
+ var NotFoundError = class NotFoundError extends GrantServerError {
53
+ constructor(message = "Not Found", code = "NOT_FOUND") {
54
+ super(message, code, 404);
55
+ this.name = "NotFoundError";
56
+ Object.setPrototypeOf(this, NotFoundError.prototype);
57
+ }
58
+ };
59
+ //#endregion
60
+ Object.defineProperty(exports, "AuthenticationError", {
61
+ enumerable: true,
62
+ get: function() {
63
+ return AuthenticationError;
64
+ }
65
+ });
66
+ Object.defineProperty(exports, "AuthorizationError", {
67
+ enumerable: true,
68
+ get: function() {
69
+ return AuthorizationError;
70
+ }
71
+ });
72
+ Object.defineProperty(exports, "BadRequestError", {
73
+ enumerable: true,
74
+ get: function() {
75
+ return BadRequestError;
76
+ }
77
+ });
78
+ Object.defineProperty(exports, "GrantServerError", {
79
+ enumerable: true,
80
+ get: function() {
81
+ return GrantServerError;
82
+ }
83
+ });
84
+ Object.defineProperty(exports, "NotFoundError", {
85
+ enumerable: true,
86
+ get: function() {
87
+ return NotFoundError;
88
+ }
89
+ });
90
+
91
+ //# sourceMappingURL=errors-BUeTn_3G.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-BUeTn_3G.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Base error class for Grant server errors\n */\nexport class GrantServerError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode: number = 500\n ) {\n super(message);\n this.name = 'GrantServerError';\n Object.setPrototypeOf(this, GrantServerError.prototype);\n }\n}\n\n/**\n * Authentication error (401)\n * Thrown when user is not authenticated\n */\nexport class AuthenticationError extends GrantServerError {\n constructor(message: string = 'Unauthorized', code: string = 'UNAUTHENTICATED') {\n super(message, code, 401);\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Authorization error (403)\n * Thrown when user is authenticated but lacks required permission\n */\nexport class AuthorizationError extends GrantServerError {\n constructor(\n message: string = 'Forbidden',\n code: string = 'FORBIDDEN',\n public readonly reason?: string\n ) {\n super(message, code, 403);\n this.name = 'AuthorizationError';\n Object.setPrototypeOf(this, AuthorizationError.prototype);\n }\n}\n\n/**\n * Bad request error (400)\n * Thrown when request is malformed or missing required data\n */\nexport class BadRequestError extends GrantServerError {\n constructor(message: string = 'Bad Request', code: string = 'BAD_REQUEST') {\n super(message, code, 400);\n this.name = 'BadRequestError';\n Object.setPrototypeOf(this, BadRequestError.prototype);\n }\n}\n\n/**\n * Not found error (404)\n * Thrown when resource is not found\n */\nexport class NotFoundError extends GrantServerError {\n constructor(message: string = 'Not Found', code: string = 'NOT_FOUND') {\n super(message, code, 404);\n this.name = 'NotFoundError';\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n"],"mappings":";;;;AAGA,IAAa,mBAAb,MAAa,yBAAyB,MAAM;CAC1C,YACE,SACA,MACA,aAAqC,KACrC;AACA,QAAM,QAAQ;AAHE,OAAA,OAAA;AACA,OAAA,aAAA;AAGhB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,iBAAiB,UAAU;;;;;;;AAQ3D,IAAa,sBAAb,MAAa,4BAA4B,iBAAiB;CACxD,YAAY,UAAkB,gBAAgB,OAAe,mBAAmB;AAC9E,QAAM,SAAS,MAAM,IAAI;AACzB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,oBAAoB,UAAU;;;;;;;AAQ9D,IAAa,qBAAb,MAAa,2BAA2B,iBAAiB;CACvD,YACE,UAAkB,aAClB,OAAe,aACf,QACA;AACA,QAAM,SAAS,MAAM,IAAI;AAFT,OAAA,SAAA;AAGhB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,mBAAmB,UAAU;;;;;;;AAQ7D,IAAa,kBAAb,MAAa,wBAAwB,iBAAiB;CACpD,YAAY,UAAkB,eAAe,OAAe,eAAe;AACzE,QAAM,SAAS,MAAM,IAAI;AACzB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,gBAAgB,UAAU;;;;;;;AAQ1D,IAAa,gBAAb,MAAa,sBAAsB,iBAAiB;CAClD,YAAY,UAAkB,aAAa,OAAe,aAAa;AACrE,QAAM,SAAS,MAAM,IAAI;AACzB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,cAAc,UAAU"}
@@ -0,0 +1,62 @@
1
+ //#region src/errors.ts
2
+ /**
3
+ * Base error class for Grant server errors
4
+ */
5
+ var GrantServerError = class GrantServerError extends Error {
6
+ constructor(message, code, statusCode = 500) {
7
+ super(message);
8
+ this.code = code;
9
+ this.statusCode = statusCode;
10
+ this.name = "GrantServerError";
11
+ Object.setPrototypeOf(this, GrantServerError.prototype);
12
+ }
13
+ };
14
+ /**
15
+ * Authentication error (401)
16
+ * Thrown when user is not authenticated
17
+ */
18
+ var AuthenticationError = class AuthenticationError extends GrantServerError {
19
+ constructor(message = "Unauthorized", code = "UNAUTHENTICATED") {
20
+ super(message, code, 401);
21
+ this.name = "AuthenticationError";
22
+ Object.setPrototypeOf(this, AuthenticationError.prototype);
23
+ }
24
+ };
25
+ /**
26
+ * Authorization error (403)
27
+ * Thrown when user is authenticated but lacks required permission
28
+ */
29
+ var AuthorizationError = class AuthorizationError extends GrantServerError {
30
+ constructor(message = "Forbidden", code = "FORBIDDEN", reason) {
31
+ super(message, code, 403);
32
+ this.reason = reason;
33
+ this.name = "AuthorizationError";
34
+ Object.setPrototypeOf(this, AuthorizationError.prototype);
35
+ }
36
+ };
37
+ /**
38
+ * Bad request error (400)
39
+ * Thrown when request is malformed or missing required data
40
+ */
41
+ var BadRequestError = class BadRequestError extends GrantServerError {
42
+ constructor(message = "Bad Request", code = "BAD_REQUEST") {
43
+ super(message, code, 400);
44
+ this.name = "BadRequestError";
45
+ Object.setPrototypeOf(this, BadRequestError.prototype);
46
+ }
47
+ };
48
+ /**
49
+ * Not found error (404)
50
+ * Thrown when resource is not found
51
+ */
52
+ var NotFoundError = class NotFoundError extends GrantServerError {
53
+ constructor(message = "Not Found", code = "NOT_FOUND") {
54
+ super(message, code, 404);
55
+ this.name = "NotFoundError";
56
+ Object.setPrototypeOf(this, NotFoundError.prototype);
57
+ }
58
+ };
59
+ //#endregion
60
+ export { NotFoundError as a, GrantServerError as i, AuthorizationError as n, BadRequestError as r, AuthenticationError as t };
61
+
62
+ //# sourceMappingURL=errors-CSC_Z_KP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-CSC_Z_KP.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Base error class for Grant server errors\n */\nexport class GrantServerError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly statusCode: number = 500\n ) {\n super(message);\n this.name = 'GrantServerError';\n Object.setPrototypeOf(this, GrantServerError.prototype);\n }\n}\n\n/**\n * Authentication error (401)\n * Thrown when user is not authenticated\n */\nexport class AuthenticationError extends GrantServerError {\n constructor(message: string = 'Unauthorized', code: string = 'UNAUTHENTICATED') {\n super(message, code, 401);\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Authorization error (403)\n * Thrown when user is authenticated but lacks required permission\n */\nexport class AuthorizationError extends GrantServerError {\n constructor(\n message: string = 'Forbidden',\n code: string = 'FORBIDDEN',\n public readonly reason?: string\n ) {\n super(message, code, 403);\n this.name = 'AuthorizationError';\n Object.setPrototypeOf(this, AuthorizationError.prototype);\n }\n}\n\n/**\n * Bad request error (400)\n * Thrown when request is malformed or missing required data\n */\nexport class BadRequestError extends GrantServerError {\n constructor(message: string = 'Bad Request', code: string = 'BAD_REQUEST') {\n super(message, code, 400);\n this.name = 'BadRequestError';\n Object.setPrototypeOf(this, BadRequestError.prototype);\n }\n}\n\n/**\n * Not found error (404)\n * Thrown when resource is not found\n */\nexport class NotFoundError extends GrantServerError {\n constructor(message: string = 'Not Found', code: string = 'NOT_FOUND') {\n super(message, code, 404);\n this.name = 'NotFoundError';\n Object.setPrototypeOf(this, NotFoundError.prototype);\n }\n}\n"],"mappings":";;;;AAGA,IAAa,mBAAb,MAAa,yBAAyB,MAAM;CAC1C,YACE,SACA,MACA,aAAqC,KACrC;AACA,QAAM,QAAQ;AAHE,OAAA,OAAA;AACA,OAAA,aAAA;AAGhB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,iBAAiB,UAAU;;;;;;;AAQ3D,IAAa,sBAAb,MAAa,4BAA4B,iBAAiB;CACxD,YAAY,UAAkB,gBAAgB,OAAe,mBAAmB;AAC9E,QAAM,SAAS,MAAM,IAAI;AACzB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,oBAAoB,UAAU;;;;;;;AAQ9D,IAAa,qBAAb,MAAa,2BAA2B,iBAAiB;CACvD,YACE,UAAkB,aAClB,OAAe,aACf,QACA;AACA,QAAM,SAAS,MAAM,IAAI;AAFT,OAAA,SAAA;AAGhB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,mBAAmB,UAAU;;;;;;;AAQ7D,IAAa,kBAAb,MAAa,wBAAwB,iBAAiB;CACpD,YAAY,UAAkB,eAAe,OAAe,eAAe;AACzE,QAAM,SAAS,MAAM,IAAI;AACzB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,gBAAgB,UAAU;;;;;;;AAQ1D,IAAa,gBAAb,MAAa,sBAAsB,iBAAiB;CAClD,YAAY,UAAkB,aAAa,OAAe,aAAa;AACrE,QAAM,SAAS,MAAM,IAAI;AACzB,OAAK,OAAO;AACZ,SAAO,eAAe,MAAM,cAAc,UAAU"}
@@ -1,6 +1,6 @@
1
+ export type { AuthorizedRequest, GrantOptions } from './middleware';
1
2
  export { grant } from './middleware';
2
- export type { GrantOptions, AuthorizedRequest } from './middleware';
3
- export type { GrantServerConfig, AuthorizationResult, PermissionCheckOptions, Scope, ResourceResolver, } from '../types';
4
- export { GrantServerError, AuthenticationError, AuthorizationError, BadRequestError, NotFoundError, } from '../errors';
3
+ export type { AuthorizationResult, GrantServerConfig, PermissionCheckOptions, ResourceResolver, Scope, } from '../types';
4
+ export { AuthenticationError, AuthorizationError, BadRequestError, GrantServerError, NotFoundError, } from '../errors';
5
5
  export { GrantClient } from '../grant-client';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGpE,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,EACL,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,aAAa,GACd,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/express/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAGrC,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,KAAK,GACN,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,6 +1,6 @@
1
+ import { NextFunction, Request, Response } from 'express';
1
2
  import { GrantClient } from '../grant-client';
2
- import { ResourceResolver, AuthorizationResult } from '../types';
3
- import { Request, Response, NextFunction } from 'express';
3
+ import { AuthorizationResult, ResourceResolver } from '../types';
4
4
  /**
5
5
  * Extended Express Request with authorization result
6
6
  */
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/express/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAI9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,OAAO;IAChD,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,YAAY,GACpB,CAAC,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAyG9E"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/express/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAItE;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,OAAO;IAChD,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,YAAY,GACpB,CAAC,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAyG9E"}
package/dist/express.cjs CHANGED
@@ -1,99 +1,110 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const index = require("./index.cjs");
4
- const debug = require("./debug-Crb5gNDM.cjs");
5
- const grantClient = require("./grant-client-DywfJN5P.cjs");
2
+ const require_grant_client = require("./grant-client-f6IKMyk5.cjs");
3
+ const require_errors = require("./errors-BUeTn_3G.cjs");
4
+ const require_debug = require("./debug-DInHA4QB.cjs");
5
+ //#region src/express/middleware.ts
6
+ /**
7
+ * Create Express middleware to check if user is granted permission
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { grant } from '@grantjs/server/express';
12
+ * import { GrantClient } from '@grantjs/server';
13
+ *
14
+ * const grantClient = new GrantClient({ apiUrl: 'https://api.grant.com' });
15
+ *
16
+ * router.get('/organizations', grant(grantClient, {
17
+ * resource: 'Organization',
18
+ * action: 'Query',
19
+ * }), handler);
20
+ * ```
21
+ */
6
22
  function grant(client, options) {
7
- return async (req, res, next) => {
8
- try {
9
- debug.debugGrant("Express", { resource: options.resource, action: options.action });
10
- const token = await grantClient.extractTokenFromRequest(req, client.config);
11
- if (!token) {
12
- res.status(401).json({
13
- error: "Unauthorized",
14
- code: "UNAUTHENTICATED"
15
- });
16
- return;
17
- }
18
- let resolvedResource = null;
19
- if (options.resourceResolver) {
20
- resolvedResource = await options.resourceResolver({
21
- resourceSlug: options.resource,
22
- request: req
23
- });
24
- if (!resolvedResource) {
25
- res.status(404).json({
26
- error: "Resource not found",
27
- code: "NOT_FOUND"
28
- });
29
- return;
30
- }
31
- }
32
- const result = await client.isAuthorized(
33
- options.resource,
34
- options.action,
35
- {
36
- context: {
37
- resource: resolvedResource || void 0
38
- }
39
- },
40
- req
41
- );
42
- debug.debugGrant("Express", {
43
- resource: options.resource,
44
- action: options.action,
45
- authorized: result.authorized,
46
- ...result.authorized ? {} : { reason: result.reason }
47
- });
48
- if (!result.authorized) {
49
- res.status(403).json({
50
- error: "Forbidden",
51
- code: "FORBIDDEN",
52
- reason: result.reason
53
- });
54
- return;
55
- }
56
- req.authorization = result;
57
- next();
58
- } catch (error) {
59
- if (error instanceof index.AuthenticationError) {
60
- res.status(401).json({
61
- error: error.message,
62
- code: error.code
63
- });
64
- return;
65
- }
66
- if (error instanceof index.AuthorizationError) {
67
- res.status(403).json({
68
- error: error.message,
69
- code: error.code,
70
- reason: error.reason
71
- });
72
- return;
73
- }
74
- if (error instanceof index.BadRequestError) {
75
- res.status(400).json({
76
- error: error.message,
77
- code: error.code
78
- });
79
- return;
80
- }
81
- if (error instanceof index.NotFoundError) {
82
- res.status(404).json({
83
- error: error.message,
84
- code: error.code
85
- });
86
- return;
87
- }
88
- next(error);
89
- }
90
- };
23
+ return async (req, res, next) => {
24
+ try {
25
+ require_debug.debugGrant("Express", {
26
+ resource: options.resource,
27
+ action: options.action
28
+ });
29
+ if (!await require_grant_client.extractTokenFromRequest(req, client.config)) {
30
+ res.status(401).json({
31
+ error: "Unauthorized",
32
+ code: "UNAUTHENTICATED"
33
+ });
34
+ return;
35
+ }
36
+ let resolvedResource = null;
37
+ if (options.resourceResolver) {
38
+ resolvedResource = await options.resourceResolver({
39
+ resourceSlug: options.resource,
40
+ request: req
41
+ });
42
+ if (!resolvedResource) {
43
+ res.status(404).json({
44
+ error: "Resource not found",
45
+ code: "NOT_FOUND"
46
+ });
47
+ return;
48
+ }
49
+ }
50
+ const result = await client.isAuthorized(options.resource, options.action, { context: { resource: resolvedResource || void 0 } }, req);
51
+ require_debug.debugGrant("Express", {
52
+ resource: options.resource,
53
+ action: options.action,
54
+ authorized: result.authorized,
55
+ ...result.authorized ? {} : { reason: result.reason }
56
+ });
57
+ if (!result.authorized) {
58
+ res.status(403).json({
59
+ error: "Forbidden",
60
+ code: "FORBIDDEN",
61
+ reason: result.reason
62
+ });
63
+ return;
64
+ }
65
+ req.authorization = result;
66
+ next();
67
+ } catch (error) {
68
+ if (error instanceof require_errors.AuthenticationError) {
69
+ res.status(401).json({
70
+ error: error.message,
71
+ code: error.code
72
+ });
73
+ return;
74
+ }
75
+ if (error instanceof require_errors.AuthorizationError) {
76
+ res.status(403).json({
77
+ error: error.message,
78
+ code: error.code,
79
+ reason: error.reason
80
+ });
81
+ return;
82
+ }
83
+ if (error instanceof require_errors.BadRequestError) {
84
+ res.status(400).json({
85
+ error: error.message,
86
+ code: error.code
87
+ });
88
+ return;
89
+ }
90
+ if (error instanceof require_errors.NotFoundError) {
91
+ res.status(404).json({
92
+ error: error.message,
93
+ code: error.code
94
+ });
95
+ return;
96
+ }
97
+ next(error);
98
+ }
99
+ };
91
100
  }
92
- exports.AuthenticationError = index.AuthenticationError;
93
- exports.AuthorizationError = index.AuthorizationError;
94
- exports.BadRequestError = index.BadRequestError;
95
- exports.GrantServerError = index.GrantServerError;
96
- exports.NotFoundError = index.NotFoundError;
97
- exports.GrantClient = grantClient.GrantClient;
101
+ //#endregion
102
+ exports.AuthenticationError = require_errors.AuthenticationError;
103
+ exports.AuthorizationError = require_errors.AuthorizationError;
104
+ exports.BadRequestError = require_errors.BadRequestError;
105
+ exports.GrantClient = require_grant_client.GrantClient;
106
+ exports.GrantServerError = require_errors.GrantServerError;
107
+ exports.NotFoundError = require_errors.NotFoundError;
98
108
  exports.grant = grant;
99
- //# sourceMappingURL=express.cjs.map
109
+
110
+ //# sourceMappingURL=express.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"express.cjs","sources":["../src/express/middleware.ts"],"sourcesContent":["import { AuthenticationError, AuthorizationError, BadRequestError, NotFoundError } from '../errors';\nimport { GrantClient } from '../grant-client';\nimport { debugGrant } from '../utils/debug';\nimport { extractTokenFromRequest } from '../utils/token-extractor';\n\nimport type { ResourceResolver, AuthorizationResult } from '../types';\nimport type { Request, Response, NextFunction } from 'express';\n\n/**\n * Extended Express Request with authorization result\n */\nexport interface AuthorizedRequest extends Request {\n authorization?: AuthorizationResult;\n}\n\n/**\n * Options for Express middleware\n */\nexport interface GrantOptions {\n /** The resource slug to check (e.g., \"Organization\", \"Project\", \"Document\") */\n resource: string;\n /** The action to check (e.g., \"Query\", \"Create\", \"Update\", \"Delete\") */\n action: string;\n /** Custom resource resolver for condition evaluation */\n resourceResolver?: ResourceResolver;\n}\n\n/**\n * Create Express middleware to check if user is granted permission\n *\n * @example\n * ```ts\n * import { grant } from '@grantjs/server/express';\n * import { GrantClient } from '@grantjs/server';\n *\n * const grantClient = new GrantClient({ apiUrl: 'https://api.grant.com' });\n *\n * router.get('/organizations', grant(grantClient, {\n * resource: 'Organization',\n * action: 'Query',\n * }), handler);\n * ```\n */\nexport function grant(\n client: GrantClient,\n options: GrantOptions\n): (req: AuthorizedRequest, res: Response, next: NextFunction) => Promise<void> {\n return async (req: AuthorizedRequest, res: Response, next: NextFunction): Promise<void> => {\n try {\n debugGrant('Express', { resource: options.resource, action: options.action });\n\n // 1. Check authentication (token must be present)\n const token = await extractTokenFromRequest(req, client.config);\n if (!token) {\n res.status(401).json({\n error: 'Unauthorized',\n code: 'UNAUTHENTICATED',\n });\n return;\n }\n\n // 2. Optionally resolve resource for condition evaluation\n let resolvedResource: Record<string, unknown> | null = null;\n\n if (options.resourceResolver) {\n resolvedResource = await options.resourceResolver({\n resourceSlug: options.resource,\n request: req,\n });\n\n if (!resolvedResource) {\n res.status(404).json({\n error: 'Resource not found',\n code: 'NOT_FOUND',\n });\n return;\n }\n }\n\n // 3. Check authorization (pass request for token extraction; scope comes from JWT claims)\n const result = await client.isAuthorized(\n options.resource,\n options.action,\n {\n context: {\n resource: resolvedResource || undefined,\n },\n },\n req\n );\n\n debugGrant('Express', {\n resource: options.resource,\n action: options.action,\n authorized: result.authorized,\n ...(result.authorized ? {} : { reason: result.reason }),\n });\n\n if (!result.authorized) {\n res.status(403).json({\n error: 'Forbidden',\n code: 'FORBIDDEN',\n reason: result.reason,\n });\n return;\n }\n\n // 4. Attach authorization result to request for downstream use\n (req as AuthorizedRequest).authorization = result;\n\n // 5. Proceed to next middleware/handler\n next();\n } catch (error) {\n // Handle known errors\n if (error instanceof AuthenticationError) {\n res.status(401).json({\n error: error.message,\n code: error.code,\n });\n return;\n }\n\n if (error instanceof AuthorizationError) {\n res.status(403).json({\n error: error.message,\n code: error.code,\n reason: error.reason,\n });\n return;\n }\n\n if (error instanceof BadRequestError) {\n res.status(400).json({\n error: error.message,\n code: error.code,\n });\n return;\n }\n\n if (error instanceof NotFoundError) {\n res.status(404).json({\n error: error.message,\n code: error.code,\n });\n return;\n }\n\n // Unknown error - pass to Express error handler\n next(error);\n }\n };\n}\n"],"names":["debugGrant","extractTokenFromRequest","AuthenticationError","AuthorizationError","BadRequestError","NotFoundError"],"mappings":";;;;;AA2CO,SAAS,MACd,QACA,SAC8E;AAC9E,SAAO,OAAO,KAAwB,KAAe,SAAsC;AACzF,QAAI;AACFA,uBAAW,WAAW,EAAE,UAAU,QAAQ,UAAU,QAAQ,QAAQ,QAAQ;AAG5E,YAAM,QAAQ,MAAMC,YAAAA,wBAAwB,KAAK,OAAO,MAAM;AAC9D,UAAI,CAAC,OAAO;AACV,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,OAAO;AAAA,UACP,MAAM;AAAA,QAAA,CACP;AACD;AAAA,MACF;AAGA,UAAI,mBAAmD;AAEvD,UAAI,QAAQ,kBAAkB;AAC5B,2BAAmB,MAAM,QAAQ,iBAAiB;AAAA,UAChD,cAAc,QAAQ;AAAA,UACtB,SAAS;AAAA,QAAA,CACV;AAED,YAAI,CAAC,kBAAkB;AACrB,cAAI,OAAO,GAAG,EAAE,KAAK;AAAA,YACnB,OAAO;AAAA,YACP,MAAM;AAAA,UAAA,CACP;AACD;AAAA,QACF;AAAA,MACF;AAGA,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,UACE,SAAS;AAAA,YACP,UAAU,oBAAoB;AAAA,UAAA;AAAA,QAChC;AAAA,QAEF;AAAA,MAAA;AAGFD,YAAAA,WAAW,WAAW;AAAA,QACpB,UAAU,QAAQ;AAAA,QAClB,QAAQ,QAAQ;AAAA,QAChB,YAAY,OAAO;AAAA,QACnB,GAAI,OAAO,aAAa,CAAA,IAAK,EAAE,QAAQ,OAAO,OAAA;AAAA,MAAO,CACtD;AAED,UAAI,CAAC,OAAO,YAAY;AACtB,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,OAAO;AAAA,UACP,MAAM;AAAA,UACN,QAAQ,OAAO;AAAA,QAAA,CAChB;AACD;AAAA,MACF;AAGC,UAA0B,gBAAgB;AAG3C,WAAA;AAAA,IACF,SAAS,OAAO;AAEd,UAAI,iBAAiBE,MAAAA,qBAAqB;AACxC,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,QAAA,CACb;AACD;AAAA,MACF;AAEA,UAAI,iBAAiBC,MAAAA,oBAAoB;AACvC,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,UACZ,QAAQ,MAAM;AAAA,QAAA,CACf;AACD;AAAA,MACF;AAEA,UAAI,iBAAiBC,MAAAA,iBAAiB;AACpC,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,QAAA,CACb;AACD;AAAA,MACF;AAEA,UAAI,iBAAiBC,MAAAA,eAAe;AAClC,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,QAAA,CACb;AACD;AAAA,MACF;AAGA,WAAK,KAAK;AAAA,IACZ;AAAA,EACF;AACF;;;;;;;;"}
1
+ {"version":3,"file":"express.cjs","names":[],"sources":["../src/express/middleware.ts"],"sourcesContent":["import type { NextFunction, Request, Response } from 'express';\n\nimport { AuthenticationError, AuthorizationError, BadRequestError, NotFoundError } from '../errors';\nimport { GrantClient } from '../grant-client';\nimport type { AuthorizationResult, ResourceResolver } from '../types';\nimport { debugGrant } from '../utils/debug';\nimport { extractTokenFromRequest } from '../utils/token-extractor';\n\n/**\n * Extended Express Request with authorization result\n */\nexport interface AuthorizedRequest extends Request {\n authorization?: AuthorizationResult;\n}\n\n/**\n * Options for Express middleware\n */\nexport interface GrantOptions {\n /** The resource slug to check (e.g., \"Organization\", \"Project\", \"Document\") */\n resource: string;\n /** The action to check (e.g., \"Query\", \"Create\", \"Update\", \"Delete\") */\n action: string;\n /** Custom resource resolver for condition evaluation */\n resourceResolver?: ResourceResolver;\n}\n\n/**\n * Create Express middleware to check if user is granted permission\n *\n * @example\n * ```ts\n * import { grant } from '@grantjs/server/express';\n * import { GrantClient } from '@grantjs/server';\n *\n * const grantClient = new GrantClient({ apiUrl: 'https://api.grant.com' });\n *\n * router.get('/organizations', grant(grantClient, {\n * resource: 'Organization',\n * action: 'Query',\n * }), handler);\n * ```\n */\nexport function grant(\n client: GrantClient,\n options: GrantOptions\n): (req: AuthorizedRequest, res: Response, next: NextFunction) => Promise<void> {\n return async (req: AuthorizedRequest, res: Response, next: NextFunction): Promise<void> => {\n try {\n debugGrant('Express', { resource: options.resource, action: options.action });\n\n // 1. Check authentication (token must be present)\n const token = await extractTokenFromRequest(req, client.config);\n if (!token) {\n res.status(401).json({\n error: 'Unauthorized',\n code: 'UNAUTHENTICATED',\n });\n return;\n }\n\n // 2. Optionally resolve resource for condition evaluation\n let resolvedResource: Record<string, unknown> | null = null;\n\n if (options.resourceResolver) {\n resolvedResource = await options.resourceResolver({\n resourceSlug: options.resource,\n request: req,\n });\n\n if (!resolvedResource) {\n res.status(404).json({\n error: 'Resource not found',\n code: 'NOT_FOUND',\n });\n return;\n }\n }\n\n // 3. Check authorization (pass request for token extraction; scope comes from JWT claims)\n const result = await client.isAuthorized(\n options.resource,\n options.action,\n {\n context: {\n resource: resolvedResource || undefined,\n },\n },\n req\n );\n\n debugGrant('Express', {\n resource: options.resource,\n action: options.action,\n authorized: result.authorized,\n ...(result.authorized ? {} : { reason: result.reason }),\n });\n\n if (!result.authorized) {\n res.status(403).json({\n error: 'Forbidden',\n code: 'FORBIDDEN',\n reason: result.reason,\n });\n return;\n }\n\n // 4. Attach authorization result to request for downstream use\n (req as AuthorizedRequest).authorization = result;\n\n // 5. Proceed to next middleware/handler\n next();\n } catch (error) {\n // Handle known errors\n if (error instanceof AuthenticationError) {\n res.status(401).json({\n error: error.message,\n code: error.code,\n });\n return;\n }\n\n if (error instanceof AuthorizationError) {\n res.status(403).json({\n error: error.message,\n code: error.code,\n reason: error.reason,\n });\n return;\n }\n\n if (error instanceof BadRequestError) {\n res.status(400).json({\n error: error.message,\n code: error.code,\n });\n return;\n }\n\n if (error instanceof NotFoundError) {\n res.status(404).json({\n error: error.message,\n code: error.code,\n });\n return;\n }\n\n // Unknown error - pass to Express error handler\n next(error);\n }\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA2CA,SAAgB,MACd,QACA,SAC8E;AAC9E,QAAO,OAAO,KAAwB,KAAe,SAAsC;AACzF,MAAI;AACF,iBAAA,WAAW,WAAW;IAAE,UAAU,QAAQ;IAAU,QAAQ,QAAQ;IAAQ,CAAC;AAI7E,OAAI,CAAC,MADe,qBAAA,wBAAwB,KAAK,OAAO,OAAO,EACnD;AACV,QAAI,OAAO,IAAI,CAAC,KAAK;KACnB,OAAO;KACP,MAAM;KACP,CAAC;AACF;;GAIF,IAAI,mBAAmD;AAEvD,OAAI,QAAQ,kBAAkB;AAC5B,uBAAmB,MAAM,QAAQ,iBAAiB;KAChD,cAAc,QAAQ;KACtB,SAAS;KACV,CAAC;AAEF,QAAI,CAAC,kBAAkB;AACrB,SAAI,OAAO,IAAI,CAAC,KAAK;MACnB,OAAO;MACP,MAAM;MACP,CAAC;AACF;;;GAKJ,MAAM,SAAS,MAAM,OAAO,aAC1B,QAAQ,UACR,QAAQ,QACR,EACE,SAAS,EACP,UAAU,oBAAoB,KAAA,GAC/B,EACF,EACD,IACD;AAED,iBAAA,WAAW,WAAW;IACpB,UAAU,QAAQ;IAClB,QAAQ,QAAQ;IAChB,YAAY,OAAO;IACnB,GAAI,OAAO,aAAa,EAAE,GAAG,EAAE,QAAQ,OAAO,QAAQ;IACvD,CAAC;AAEF,OAAI,CAAC,OAAO,YAAY;AACtB,QAAI,OAAO,IAAI,CAAC,KAAK;KACnB,OAAO;KACP,MAAM;KACN,QAAQ,OAAO;KAChB,CAAC;AACF;;AAID,OAA0B,gBAAgB;AAG3C,SAAM;WACC,OAAO;AAEd,OAAI,iBAAiB,eAAA,qBAAqB;AACxC,QAAI,OAAO,IAAI,CAAC,KAAK;KACnB,OAAO,MAAM;KACb,MAAM,MAAM;KACb,CAAC;AACF;;AAGF,OAAI,iBAAiB,eAAA,oBAAoB;AACvC,QAAI,OAAO,IAAI,CAAC,KAAK;KACnB,OAAO,MAAM;KACb,MAAM,MAAM;KACZ,QAAQ,MAAM;KACf,CAAC;AACF;;AAGF,OAAI,iBAAiB,eAAA,iBAAiB;AACpC,QAAI,OAAO,IAAI,CAAC,KAAK;KACnB,OAAO,MAAM;KACb,MAAM,MAAM;KACb,CAAC;AACF;;AAGF,OAAI,iBAAiB,eAAA,eAAe;AAClC,QAAI,OAAO,IAAI,CAAC,KAAK;KACnB,OAAO,MAAM;KACb,MAAM,MAAM;KACb,CAAC;AACF;;AAIF,QAAK,MAAM"}