@holoyan/adonisjs-permissions 0.1.0 → 0.5.2

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 (46) hide show
  1. package/README.md +160 -59
  2. package/build/index.d.ts +10 -4
  3. package/build/index.js +10 -5
  4. package/build/providers/role_permission_provider.d.ts +3 -0
  5. package/build/providers/role_permission_provider.js +21 -0
  6. package/build/src/acl.d.ts +10 -5
  7. package/build/src/acl.js +17 -9
  8. package/build/src/decorators.js +1 -0
  9. package/build/src/mixins/has_permissions.d.ts +58 -26
  10. package/build/src/mixins/has_permissions.js +123 -18
  11. package/build/src/model_manager.d.ts +7 -0
  12. package/build/src/model_manager.js +15 -0
  13. package/build/src/models/permission.d.ts +4 -4
  14. package/build/src/models/permission.js +2 -7
  15. package/build/src/models/role.d.ts +1 -1
  16. package/build/src/models/role.js +2 -7
  17. package/build/src/morph_map.d.ts +5 -2
  18. package/build/src/morph_map.js +16 -9
  19. package/build/src/services/helper.d.ts +2 -3
  20. package/build/src/services/helper.js +1 -7
  21. package/build/src/services/model_has_role_permissions.d.ts +41 -39
  22. package/build/src/services/model_has_role_permissions.js +92 -111
  23. package/build/src/services/model_service.d.ts +15 -6
  24. package/build/src/services/model_service.js +39 -14
  25. package/build/src/services/permissions/empty_permission.d.ts +8 -0
  26. package/build/src/services/permissions/empty_permission.js +17 -0
  27. package/build/src/services/permissions/permission_has_model_roles.d.ts +12 -8
  28. package/build/src/services/permissions/permission_has_model_roles.js +28 -19
  29. package/build/src/services/permissions/permissions_service.d.ts +42 -30
  30. package/build/src/services/permissions/permissions_service.js +198 -155
  31. package/build/src/services/query_helper.d.ts +7 -0
  32. package/build/src/services/query_helper.js +12 -0
  33. package/build/src/services/roles/empty_roles.d.ts +8 -0
  34. package/build/src/services/roles/empty_roles.js +17 -0
  35. package/build/src/services/roles/role_has_model_permissions.d.ts +32 -33
  36. package/build/src/services/roles/role_has_model_permissions.js +64 -78
  37. package/build/src/services/roles/roles_service.d.ts +20 -9
  38. package/build/src/services/roles/roles_service.js +90 -34
  39. package/build/src/types.d.ts +65 -5
  40. package/build/stubs/configs/permissions.stub +1 -1
  41. package/build/stubs/migrations/create_db.stub +8 -8
  42. package/package.json +3 -1
  43. package/build/src/mixins/has_role_permissions.d.ts +0 -128
  44. package/build/src/mixins/has_role_permissions.js +0 -10
  45. package/build/src/mixins/has_roles.d.ts +0 -1
  46. package/build/src/mixins/has_roles.js +0 -47
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Role permissions system for AdonisJS V6+
2
2
 
3
- ## Under development!
3
+ ## Beta version
4
4
 
