@jperezmart/nest-casl-testing 0.2.0 → 0.3.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.
package/README.md CHANGED
@@ -61,8 +61,10 @@ application would:
61
61
  | `detectSubjectType` | `(subject: object) => string` | Custom subject-type detection, for subjects CASL cannot name on its own. |
62
62
 
63
63
  A role whose definition is `true` rather than a function also grants
64
- `manage all`. A user whose `roles` is missing or not an array is treated as
65
- having no roles, which is what `AbilityFactory` does.
64
+ `manage all`. The `everyone` entry applies to every user before their Roles,
65
+ and a role named `everyone` on the user is ignored. A user whose `roles` is
66
+ missing or not an array is treated as having no roles (the Everyone
67
+ permissions still apply), which is what `AbilityFactory` does.
66
68
 
67
69
  ## License
68
70
 
package/dist/index.cjs CHANGED
@@ -4,9 +4,9 @@ let _casl_ability = require("@casl/ability");
4
4
  /**
5
5
  * Build a CASL ability directly from Role permissions and a user, without
6
6
  * booting a Nest application. Intended for unit-testing permission definitions
7
- * in projects that consume `@jperezmart/nest-casl`. The role union, user and
8
- * ability types are inferred from `permissions`; the user may carry roles the
9
- * map does not declare.
7
+ * in projects that consume `@jperezmart/nest-casl`. The user and ability types
8
+ * are inferred from `permissions`; the user may carry roles the map does not
9
+ * declare. Everyone permissions apply first, then the user's Roles.
10
10
  *
11
11
  * @example
12
12
  * ```ts
@@ -22,10 +22,14 @@ function buildAbilityForTest(permissions, user, options = {}) {
22
22
  builder.can("manage", "all");
23
23
  return builder.build(buildOptions);
24
24
  }
25
+ const abilityBuilder = builder;
26
+ const everyone = permissions["everyone"];
27
+ if (typeof everyone === "function") everyone(user, abilityBuilder);
25
28
  for (const role of roles) {
29
+ if (role === "everyone") continue;
26
30
  const definition = permissions[role];
27
31
  if (definition === true) builder.can("manage", "all");
28
- else if (typeof definition === "function") definition(user, builder);
32
+ else if (typeof definition === "function") definition(user, abilityBuilder);
29
33
  }
30
34
  return builder.build(buildOptions);
31
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["AbilityBuilder","createMongoAbility"],"sources":["../src/index.ts"],"sourcesContent":["import type { AnyAbility, MongoAbility } from '@casl/ability';\nimport { AbilityBuilder, createMongoAbility } from '@casl/ability';\nimport type {\n AuthorizableUser,\n DefineRolePermissions,\n RolePermissions,\n} from '@jperezmart/nest-casl';\n\n/** Extra options accepted by {@link buildAbilityForTest}. */\nexport interface BuildAbilityForTestOptions {\n /**\n * Role that bypasses all checks (mirrors `CaslModule.forRoot`). Any string:\n * the superuser role usually has no entry in the Role permissions.\n */\n superuserRole?: string;\n\n /** Custom subject-type detection (mirrors `CaslModule.forRoot`). */\n detectSubjectType?: (subject: object) => string;\n}\n\n/**\n * Build a CASL ability directly from Role permissions and a user, without\n * booting a Nest application. Intended for unit-testing permission definitions\n * in projects that consume `@jperezmart/nest-casl`. The role union, user and\n * ability types are inferred from `permissions`; the user may carry roles the\n * map does not declare.\n *\n * @example\n * ```ts\n * const ability = buildAbilityForTest(permissions, { id: \"1\", roles: [\"author\"] });\n * expect(ability.can(\"update\", subject(\"Article\", { authorId: \"1\" }))).toBe(true);\n * ```\n */\nexport function buildAbilityForTest<\n Roles extends string = string,\n TUser extends AuthorizableUser = AuthorizableUser,\n TAbility extends AnyAbility = AnyAbility,\n>(\n permissions: RolePermissions<Roles, TUser, TAbility>,\n user: TUser,\n options: BuildAbilityForTestOptions = {},\n): TAbility {\n const builder = new AbilityBuilder<MongoAbility>(createMongoAbility);\n const buildOptions = options.detectSubjectType\n ? { detectSubjectType: options.detectSubjectType }\n : undefined;\n\n // Mirror AbilityFactory: a missing / non-array `roles` means \"no roles\".\n const roles: readonly string[] = Array.isArray(user.roles) ? user.roles : [];\n\n if (\n options.superuserRole !== undefined &&\n roles.includes(options.superuserRole)\n ) {\n builder.can('manage', 'all');\n return builder.build(buildOptions) as unknown as TAbility;\n }\n\n for (const role of roles) {\n const definition = (permissions as Record<string, unknown>)[role];\n if (definition === true) {\n builder.can('manage', 'all');\n } else if (typeof definition === 'function') {\n (definition as DefineRolePermissions<TUser, AnyAbility>)(\n user,\n builder as unknown as AbilityBuilder<AnyAbility>,\n );\n }\n }\n\n return builder.build(buildOptions) as unknown as TAbility;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiCA,SAAgB,oBAKd,aACA,MACA,UAAsC,CAAC,GAC7B;CACV,MAAM,UAAU,IAAIA,cAAAA,eAA6BC,cAAAA,kBAAkB;CACnE,MAAM,eAAe,QAAQ,oBACzB,EAAE,mBAAmB,QAAQ,kBAAkB,IAC/C,KAAA;CAGJ,MAAM,QAA2B,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;CAE3E,IACE,QAAQ,kBAAkB,KAAA,KAC1B,MAAM,SAAS,QAAQ,aAAa,GACpC;EACA,QAAQ,IAAI,UAAU,KAAK;EAC3B,OAAO,QAAQ,MAAM,YAAY;CACnC;CAEA,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,aAAc,YAAwC;EAC5D,IAAI,eAAe,MACjB,QAAQ,IAAI,UAAU,KAAK;OACtB,IAAI,OAAO,eAAe,YAC/B,WACE,MACA,OACF;CAEJ;CAEA,OAAO,QAAQ,MAAM,YAAY;AACnC"}
1
+ {"version":3,"file":"index.cjs","names":["AbilityBuilder","createMongoAbility"],"sources":["../src/index.ts"],"sourcesContent":["import type { AnyAbility, MongoAbility } from '@casl/ability';\nimport { AbilityBuilder, createMongoAbility } from '@casl/ability';\nimport type {\n AuthorizableUser,\n DefineRolePermissions,\n RolePermissions,\n} from '@jperezmart/nest-casl';\n\n/** Extra options accepted by {@link buildAbilityForTest}. */\nexport interface BuildAbilityForTestOptions {\n /**\n * Role that bypasses all checks (mirrors `CaslModule.forRoot`). Any string:\n * the superuser role usually has no entry in the Role permissions.\n */\n superuserRole?: string;\n\n /** Custom subject-type detection (mirrors `CaslModule.forRoot`). */\n detectSubjectType?: (subject: object) => string;\n}\n\n/**\n * Build a CASL ability directly from Role permissions and a user, without\n * booting a Nest application. Intended for unit-testing permission definitions\n * in projects that consume `@jperezmart/nest-casl`. The user and ability types\n * are inferred from `permissions`; the user may carry roles the map does not\n * declare. Everyone permissions apply first, then the user's Roles.\n *\n * @example\n * ```ts\n * const ability = buildAbilityForTest(permissions, { id: \"1\", roles: [\"author\"] });\n * expect(ability.can(\"update\", subject(\"Article\", { authorId: \"1\" }))).toBe(true);\n * ```\n */\nexport function buildAbilityForTest<\n TUser extends AuthorizableUser = AuthorizableUser,\n TAbility extends AnyAbility = AnyAbility,\n>(\n permissions: RolePermissions<string, TUser, TAbility>,\n user: TUser,\n options: BuildAbilityForTestOptions = {},\n): TAbility {\n const builder = new AbilityBuilder<MongoAbility>(createMongoAbility);\n const buildOptions = options.detectSubjectType\n ? { detectSubjectType: options.detectSubjectType }\n : undefined;\n\n // Mirror AbilityFactory: a missing / non-array `roles` means \"no roles\"\n // (Everyone permissions still apply).\n const roles: readonly string[] = Array.isArray(user.roles) ? user.roles : [];\n\n if (\n options.superuserRole !== undefined &&\n roles.includes(options.superuserRole)\n ) {\n builder.can('manage', 'all');\n return builder.build(buildOptions) as unknown as TAbility;\n }\n\n const abilityBuilder = builder as unknown as AbilityBuilder<AnyAbility>;\n const everyone = (permissions as Record<string, unknown>)['everyone'];\n if (typeof everyone === 'function') {\n (everyone as DefineRolePermissions<TUser, AnyAbility>)(\n user,\n abilityBuilder,\n );\n }\n\n for (const role of roles) {\n // A foreign Role named `everyone` is not a Role: its rules are already in.\n if (role === 'everyone') continue;\n const definition = (permissions as Record<string, unknown>)[role];\n if (definition === true) {\n builder.can('manage', 'all');\n } else if (typeof definition === 'function') {\n (definition as DefineRolePermissions<TUser, AnyAbility>)(\n user,\n abilityBuilder,\n );\n }\n }\n\n return builder.build(buildOptions) as unknown as TAbility;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiCA,SAAgB,oBAId,aACA,MACA,UAAsC,CAAC,GAC7B;CACV,MAAM,UAAU,IAAIA,cAAAA,eAA6BC,cAAAA,kBAAkB;CACnE,MAAM,eAAe,QAAQ,oBACzB,EAAE,mBAAmB,QAAQ,kBAAkB,IAC/C,KAAA;CAIJ,MAAM,QAA2B,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;CAE3E,IACE,QAAQ,kBAAkB,KAAA,KAC1B,MAAM,SAAS,QAAQ,aAAa,GACpC;EACA,QAAQ,IAAI,UAAU,KAAK;EAC3B,OAAO,QAAQ,MAAM,YAAY;CACnC;CAEA,MAAM,iBAAiB;CACvB,MAAM,WAAY,YAAwC;CAC1D,IAAI,OAAO,aAAa,YACtB,SACE,MACA,cACF;CAGF,KAAK,MAAM,QAAQ,OAAO;EAExB,IAAI,SAAS,YAAY;EACzB,MAAM,aAAc,YAAwC;EAC5D,IAAI,eAAe,MACjB,QAAQ,IAAI,UAAU,KAAK;OACtB,IAAI,OAAO,eAAe,YAC/B,WACE,MACA,cACF;CAEJ;CAEA,OAAO,QAAQ,MAAM,YAAY;AACnC"}
package/dist/index.d.cts CHANGED
@@ -15,9 +15,9 @@ interface BuildAbilityForTestOptions {
15
15
  /**
16
16
  * Build a CASL ability directly from Role permissions and a user, without
17
17
  * booting a Nest application. Intended for unit-testing permission definitions
18
- * in projects that consume `@jperezmart/nest-casl`. The role union, user and
19
- * ability types are inferred from `permissions`; the user may carry roles the
20
- * map does not declare.
18
+ * in projects that consume `@jperezmart/nest-casl`. The user and ability types
19
+ * are inferred from `permissions`; the user may carry roles the map does not
20
+ * declare. Everyone permissions apply first, then the user's Roles.
21
21
  *
22
22
  * @example
23
23
  * ```ts
@@ -25,7 +25,7 @@ interface BuildAbilityForTestOptions {
25
25
  * expect(ability.can("update", subject("Article", { authorId: "1" }))).toBe(true);
26
26
  * ```
27
27
  */
28
- declare function buildAbilityForTest<Roles extends string = string, TUser extends AuthorizableUser = AuthorizableUser, TAbility extends AnyAbility = AnyAbility>(permissions: RolePermissions<Roles, TUser, TAbility>, user: TUser, options?: BuildAbilityForTestOptions): TAbility;
28
+ declare function buildAbilityForTest<TUser extends AuthorizableUser = AuthorizableUser, TAbility extends AnyAbility = AnyAbility>(permissions: RolePermissions<string, TUser, TAbility>, user: TUser, options?: BuildAbilityForTestOptions): TAbility;
29
29
  //#endregion
30
30
  export { BuildAbilityForTestOptions, buildAbilityForTest };
31
31
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;UASiB,0BAAA;EAAA;;;;EAKf,aAAA;EAGA;EAAA,iBAAA,IAAqB,OAAA;AAAA;AAAe;AAgBtC;;;;;;;;;;;;AAhBsC,iBAgBtB,mBAAA,8CAEA,gBAAA,GAAmB,gBAAA,mBAChB,UAAA,GAAa,UAAA,EAE9B,WAAA,EAAa,eAAA,CAAgB,KAAA,EAAO,KAAA,EAAO,QAAA,GAC3C,IAAA,EAAM,KAAA,EACN,OAAA,GAAS,0BAAA,GACR,QAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;UASiB,0BAAA;EAAA;;;;EAKf,aAAA;EAGA;EAAA,iBAAA,IAAqB,OAAA;AAAA;AAAe;AAgBtC;;;;;;;;;;;;AAhBsC,iBAgBtB,mBAAA,eACA,gBAAA,GAAmB,gBAAA,mBAChB,UAAA,GAAa,UAAA,EAE9B,WAAA,EAAa,eAAA,SAAwB,KAAA,EAAO,QAAA,GAC5C,IAAA,EAAM,KAAA,EACN,OAAA,GAAS,0BAAA,GACR,QAAA"}
package/dist/index.d.ts CHANGED
@@ -15,9 +15,9 @@ interface BuildAbilityForTestOptions {
15
15
  /**
16
16
  * Build a CASL ability directly from Role permissions and a user, without
17
17
  * booting a Nest application. Intended for unit-testing permission definitions
18
- * in projects that consume `@jperezmart/nest-casl`. The role union, user and
19
- * ability types are inferred from `permissions`; the user may carry roles the
20
- * map does not declare.
18
+ * in projects that consume `@jperezmart/nest-casl`. The user and ability types
19
+ * are inferred from `permissions`; the user may carry roles the map does not
20
+ * declare. Everyone permissions apply first, then the user's Roles.
21
21
  *
22
22
  * @example
23
23
  * ```ts
@@ -25,7 +25,7 @@ interface BuildAbilityForTestOptions {
25
25
  * expect(ability.can("update", subject("Article", { authorId: "1" }))).toBe(true);
26
26
  * ```
27
27
  */
28
- declare function buildAbilityForTest<Roles extends string = string, TUser extends AuthorizableUser = AuthorizableUser, TAbility extends AnyAbility = AnyAbility>(permissions: RolePermissions<Roles, TUser, TAbility>, user: TUser, options?: BuildAbilityForTestOptions): TAbility;
28
+ declare function buildAbilityForTest<TUser extends AuthorizableUser = AuthorizableUser, TAbility extends AnyAbility = AnyAbility>(permissions: RolePermissions<string, TUser, TAbility>, user: TUser, options?: BuildAbilityForTestOptions): TAbility;
29
29
  //#endregion
30
30
  export { BuildAbilityForTestOptions, buildAbilityForTest };
31
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;UASiB,0BAAA;EAAA;;;;EAKf,aAAA;EAGA;EAAA,iBAAA,IAAqB,OAAA;AAAA;AAAe;AAgBtC;;;;;;;;;;;;AAhBsC,iBAgBtB,mBAAA,8CAEA,gBAAA,GAAmB,gBAAA,mBAChB,UAAA,GAAa,UAAA,EAE9B,WAAA,EAAa,eAAA,CAAgB,KAAA,EAAO,KAAA,EAAO,QAAA,GAC3C,IAAA,EAAM,KAAA,EACN,OAAA,GAAS,0BAAA,GACR,QAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;UASiB,0BAAA;EAAA;;;;EAKf,aAAA;EAGA;EAAA,iBAAA,IAAqB,OAAA;AAAA;AAAe;AAgBtC;;;;;;;;;;;;AAhBsC,iBAgBtB,mBAAA,eACA,gBAAA,GAAmB,gBAAA,mBAChB,UAAA,GAAa,UAAA,EAE9B,WAAA,EAAa,eAAA,SAAwB,KAAA,EAAO,QAAA,GAC5C,IAAA,EAAM,KAAA,EACN,OAAA,GAAS,0BAAA,GACR,QAAA"}
package/dist/index.js CHANGED
@@ -3,9 +3,9 @@ import { AbilityBuilder, createMongoAbility } from "@casl/ability";
3
3
  /**
4
4
  * Build a CASL ability directly from Role permissions and a user, without
5
5
  * booting a Nest application. Intended for unit-testing permission definitions
6
- * in projects that consume `@jperezmart/nest-casl`. The role union, user and
7
- * ability types are inferred from `permissions`; the user may carry roles the
8
- * map does not declare.
6
+ * in projects that consume `@jperezmart/nest-casl`. The user and ability types
7
+ * are inferred from `permissions`; the user may carry roles the map does not
8
+ * declare. Everyone permissions apply first, then the user's Roles.
9
9
  *
10
10
  * @example
11
11
  * ```ts
@@ -21,10 +21,14 @@ function buildAbilityForTest(permissions, user, options = {}) {
21
21
  builder.can("manage", "all");
22
22
  return builder.build(buildOptions);
23
23
  }
24
+ const abilityBuilder = builder;
25
+ const everyone = permissions["everyone"];
26
+ if (typeof everyone === "function") everyone(user, abilityBuilder);
24
27
  for (const role of roles) {
28
+ if (role === "everyone") continue;
25
29
  const definition = permissions[role];
26
30
  if (definition === true) builder.can("manage", "all");
27
- else if (typeof definition === "function") definition(user, builder);
31
+ else if (typeof definition === "function") definition(user, abilityBuilder);
28
32
  }
29
33
  return builder.build(buildOptions);
30
34
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { AnyAbility, MongoAbility } from '@casl/ability';\nimport { AbilityBuilder, createMongoAbility } from '@casl/ability';\nimport type {\n AuthorizableUser,\n DefineRolePermissions,\n RolePermissions,\n} from '@jperezmart/nest-casl';\n\n/** Extra options accepted by {@link buildAbilityForTest}. */\nexport interface BuildAbilityForTestOptions {\n /**\n * Role that bypasses all checks (mirrors `CaslModule.forRoot`). Any string:\n * the superuser role usually has no entry in the Role permissions.\n */\n superuserRole?: string;\n\n /** Custom subject-type detection (mirrors `CaslModule.forRoot`). */\n detectSubjectType?: (subject: object) => string;\n}\n\n/**\n * Build a CASL ability directly from Role permissions and a user, without\n * booting a Nest application. Intended for unit-testing permission definitions\n * in projects that consume `@jperezmart/nest-casl`. The role union, user and\n * ability types are inferred from `permissions`; the user may carry roles the\n * map does not declare.\n *\n * @example\n * ```ts\n * const ability = buildAbilityForTest(permissions, { id: \"1\", roles: [\"author\"] });\n * expect(ability.can(\"update\", subject(\"Article\", { authorId: \"1\" }))).toBe(true);\n * ```\n */\nexport function buildAbilityForTest<\n Roles extends string = string,\n TUser extends AuthorizableUser = AuthorizableUser,\n TAbility extends AnyAbility = AnyAbility,\n>(\n permissions: RolePermissions<Roles, TUser, TAbility>,\n user: TUser,\n options: BuildAbilityForTestOptions = {},\n): TAbility {\n const builder = new AbilityBuilder<MongoAbility>(createMongoAbility);\n const buildOptions = options.detectSubjectType\n ? { detectSubjectType: options.detectSubjectType }\n : undefined;\n\n // Mirror AbilityFactory: a missing / non-array `roles` means \"no roles\".\n const roles: readonly string[] = Array.isArray(user.roles) ? user.roles : [];\n\n if (\n options.superuserRole !== undefined &&\n roles.includes(options.superuserRole)\n ) {\n builder.can('manage', 'all');\n return builder.build(buildOptions) as unknown as TAbility;\n }\n\n for (const role of roles) {\n const definition = (permissions as Record<string, unknown>)[role];\n if (definition === true) {\n builder.can('manage', 'all');\n } else if (typeof definition === 'function') {\n (definition as DefineRolePermissions<TUser, AnyAbility>)(\n user,\n builder as unknown as AbilityBuilder<AnyAbility>,\n );\n }\n }\n\n return builder.build(buildOptions) as unknown as TAbility;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAiCA,SAAgB,oBAKd,aACA,MACA,UAAsC,CAAC,GAC7B;CACV,MAAM,UAAU,IAAI,eAA6B,kBAAkB;CACnE,MAAM,eAAe,QAAQ,oBACzB,EAAE,mBAAmB,QAAQ,kBAAkB,IAC/C,KAAA;CAGJ,MAAM,QAA2B,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;CAE3E,IACE,QAAQ,kBAAkB,KAAA,KAC1B,MAAM,SAAS,QAAQ,aAAa,GACpC;EACA,QAAQ,IAAI,UAAU,KAAK;EAC3B,OAAO,QAAQ,MAAM,YAAY;CACnC;CAEA,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,aAAc,YAAwC;EAC5D,IAAI,eAAe,MACjB,QAAQ,IAAI,UAAU,KAAK;OACtB,IAAI,OAAO,eAAe,YAC/B,WACE,MACA,OACF;CAEJ;CAEA,OAAO,QAAQ,MAAM,YAAY;AACnC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { AnyAbility, MongoAbility } from '@casl/ability';\nimport { AbilityBuilder, createMongoAbility } from '@casl/ability';\nimport type {\n AuthorizableUser,\n DefineRolePermissions,\n RolePermissions,\n} from '@jperezmart/nest-casl';\n\n/** Extra options accepted by {@link buildAbilityForTest}. */\nexport interface BuildAbilityForTestOptions {\n /**\n * Role that bypasses all checks (mirrors `CaslModule.forRoot`). Any string:\n * the superuser role usually has no entry in the Role permissions.\n */\n superuserRole?: string;\n\n /** Custom subject-type detection (mirrors `CaslModule.forRoot`). */\n detectSubjectType?: (subject: object) => string;\n}\n\n/**\n * Build a CASL ability directly from Role permissions and a user, without\n * booting a Nest application. Intended for unit-testing permission definitions\n * in projects that consume `@jperezmart/nest-casl`. The user and ability types\n * are inferred from `permissions`; the user may carry roles the map does not\n * declare. Everyone permissions apply first, then the user's Roles.\n *\n * @example\n * ```ts\n * const ability = buildAbilityForTest(permissions, { id: \"1\", roles: [\"author\"] });\n * expect(ability.can(\"update\", subject(\"Article\", { authorId: \"1\" }))).toBe(true);\n * ```\n */\nexport function buildAbilityForTest<\n TUser extends AuthorizableUser = AuthorizableUser,\n TAbility extends AnyAbility = AnyAbility,\n>(\n permissions: RolePermissions<string, TUser, TAbility>,\n user: TUser,\n options: BuildAbilityForTestOptions = {},\n): TAbility {\n const builder = new AbilityBuilder<MongoAbility>(createMongoAbility);\n const buildOptions = options.detectSubjectType\n ? { detectSubjectType: options.detectSubjectType }\n : undefined;\n\n // Mirror AbilityFactory: a missing / non-array `roles` means \"no roles\"\n // (Everyone permissions still apply).\n const roles: readonly string[] = Array.isArray(user.roles) ? user.roles : [];\n\n if (\n options.superuserRole !== undefined &&\n roles.includes(options.superuserRole)\n ) {\n builder.can('manage', 'all');\n return builder.build(buildOptions) as unknown as TAbility;\n }\n\n const abilityBuilder = builder as unknown as AbilityBuilder<AnyAbility>;\n const everyone = (permissions as Record<string, unknown>)['everyone'];\n if (typeof everyone === 'function') {\n (everyone as DefineRolePermissions<TUser, AnyAbility>)(\n user,\n abilityBuilder,\n );\n }\n\n for (const role of roles) {\n // A foreign Role named `everyone` is not a Role: its rules are already in.\n if (role === 'everyone') continue;\n const definition = (permissions as Record<string, unknown>)[role];\n if (definition === true) {\n builder.can('manage', 'all');\n } else if (typeof definition === 'function') {\n (definition as DefineRolePermissions<TUser, AnyAbility>)(\n user,\n abilityBuilder,\n );\n }\n }\n\n return builder.build(buildOptions) as unknown as TAbility;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAiCA,SAAgB,oBAId,aACA,MACA,UAAsC,CAAC,GAC7B;CACV,MAAM,UAAU,IAAI,eAA6B,kBAAkB;CACnE,MAAM,eAAe,QAAQ,oBACzB,EAAE,mBAAmB,QAAQ,kBAAkB,IAC/C,KAAA;CAIJ,MAAM,QAA2B,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;CAE3E,IACE,QAAQ,kBAAkB,KAAA,KAC1B,MAAM,SAAS,QAAQ,aAAa,GACpC;EACA,QAAQ,IAAI,UAAU,KAAK;EAC3B,OAAO,QAAQ,MAAM,YAAY;CACnC;CAEA,MAAM,iBAAiB;CACvB,MAAM,WAAY,YAAwC;CAC1D,IAAI,OAAO,aAAa,YACtB,SACE,MACA,cACF;CAGF,KAAK,MAAM,QAAQ,OAAO;EAExB,IAAI,SAAS,YAAY;EACzB,MAAM,aAAc,YAAwC;EAC5D,IAAI,eAAe,MACjB,QAAQ,IAAI,UAAU,KAAK;OACtB,IAAI,OAAO,eAAe,YAC/B,WACE,MACA,cACF;CAEJ;CAEA,OAAO,QAAQ,MAAM,YAAY;AACnC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jperezmart/nest-casl-testing",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Testing utilities for @jperezmart/nest-casl — build and assert abilities without booting Nest.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,7 +35,7 @@
35
35
  "devDependencies": {
36
36
  "@casl/ability": "^7.0.0",
37
37
  "@jperezmart/eslint-config": "^1.0.0",
38
- "@jperezmart/nest-casl": "0.2.0",
38
+ "@jperezmart/nest-casl": "0.3.0",
39
39
  "@jperezmart/typescript-config": "^1.0.0",
40
40
  "eslint": "^10.3.0",
41
41
  "tsdown": "^0.22.2",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@casl/ability": "^7.0.0",
47
- "@jperezmart/nest-casl": "^0.2.0"
47
+ "@jperezmart/nest-casl": "^0.3.0"
48
48
  },
49
49
  "publishConfig": {
50
50
  "access": "public"