@nest-boot/permission 7.0.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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/dist/decorators/can.decorator.d.ts +21 -0
  3. package/dist/decorators/can.decorator.js +26 -0
  4. package/dist/decorators/can.decorator.js.map +1 -0
  5. package/dist/decorators/can.decorator.spec.d.ts +1 -0
  6. package/dist/decorators/can.decorator.spec.js +46 -0
  7. package/dist/decorators/can.decorator.spec.js.map +1 -0
  8. package/dist/enums/permission-action.enum.d.ts +13 -0
  9. package/dist/enums/permission-action.enum.js +18 -0
  10. package/dist/enums/permission-action.enum.js.map +1 -0
  11. package/dist/index.d.ts +16 -0
  12. package/dist/index.js +33 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/interfaces/can-options.interface.d.ts +10 -0
  15. package/dist/interfaces/can-options.interface.js +3 -0
  16. package/dist/interfaces/can-options.interface.js.map +1 -0
  17. package/dist/interfaces/permission-module-options.interface.d.ts +6 -0
  18. package/dist/interfaces/permission-module-options.interface.js +3 -0
  19. package/dist/interfaces/permission-module-options.interface.js.map +1 -0
  20. package/dist/interfaces/route-argument-metadata-value.interface.d.ts +10 -0
  21. package/dist/interfaces/route-argument-metadata-value.interface.js +3 -0
  22. package/dist/interfaces/route-argument-metadata-value.interface.js.map +1 -0
  23. package/dist/permission.ability-builder.d.ts +7 -0
  24. package/dist/permission.ability-builder.js +13 -0
  25. package/dist/permission.ability-builder.js.map +1 -0
  26. package/dist/permission.constants.d.ts +50 -0
  27. package/dist/permission.constants.js +54 -0
  28. package/dist/permission.constants.js.map +1 -0
  29. package/dist/permission.guard.d.ts +51 -0
  30. package/dist/permission.guard.js +232 -0
  31. package/dist/permission.guard.js.map +1 -0
  32. package/dist/permission.guard.spec.d.ts +1 -0
  33. package/dist/permission.guard.spec.js +358 -0
  34. package/dist/permission.guard.spec.js.map +1 -0
  35. package/dist/permission.module-definition.d.ts +5 -0
  36. package/dist/permission.module-definition.js +12 -0
  37. package/dist/permission.module-definition.js.map +1 -0
  38. package/dist/permission.module.d.ts +4 -0
  39. package/dist/permission.module.js +24 -0
  40. package/dist/permission.module.js.map +1 -0
  41. package/dist/permission.module.spec.d.ts +1 -0
  42. package/dist/permission.module.spec.js +12 -0
  43. package/dist/permission.module.spec.js.map +1 -0
  44. package/dist/tsconfig.build.tsbuildinfo +1 -0
  45. package/dist/types/build-ability-callback.type.d.ts +4 -0
  46. package/dist/types/build-ability-callback.type.js +3 -0
  47. package/dist/types/build-ability-callback.type.js.map +1 -0
  48. package/dist/types/can-subject-factory.type.d.ts +3 -0
  49. package/dist/types/can-subject-factory.type.js +3 -0
  50. package/dist/types/can-subject-factory.type.js.map +1 -0
  51. package/dist/types/can-subject.type.d.ts +5 -0
  52. package/dist/types/can-subject.type.js +3 -0
  53. package/dist/types/can-subject.type.js.map +1 -0
  54. package/dist/types/permission-ability.type.d.ts +4 -0
  55. package/dist/types/permission-ability.type.js +3 -0
  56. package/dist/types/permission-ability.type.js.map +1 -0
  57. package/dist/types/route-argument-metadata.type.d.ts +3 -0
  58. package/dist/types/route-argument-metadata.type.js +3 -0
  59. package/dist/types/route-argument-metadata.type.js.map +1 -0
  60. package/dist/utils/can.util.d.ts +4 -0
  61. package/dist/utils/can.util.js +9 -0
  62. package/dist/utils/can.util.js.map +1 -0
  63. package/dist/utils/can.util.spec.d.ts +1 -0
  64. package/dist/utils/can.util.spec.js +34 -0
  65. package/dist/utils/can.util.spec.js.map +1 -0
  66. package/dist/utils/get-permission-ability.util.d.ts +3 -0
  67. package/dist/utils/get-permission-ability.util.js +16 -0
  68. package/dist/utils/get-permission-ability.util.js.map +1 -0
  69. package/dist/utils/get-permission-ability.util.spec.d.ts +1 -0
  70. package/dist/utils/get-permission-ability.util.spec.js +27 -0
  71. package/dist/utils/get-permission-ability.util.spec.js.map +1 -0
  72. package/package.json +76 -0