5
- [![test](https://github.com/holoyan/adonisjs-permissions/actions/workflows/test.yml/badge.svg)](https://github.com/holoyan/adonisjs-permissions/actions/workflows/test.yml)
5
+ [//]: # ([![test](https://github.com/holoyan/adonisjs-permissions/actions/workflows/test.yml/badge.svg)](https://github.com/holoyan/adonisjs-permissions/actions/workflows/test.yml))
6
6
  [![license](https://poser.pugx.org/silber/bouncer/license.svg)](https://github.com/holoyan/adonisjs-permissions/blob/master/LICENSE.md)
7
7
 
8
8
  ## Table of Contents
@@ -12,6 +12,10 @@
12
12
  - [Introduction](#introduction)
13
13
  - [Installation](#installation)
14
14
  - [Configuration](#configuration)
15
+ - [Mixins](#mixins)
16
+ - [Support](#support)
17
+ - [Database support](#database-support)
18
+ - [UUID support](#uuid-support)
15
19
  - [Basic Usage](#basic-usage)
16
20
  - [Creating roles and permissions](#creating-roles-and-permissions)
17
21
  - [Assigning permissions to the roles (Globally)](#assigning-permissions-to-the-roles-globally)
@@ -30,8 +34,9 @@
30
34
  - [Forbidding permissions on a resource](#forbidding-permissions-on-a-resource)
31
35
  - [Checking for forbidden permissions](#checking-for-forbidden-permissions)
32
36
  - [Unforbidding the permissions](#unforbidding-the-permissions)
33
- - [Global v resource permissions (Important!)](#global-v-resource-permissions-important)
37
+ - [Global vs resource permissions (Important!)](#global-vs-resource-permissions-important)
34
38
  - [containsPermission v hasPermission](#containspermission-v-haspermission)
39
+ - [Test](#test)
35
40
  - [License](#license)
36
41
  </p></details>
37
42
 
@@ -56,16 +61,108 @@ await Acl.permission('edit').attachToModel(user);
56
61
  // You can also grant a permission only to a specific model
57
62
  const post = await Post.first()
58
63
  await Acl.model(user).allow('delete', post);
64
+ // or
65
+ await user.allow('delete', post)
59
66
  ```
60
67
 
61
- To be able to use full power of Acl you should have clear understanding how it is structured and works, that's why documentation will be divided into two parts - [Basic usage](#basic-usage) and [Advanced usage](#advanced-usage) .
68
+ To be able to use full power of Acl you should have clear understanding how it is structured and works, that's why documentation will be divided into two parts - [Basic usage](#basic-usage) and [Advanced usage](#digging-deeper) .
62
69
  For most of the applications [Basic usage](#basic-usage) will be enough
63
70
 
64
71
  ## Installation
65
- npm install ...
72
+
73
+ npm i @holoyan/adonisjs-permissions
74
+
75
+
76
+ Next publish config files
77
+
78
+ node ace configure @holoyan/adonisjs-permissions
79
+ this will create permissions.ts file in `configs` and migration file in the `database/migrations` directory
80
+
81
+ Next run migration
82
+
83
+ node ace migration:run
84
+
66
85
 
67
86
  ## Configuration
68
87
 
88
+ All models which will interact with `Acl` MUST use `@MorphMap('ALIAS_FOR_CLASS')` decorator and implement `AclModelInterface` contract
89
+
90
+ Example.
91
+
92
+ ```typescript
93
+
94
+ import { BaseModel, column } from '@adonisjs/lucid/orm'
95
+ import { MorphMap } from '@holoyan/adonisjs-permissions'
96
+ import { AclModelInterface } from '@holoyan/adonisjs-permissions/types'
97
+
98
+ @MorphMap('users')
99
+ export default class User extends BaseModel implements AclModelInterface {
100
+ getModelId(): number {
101
+ return this.id
102
+ }
103
+
104
+ // other code goes here
105
+ }
106
+
107
+ @MorphMap('admins')
108
+ export default class Admin extends BaseModel implements AclModelInterface {
109
+ getModelId(): number {
110
+ return this.id
111
+ }
112
+ // other code goes here
113
+ }
114
+
115
+ @MorphMap('posts')
116
+ export default class Post extends BaseModel implements AclModelInterface {
117
+ getModelId(): number {
118
+ return this.id
119
+ }
120
+
121
+ // other code goes here
122
+ }
123
+
124
+ ```
125
+
126
+
127
+ ## Mixins
128
+
129
+ If you want to be able to call these methods on a `User` model then consider using `hasPermissions` mixin
130
+
131
+ ```typescript
132
+
133
+ import { BaseModel, column } from '@adonisjs/lucid/orm'
134
+ import { MorphMap } from '@holoyan/adonisjs-permissions'
135
+ import { AclModelInterface } from '@holoyan/adonisjs-permissions/types'
136
+
137
+ // import mixin
138
+ import { hasPermissions } from '@holoyan/adonisjs-permissions'
139
+ import { compose } from '@adonisjs/core/helpers'
140
+
141
+ @MorphMap('users')
142
+ export default class User extends compose(BaseModel, hasPermissions()) implements AclModelInterface {
143
+ getModelId(): number {
144
+ return this.id
145
+ }
146
+ // other code goes here
147
+ }
148
+
149
+ // then all methods are available on the user
150
+
151
+ const user = await User.first()
152
+ const roles = await user.roles() // and so on
153
+
154
+
155
+ ```
156
+
157
+ ## Support
158
+
159
+ ### Database Support
160
+
161
+ Currently supported databases: `postgres`, `mysql`, `mssql`
162
+
163
+ ### UUID support
164
+ No uuid support *yet*
165
+
69
166
  ## Basic Usage
70
167
 
71
168
  On this section we will explore basic role permission methods
@@ -200,7 +297,7 @@ const roles = await Acl.model(user).permissions()
200
297
  const models = await Acl.permission(permission).models()
201
298
 
202
299
  ```
203
- this will return array of `ModelPermission` which will contain `modelType,modelId` attributes, where `modelType` is *alias* which you had specified in [morphMap decorator](#morph-map-decorator), `modelId` is the value of column, you've specified in [getModelId]() method.
300
+ this will return array of `ModelPermission` which will contain `modelType,modelId` attributes, where `modelType` is *alias* which you had specified in [morphMap decorator](#configuration), `modelId` is the value of column, you've specified in [getModelId](#configuration) method.
204
301
 
205
302
  Most of the cases you will have only one model (User), it's better to use `modelsFor()` to get concrete models
206
303
 
@@ -242,7 +339,7 @@ you can pass array of roles
242
339
  ```typescript
243
340
 
244
341
  // returns true only if user has all roles
245
- await Acl.model(user).hasAllRoles(['admin', 'manager'])
342
+ await Acl.model(user).hasAllRoles('admin', 'manager')
246
343
 
247
344
  ```
248
345
 
@@ -250,7 +347,7 @@ to check if user has any of roles, will return true if user has at least one rol
250
347
 
251
348
  ```typescript
252
349
 
253
- await Acl.model(user).hasAnyRole(['admin', 'manager'])
350
+ await Acl.model(user).hasAnyRole('admin', 'manager')
254
351
 
255
352
  ```
256
353
 
@@ -550,89 +647,87 @@ await Acl.role(role).containsPermission('delete') // true
550
647
 
551
648
  ```
552
649
 
553
- ### Global v resource permissions (Important!)
650
+ ### Global vs resource permissions (Important!)
554
651
 
555
- > Important! Action performed globally will affect on resource models
652
+ > Important! Action performed globally will affect on a resource models
556
653
 
557
654
  It is very important to understood difference between global and resource permissions and their scope.
558
655
  Look at this way, if there is no `entity` model then action will be performed **globally**, otherwise **on resource**
559
656
 
560
- ```typescript
561
- // global actions
562
- import {Acl} from "@holoyan/adonisjs-permissions";
563
-
564
- // Give a user the permission to edit
565
- await Acl.model(user).allow('edit');
566
-
567
- Acl.model(user).assignDirectPermission('uploadFile')
568
-
569
- await Acl.model(user).forbid('delete')
570
-
571
- await Acl.model(user).hasPermission('create')
572
- await Acl.model(user).unforbid('delete')
573
- // ... and so on
574
-
575
657
  ```
576
658
 
577
- ```typescript
578
- // On resource actions
579
659
 
580
- await Acl.role(admin).assign('edit', product1)
581
- await Acl.model(user).hasPermission('edit', product1)
582
- await Acl.model(user).assignDirectPermission('edit', Post)
660
+ |--------------Global--------------|
661
+ | |
662
+ | |------Class level------| |
663
+ | | | |
664
+ | | |--Model level--| | |
665
+ | | | | | |
666
+ | | | | | |
667
+ | | | | | |
668
+ | | |---------------| | |
669
+ | | | |
670
+ | |-----------------------| |
671
+ | |
672
+ |----------------------------------|
583
673
 
584
674
  ```
585
675
 
586
- As you can see if `entity` (product1, Post and so on) is specified then it's a *on resource* action
587
676
 
588
- Now let's see few examples
589
677
 
590
678
  ```typescript
591
679
  import {Acl} from "@holoyan/adonisjs-permissions";
680
+ import Post from "#models/post";
592
681
 
593
- // Global action
594
- await Acl.model(user).allow('edit');
595
682
 
596
- const product1 = Product.first();
683
+ // Global level
684
+ await Acl.model(admin).allow('create');
685
+ await Acl.model(admin).allow('edit');
686
+ await Acl.model(admin).allow('view');
597
687
 
598
- await Acl.model(user).hasPermission('edit') // true
599
- await Acl.model(user).hasPermission('edit', product1) // true becouse 'edit' permission assigned globaly
600
- await Acl.model(user).hasPermission('edit', ImageModel) // true becouse 'edit' permission assigned globaly
688
+ // class level
689
+ await Acl.model(manager).allow('create', Post)
601
690
 
602
- ```
691
+ // model level
692
+ const myPost = await Post.find(id)
693
+ await Acl.model(client).allow('view', myPost)
603
694
 
604
- Now if do same but assign on Resource, result will be different
605
-
606
- ```typescript
695
+ // checking
696
+ // admin
697
+ await Acl.model(admin).hasPermission('create') // true
698
+ await Acl.model(admin).hasPermission('create', Post) // true
699
+ await Acl.model(admin).hasPermission('create', myPost) // true
607
700
 
608
- const product1 = Product.first();
701
+ // manager
702
+ await Acl.model(manager).hasPermission('create') // false
703
+ await Acl.model(manager).hasPermission('create', Post) // true
704
+ await Acl.model(manager).hasPermission('create', myPost) // true
705
+ await Acl.model(manager).hasPermission('create', myOtherPost) // true
609
706
 
610
- await Acl.model(user).allow('edit', product1);
611
-
612
- await Acl.model(user).hasPermission('edit', product1) // true becouse 'edit' permission assigned to this specific model instance
613
-
614
- await Acl.model(user).hasPermission('edit') // false
615
- await Acl.model(user).hasPermission('edit', Product) // false becouse 'edit' permission assigned to the specific model instance
707
+ // client
708
+ await Acl.model(client).hasPermission('create') // false
709
+ await Acl.model(client).hasPermission('create', Post) // false
710
+ await Acl.model(client).hasPermission('create', myPost) // true
711
+ await Acl.model(client).hasPermission('create', myOtherPost) // false
712
+ // ... and so on
616
713
 
617
714
  ```
618
715
 
619
- let's see one more example
716
+ Same is true when using `forbidden` action
620
717
 
621
718
  ```typescript
622
719
 
623
- await Acl.model(user).allow('edit', Product); // assing to Product model, for all Product instances it will be true
720
+ // class level
721
+ await Acl.model(manager).allow('edit', Post) // allow to edit all posts
624
722
 
625
- const product1 = Product.first();
626
- await Acl.model(user).hasPermission('edit', product1) // true
627
- const product2 = Product.find(someId);
628
- await Acl.model(user).hasPermission('edit', product2) // true
629
- await Acl.model(user).hasPermission('edit', Product) // true
723
+ await Acl.model(manager).forbid('edit', myPost) // forbid editing on a specific post
630
724
 
631
- await Acl.model(user).hasPermission('edit') // false , becouse it's not global, it's only on Product resrouce
632
725
 
633
- ```
726
+ await Acl.model(client).hasPermission('edit', Post) // true
727
+ await Acl.model(client).hasPermission('edit', myPost) // false
728
+ await Acl.model(client).hasPermission('edit', myOtherPost) // true
634
729
 
635
- Anytime you can use `containsPermission()` method to check if user has it
730
+ ```
636
731
 
637
732
  ### containsPermission v hasPermission
638
733
 
@@ -656,6 +751,12 @@ await Acl.model(user).containsPermission('read') // true
656
751
 
657
752
  ```
658
753
 
754
+ ## Test
755
+
756
+ npm run test
757
+
758
+
659
759
  ## License
660
760
 
761
+
661
762
  MIT
package/build/index.d.ts CHANGED
@@ -1,8 +1,14 @@
1
+ import modelRole from './src/models/model_role.js';
2
+ import modelPermission from './src/models/model_permission.js';
3
+ import permission from './src/models/permission.js';
4
+ import role from './src/models/role.js';
5
+ export declare const ModelRole: typeof modelRole;
6
+ export declare const ModelPermission: typeof modelPermission;
7
+ export declare const Permission: typeof permission;
8
+ export declare const Role: typeof role;
1
9
  export { configure } from './configure.js';
2
10
  export { stubsRoot } from './stubs/main.js';
3
11
  export { Acl } from './src/acl.js';
4
- export * from './src/models/role.js';
5
- export * from './src/models/permission.js';
6
- export * from './src/models/model_permission.js';
7
- export * from './src/models/model_role.js';
8
12
  export { MorphMap, getClassPath } from './src/decorators.js';
13
+ export * as morphMapModel from './src/morph_map.js';
14
+ export { hasPermissions } from './src/mixins/has_permissions.js';
package/build/index.js CHANGED
@@ -6,12 +6,17 @@
6
6
  | Export values from the package entrypoint as you see fit.
7
7
  |
8
8
  */
9
+ import modelRole from './src/models/model_role.js';
10
+ import modelPermission from './src/models/model_permission.js';
11
+ import permission from './src/models/permission.js';
12
+ import role from './src/models/role.js';
13
+ export const ModelRole = modelRole;
14
+ export const ModelPermission = modelPermission;
15
+ export const Permission = permission;
16
+ export const Role = role;
9
17
  export { configure } from './configure.js';
10
18
  export { stubsRoot } from './stubs/main.js';
11
19
  export { Acl } from './src/acl.js';
12
- export * from './src/models/role.js';
13
- export * from './src/models/permission.js';
14
- export * from './src/models/model_permission.js';
15
- export * from './src/models/model_role.js';
16
- // export * as HasPermissions from './src/mixins/has_permissions.js'
17
20
  export { MorphMap, getClassPath } from './src/decorators.js';
21
+ export * as morphMapModel from './src/morph_map.js';
22
+ export { hasPermissions } from './src/mixins/has_permissions.js';
@@ -1,12 +1,15 @@
1
1
  import { ApplicationService } from '@adonisjs/core/types';
2
+ import ModelManager from '../src/model_manager.js';
2
3
  import MorphMap from '../src/morph_map.js';
3
4
  declare module '@adonisjs/core/types' {
4
5
  interface ContainerBindings {
5
6
  morphMap: MorphMap;
7
+ modelManager: ModelManager;
6
8
  }
7
9
  }
8
10
  export default class RolePermissionProvider {
9
11
  protected app: ApplicationService;
10
12
  constructor(app: ApplicationService);
11
13
  register(): void;
14
+ boot(): Promise<void>;
12
15
  }
@@ -1,3 +1,9 @@
1
+ import Permission from '../src/models/permission.js';
2
+ import Role from '../src/models/role.js';
3
+ import ModelPermission from '../src/models/model_permission.js';
4
+ import ModelRole from '../src/models/model_role.js';
5
+ import ModelManager from '../src/model_manager.js';
6
+ import { Acl } from '../src/acl.js';
1
7
  import MorphMap from '../src/morph_map.js';
2
8
  export default class RolePermissionProvider {
3
9
  app;
@@ -8,5 +14,20 @@ export default class RolePermissionProvider {
8
14
  this.app.container.singleton('morphMap', async () => {
9
15
  return new MorphMap();
10
16
  });
17
+ this.app.container.singleton('modelManager', async () => {
18
+ return new ModelManager();
19
+ });
20
+ }
21
+ async boot() {
22
+ const modelManager = await this.app.container.make('modelManager');
23
+ modelManager.setModel('permission', Permission);
24
+ modelManager.setModel('role', Role);
25
+ modelManager.setModel('modelPermission', ModelPermission);
26
+ modelManager.setModel('modelRole', ModelRole);
27
+ Acl.setModelManager(modelManager);
28
+ const map = await this.app.container.make('morphMap');
29
+ map.set('permissions', Permission);
30
+ map.set('roles', Role);
31
+ Acl.setMorphMap(map);
11
32
  }
12
33
  }
@@ -1,11 +1,16 @@
1
1
  import { RoleHasModelPermissions } from './services/roles/role_has_model_permissions.js';
2
2
  import { ModelHasRolePermissions } from './services/model_has_role_permissions.js';
3
- import { AclModel } from './types.js';
4
- import Role from './models/role.js';
5
- import Permission from './models/permission.js';
3
+ import { AclModel, MorphInterface, PermissionInterface, RoleInterface } from './types.js';
6
4
  import PermissionHasModelRoles from './services/permissions/permission_has_model_roles.js';
5
+ import ModelManager from './model_manager.js';
6
+ import EmptyPermission from './services/permissions/empty_permission.js';
7
+ import EmptyRoles from './services/roles/empty_roles.js';
7
8
  export declare class Acl {
9
+ private static modelManager;
10
+ private static map;
11
+ static setModelManager(manager: ModelManager): void;
12
+ static setMorphMap(map: MorphInterface): void;
8
13
  static model(model: AclModel): ModelHasRolePermissions;
9
- static role(role: Role | null): typeof Role | RoleHasModelPermissions;
10
- static permission(permisison: Permission | null): typeof Permission | PermissionHasModelRoles;
14
+ static role(role?: RoleInterface): RoleHasModelPermissions | EmptyRoles;
15
+ static permission(permission?: PermissionInterface): PermissionHasModelRoles | EmptyPermission;
11
16
  }
package/build/src/acl.js CHANGED
@@ -2,28 +2,36 @@ import { RoleHasModelPermissions } from './services/roles/role_has_model_permiss
2
2
  import { ModelHasRolePermissions } from './services/model_has_role_permissions.js';
3
3
  import PermissionsService from './services/permissions/permissions_service.js';
4
4
  import RolesService from './services/roles/roles_service.js';
5
- import Role from './models/role.js';
6
- import Permission from './models/permission.js';
7
5
  import PermissionHasModelRoles from './services/permissions/permission_has_model_roles.js';
8
6
  import ModelService from './services/model_service.js';
7
+ import EmptyPermission from './services/permissions/empty_permission.js';
8
+ import EmptyRoles from './services/roles/empty_roles.js';
9
9
  export class Acl {
10
+ static modelManager;
11
+ static map;
12
+ static setModelManager(manager) {
13
+ this.modelManager = manager;
14
+ }
15
+ static setMorphMap(map) {
16
+ this.map = map;
17
+ }
10
18
  static model(model) {
11
- return new ModelHasRolePermissions(model, new RolesService(), new PermissionsService());
19
+ return new ModelHasRolePermissions(model, new RolesService(this.modelManager.getModel('role'), this.modelManager.getModel('modelPermission'), this.modelManager.getModel('modelRole'), this.map), new PermissionsService(this.modelManager.getModel('permission'), this.modelManager.getModel('role'), this.modelManager.getModel('modelPermission'), this.modelManager.getModel('modelRole'), this.map), this.map);
12
20
  }
13
21
  static role(role) {
14
22
  if (role) {
15
- return new RoleHasModelPermissions(role, new PermissionsService(), new ModelService());
23
+ return new RoleHasModelPermissions(role, new PermissionsService(this.modelManager.getModel('permission'), this.modelManager.getModel('role'), this.modelManager.getModel('modelPermission'), this.modelManager.getModel('modelRole'), this.map), new ModelService(this.modelManager.getModel('modelPermission'), this.modelManager.getModel('modelRole'), this.map), this.map);
16
24
  }
17
25
  else {
18
- return Role;
26
+ return new EmptyRoles(this.modelManager.getModel('role'));
19
27
  }
20
28
  }
21
- static permission(permisison) {
22
- if (permisison) {
23
- return new PermissionHasModelRoles(permisison, new RolesService(), new PermissionsService(), new ModelService());
29
+ static permission(permission) {
30
+ if (permission) {
31
+ return new PermissionHasModelRoles(permission, new RolesService(this.modelManager.getModel('role'), this.modelManager.getModel('modelPermission'), this.modelManager.getModel('modelRole'), this.map), new PermissionsService(this.modelManager.getModel('permission'), this.modelManager.getModel('role'), this.modelManager.getModel('modelPermission'), this.modelManager.getModel('modelRole'), this.map), new ModelService(this.modelManager.getModel('modelPermission'), this.modelManager.getModel('modelRole'), this.map), this.modelManager.getModel('modelPermission'), this.modelManager.getModel('modelRole'), this.map);
24
32
  }
25
33
  else {
26
- return Permission;
34
+ return new EmptyPermission(this.modelManager.getModel('permission'));
27
35
  }
28
36
  }
29
37
  }
@@ -7,6 +7,7 @@ export function MorphMap(param) {
7
7
  return param;
8
8
  };
9
9
  target.prototype.__morphMapName = service();
10
+ target.prototype.__morphMapName = param;
10
11
  };
11
12
  }
12
13
  export function getClassPath(clazz) {