@@ -0,0 +1,3 @@
1
+ import type { Subject } from "@casl/ability";
2
+ /** Factory that resolves a permission subject from the current handler instance and decorated method parameters. */
3
+ export type CanSubjectFactory<T extends Subject = Subject, TSelf = unknown, TArgs extends unknown[] = unknown[]> = (self: TSelf, ...args: TArgs) => T | Promise<T>;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=can-subject-factory.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"can-subject-factory.type.js","sourceRoot":"","sources":["../../src/types/can-subject-factory.type.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import type { Subject } from "@casl/ability";
2
+ import type { Type } from "@nestjs/common";
3
+ import type { CanSubjectFactory } from "./can-subject-factory.type";
4
+ /** Permission subject type or subject resolver factory. */
5
+ export type CanSubject<T extends Subject = Subject> = Type<T> | CanSubjectFactory<T>;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=can-subject.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"can-subject.type.js","sourceRoot":"","sources":["../../src/types/can-subject.type.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { MongoAbility, Subject } from "@casl/ability";
2
+ import type { PermissionAction } from "../enums/permission-action.enum";
3
+ /** CASL ability type used by the permission module. */
4
+ export type PermissionAbility = MongoAbility<[PermissionAction, Subject]>;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=permission-ability.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-ability.type.js","sourceRoot":"","sources":["../../src/types/permission-ability.type.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { RouteArgumentMetadataValue } from "../interfaces/route-argument-metadata-value.interface";
2
+ /** Nest route arguments metadata map keyed by route parameter metadata token. */
3
+ export type RouteArgumentMetadata = Record<string, RouteArgumentMetadataValue>;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=route-argument-metadata.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-argument-metadata.type.js","sourceRoot":"","sources":["../../src/types/route-argument-metadata.type.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { Subject } from "@casl/ability";
2
+ import type { PermissionAction } from "../enums/permission-action.enum";
3
+ /** Checks a permission with the ability prepared for the current request. */
4
+ export declare function can(action: PermissionAction, subject: Subject): boolean;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.can = can;
4
+ const get_permission_ability_util_1 = require("./get-permission-ability.util");
5
+ /** Checks a permission with the ability prepared for the current request. */
6
+ function can(action, subject) {
7
+ return (0, get_permission_ability_util_1.getPermissionAbility)().can(action, subject);
8
+ }
9
+ //# sourceMappingURL=can.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"can.util.js","sourceRoot":"","sources":["../../src/utils/can.util.ts"],"names":[],"mappings":";;AAMA,kBAEC;AALD,+EAAqE;AAErE,6EAA6E;AAC7E,SAAgB,GAAG,CAAC,MAAwB,EAAE,OAAgB;IAC5D,OAAO,IAAA,kDAAoB,GAAE,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const request_context_1 = require("@nest-boot/request-context");
4
+ const common_1 = require("@nestjs/common");
5
+ const permission_action_enum_1 = require("../enums/permission-action.enum");
6
+ const permission_constants_1 = require("../permission.constants");
7
+ const can_util_1 = require("./can.util");
8
+ class TestSubject {
9
+ }
10
+ describe("can", () => {
11
+ it("checks permissions with cached current ability", async () => {
12
+ const canMock = jest.fn(() => true);
13
+ const ability = {
14
+ can: canMock,
15
+ };
16
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), () => {
17
+ request_context_1.RequestContext.set(permission_constants_1.PERMISSION_ABILITY, ability);
18
+ expect((0, can_util_1.can)(permission_action_enum_1.PermissionAction.UPDATE, TestSubject)).toBe(true);
19
+ });
20
+ expect(canMock).toHaveBeenCalledWith(permission_action_enum_1.PermissionAction.UPDATE, TestSubject);
21
+ });
22
+ it("throws when permission ability is not cached", async () => {
23
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), () => {
24
+ expect(() => (0, can_util_1.can)(permission_action_enum_1.PermissionAction.UPDATE, TestSubject)).toThrow(common_1.ForbiddenException);
25
+ });
26
+ });
27
+ it("throws when cached permission ability is null", async () => {
28
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), () => {
29
+ request_context_1.RequestContext.set(permission_constants_1.PERMISSION_ABILITY, null);
30
+ expect(() => (0, can_util_1.can)(permission_action_enum_1.PermissionAction.UPDATE, TestSubject)).toThrow(common_1.ForbiddenException);
31
+ });
32
+ });
33
+ });
34
+ //# sourceMappingURL=can.util.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"can.util.spec.js","sourceRoot":"","sources":["../../src/utils/can.util.spec.ts"],"names":[],"mappings":";;AAAA,gEAA4D;AAC5D,2CAAoD;AAEpD,4EAAmE;AACnE,kEAA6D;AAE7D,yCAAiC;AAEjC,MAAM,WAAW;CAAG;AAEpB,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;IACnB,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG;YACd,GAAG,EAAE,OAAO;SACmB,CAAC;QAElC,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE;YAClE,gCAAc,CAAC,GAAG,CAAC,yCAAkB,EAAE,OAAO,CAAC,CAAC;YAEhD,MAAM,CAAC,IAAA,cAAG,EAAC,yCAAgB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,yCAAgB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE;YAClE,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,cAAG,EAAC,yCAAgB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAC7D,2BAAkB,CACnB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE;YAClE,gCAAc,CAAC,GAAG,CAAC,yCAAkB,EAAE,IAAI,CAAC,CAAC;YAE7C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,cAAG,EAAC,yCAAgB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAC7D,2BAAkB,CACnB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PermissionAbility } from "../types/permission-ability.type";
2
+ /** Reads the permission ability prepared for the current request. */
3
+ export declare const getPermissionAbility: () => PermissionAbility;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPermissionAbility = void 0;
4
+ const request_context_1 = require("@nest-boot/request-context");
5
+ const common_1 = require("@nestjs/common");
6
+ const permission_constants_1 = require("../permission.constants");
7
+ /** Reads the permission ability prepared for the current request. */
8
+ const getPermissionAbility = () => {
9
+ const ability = request_context_1.RequestContext.get(permission_constants_1.PERMISSION_ABILITY) ?? null;
10
+ if (!ability) {
11
+ throw new common_1.ForbiddenException("Permission ability is not available");
12
+ }
13
+ return ability;
14
+ };
15
+ exports.getPermissionAbility = getPermissionAbility;
16
+ //# sourceMappingURL=get-permission-ability.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-permission-ability.util.js","sourceRoot":"","sources":["../../src/utils/get-permission-ability.util.ts"],"names":[],"mappings":";;;AAAA,gEAA4D;AAC5D,2CAAoD;AAEpD,kEAA6D;AAG7D,qEAAqE;AAC9D,MAAM,oBAAoB,GAAG,GAAsB,EAAE;IAC1D,MAAM,OAAO,GACX,gCAAc,CAAC,GAAG,CAAoB,yCAAkB,CAAC,IAAI,IAAI,CAAC;IAEpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,2BAAkB,CAAC,qCAAqC,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AATW,QAAA,oBAAoB,wBAS/B"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const request_context_1 = require("@nest-boot/request-context");
4
+ const common_1 = require("@nestjs/common");
5
+ const permission_constants_1 = require("../permission.constants");
6
+ const get_permission_ability_util_1 = require("./get-permission-ability.util");
7
+ describe("getPermissionAbility", () => {
8
+ it("throws when no permission ability is cached", async () => {
9
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), () => {
10
+ expect(() => (0, get_permission_ability_util_1.getPermissionAbility)()).toThrow(common_1.ForbiddenException);
11
+ });
12
+ });
13
+ it("throws when cached permission ability is null", async () => {
14
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), () => {
15
+ request_context_1.RequestContext.set(permission_constants_1.PERMISSION_ABILITY, null);
16
+ expect(() => (0, get_permission_ability_util_1.getPermissionAbility)()).toThrow(common_1.ForbiddenException);
17
+ });
18
+ });
19
+ it("reads the permission ability from request context", async () => {
20
+ const ability = { can: jest.fn() };
21
+ await request_context_1.RequestContext.run(new request_context_1.RequestContext({ type: "http" }), (context) => {
22
+ context.set(permission_constants_1.PERMISSION_ABILITY, ability);
23
+ expect((0, get_permission_ability_util_1.getPermissionAbility)()).toBe(ability);
24
+ });
25
+ });
26
+ });
27
+ //# sourceMappingURL=get-permission-ability.util.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-permission-ability.util.spec.js","sourceRoot":"","sources":["../../src/utils/get-permission-ability.util.spec.ts"],"names":[],"mappings":";;AAAA,gEAA4D;AAC5D,2CAAoD;AAEpD,kEAA6D;AAC7D,+EAAqE;AAErE,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE;YAClE,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,kDAAoB,GAAE,CAAC,CAAC,OAAO,CAAC,2BAAkB,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,gCAAc,CAAC,GAAG,CAAC,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE;YAClE,gCAAc,CAAC,GAAG,CAAC,yCAAkB,EAAE,IAAI,CAAC,CAAC;YAE7C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,kDAAoB,GAAE,CAAC,CAAC,OAAO,CAAC,2BAAkB,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;QAEnC,MAAM,gCAAc,CAAC,GAAG,CACtB,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EACpC,CAAC,OAAO,EAAE,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,yCAAkB,EAAE,OAAO,CAAC,CAAC;YAEzC,MAAM,CAAC,IAAA,kDAAoB,GAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@nest-boot/permission",
3
+ "version": "7.0.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/nest-boot/nest-boot.git",
7
+ "directory": "packages/permission"
8
+ },
9
+ "description": "CASL-based permission helpers for Nest Boot applications",
10
+ "author": {
11
+ "name": "Xudong Huang",
12
+ "email": "me@huangxudong.com",
13
+ "url": "https://www.huangxudong.com/"
14
+ },
15
+ "homepage": "",
16
+ "license": "MIT",
17
+ "main": "dist/index.js",
18
+ "types": "dist/index.d.ts",
19
+ "directories": {
20
+ "lib": "dist"
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "peerDependencies": {
26
+ "@casl/ability": "^6.0.0",
27
+ "@nest-boot/request-context": "^7.0.0",
28
+ "@nestjs/common": "^11.0.0",
29
+ "@nestjs/core": "^11.0.0",
30
+ "express": "^5.0.0",
31
+ "reflect-metadata": "^0.2.2",
32
+ "rxjs": "^7.0.0"
33
+ },
34
+ "devDependencies": {
35
+ "@casl/ability": "^6.7.5",
36
+ "@nestjs/common": "^11.1.11",
37
+ "@nestjs/core": "^11.1.11",
38
+ "@nestjs/testing": "^11.1.11",
39
+ "@types/express": "^5.0.3",
40
+ "@types/jest": "^29.5.14",
41
+ "@types/node": "^24.12.4",
42
+ "eslint": "^9.39.3",
43
+ "express": "^5.1.0",
44
+ "jest": "^29.7.0",
45
+ "reflect-metadata": "^0.2.2",
46
+ "rxjs": "^7.8.2",
47
+ "ts-jest": "^29.4.4",
48
+ "typescript": "^5.9.3",
49
+ "@nest-boot/eslint-config": "^7.0.3",
50
+ "@nest-boot/eslint-plugin": "^7.0.6",
51
+ "@nest-boot/request-context": "^7.4.3",
52
+ "@nest-boot/tsconfig": "^7.0.3"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "lint-staged": {
58
+ "*.ts": [
59
+ "prettier --write",
60
+ "eslint --fix"
61
+ ]
62
+ },
63
+ "volta": {
64
+ "extends": "../../package.json"
65
+ },
66
+ "scripts": {
67
+ "build": "tsc -p tsconfig.build.json",
68
+ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
69
+ "dev": "tsc -w -p tsconfig.build.json",
70
+ "lint": "eslint \"{src,test}/**/*.ts\" --fix",
71
+ "test": "jest",
72
+ "test:cov": "jest --coverage",
73
+ "test:watch": "jest --watch",
74
+ "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand"
75
+ }
76
+ }