@dudousxd/nestjs-authz-mikro-orm 0.3.1 → 0.5.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/CHANGELOG.md +28 -0
- package/README.md +55 -4
- package/dist/entities.d.ts +79 -11
- package/dist/entities.d.ts.map +1 -1
- package/dist/entities.js +124 -100
- package/dist/entities.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/repositories.d.ts +26 -0
- package/dist/repositories.d.ts.map +1 -0
- package/dist/repositories.js +25 -0
- package/dist/repositories.js.map +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +26 -8
- package/dist/schema.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @dudousxd/nestjs-authz-mikro-orm
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#18](https://github.com/DavideCarvalho/nestjs-authz/pull/18) [`a5662a2`](https://github.com/DavideCarvalho/nestjs-authz/commit/a5662a2b599d826ae3a0d08e6ad71da7f2e425dc) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Ship typed MikroORM repositories for the four authz entities, and a schema factory for custom table names.
|
|
8
|
+
|
|
9
|
+
- New `AuthzRoleRepository`, `AuthzPermissionRepository`, `AuthzRolePermissionRepository` and `AuthzUserRoleRepository` (empty `EntityRepository` subclasses), bound to the entities via `repository: () => ...` on each `EntitySchema` plus an `[EntityRepositoryType]` marker on each entity class. `em.getRepository(RoleEntity)` now returns — and is typed as — `AuthzRoleRepository`, and `MikroOrmModule.forFeature([...AUTHZ_ENTITY_CLASSES])` registers each repository class as its own DI token, so host apps inject by type instead of threading the entity class through every `em.find(RoleEntity, ...)`.
|
|
10
|
+
- New `createAuthzEntitySchemas(tableNames?)` — the supported way to relocate the authz tables. It carries the repository binding and derives the index names from the given table names; hand-writing a replacement `EntitySchema` (the previously documented path) silently dropped both. `AUTHZ_ENTITIES` and `RoleEntitySchema` … `UserRoleEntitySchema` are now produced by this factory with the default names, so they are unchanged.
|
|
11
|
+
- New `AUTHZ_ENTITY_CLASSES` export (the four classes in dependency order) for `MikroOrmModule.forFeature()`, which matches on `meta.class`.
|
|
12
|
+
- `ensureAuthzSchema` / `authzSchemaSql` now read the four physical table names off the live metadata instead of hard-coding the `authz_*` literals, so relocated tables are created too.
|
|
13
|
+
|
|
14
|
+
`EntityRepository`, `EntityRepositoryType` and the `repository` option on `EntitySchemaMetadata` all live in `@mikro-orm/core` on both MikroORM 6 and 7, so this adds no peer and no decorator import. Verified against the v6 suite and the pinned `@mikro-orm/core@7` integration suite.
|
|
15
|
+
|
|
16
|
+
`MikroOrmAuthzStore` is unchanged.
|
|
17
|
+
|
|
18
|
+
## 0.4.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- [`45719bb`](https://github.com/DavideCarvalho/nestjs-authz/commit/45719bb958d7abceb8b0edad4c0c3d97f99590cb) - Support MikroORM 7 (peer `@mikro-orm/core` / `@mikro-orm/nestjs` widened to `^6 || ^7`).
|
|
23
|
+
|
|
24
|
+
MikroORM 7 relocated the entity decorators (`@Entity/@Property/@PrimaryKey/@Index`) out of `@mikro-orm/core` into a separate `@mikro-orm/decorators` package, and removed `MikroORM.getSchemaGenerator()`. To run on both v6 and v7 from a single codebase with no extra peer:
|
|
25
|
+
|
|
26
|
+
- The four authz entities are now defined with `EntitySchema` (the one definition style that lives in `@mikro-orm/core` on both majors) instead of decorators. The entity classes (`RoleEntity` … `UserRoleEntity`) are unchanged as the store's reference; their schemas are also exported (`RoleEntitySchema` … `UserRoleEntitySchema`) for BYO-table-name re-declaration.
|
|
27
|
+
- `ensureAuthzSchema` / `authzSchemaSql` now detect a `MikroORM` instance via its `em` property (present on both v6 and v7) instead of the v7-removed `getSchemaGenerator()`, and read the schema generator off the EM-bound platform.
|
|
28
|
+
|
|
29
|
+
Verified end-to-end against `@mikro-orm/core@7` + `@mikro-orm/sqlite@7` (and the existing v6 suite still passes).
|
|
30
|
+
|
|
3
31
|
## 0.3.1
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -7,6 +7,11 @@ roles, permissions, and a Gate seam, with **zero connection ownership** (your ap
|
|
|
7
7
|
This is the MikroORM sibling of `@dudousxd/nestjs-authz-typeorm`: identical store surface
|
|
8
8
|
and `AuthzRbacModule`, backed by MikroORM entities.
|
|
9
9
|
|
|
10
|
+
Works with **MikroORM 6 and 7** (peer `@mikro-orm/core` `^6 || ^7`). The entities are
|
|
11
|
+
defined with `EntitySchema` — the one definition style that lives entirely in
|
|
12
|
+
`@mikro-orm/core` across both majors (v7 moved the `@Entity/@Property/...` decorators into a
|
|
13
|
+
separate `@mikro-orm/decorators` package), so no extra peer is required.
|
|
14
|
+
|
|
10
15
|
## Install
|
|
11
16
|
|
|
12
17
|
```bash
|
|
@@ -31,10 +36,56 @@ import { AUTHZ_ENTITIES } from '@dudousxd/nestjs-authz-mikro-orm';
|
|
|
31
36
|
await MikroORM.init({ entities: [...AUTHZ_ENTITIES /* , your entities */] });
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
### BYO table names
|
|
40
|
+
|
|
41
|
+
MikroORM resolves table names from entity metadata at discovery time. Build your own set of
|
|
42
|
+
schemas with `createAuthzEntitySchemas` and register those instead:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { createAuthzEntitySchemas } from '@dudousxd/nestjs-authz-mikro-orm';
|
|
46
|
+
|
|
47
|
+
const authz = createAuthzEntitySchemas({ roles: 'app_roles', userRole: 'app_user_role' });
|
|
48
|
+
await MikroORM.init({ entities: [...authz.all /* , your entities */] });
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Any subset of `roles` / `permissions` / `rolePermission` / `userRole` may be overridden; the
|
|
52
|
+
rest keep their defaults. The factory carries the custom repository binding and derives the
|
|
53
|
+
index names from your table names, so nothing is lost by relocating the tables — hand-writing
|
|
54
|
+
`new EntitySchema({ class: RoleEntity, tableName })` instead silently drops both. The store and
|
|
55
|
+
the schema helpers read the physical names back off the live metadata and never assume a
|
|
56
|
+
literal name.
|
|
57
|
+
|
|
58
|
+
## Repositories
|
|
59
|
+
|
|
60
|
+
Each entity is bound to a typed repository, so app code injects it by type rather than passing
|
|
61
|
+
the entity class to every `EntityManager` call:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { AUTHZ_ENTITY_CLASSES, AuthzRoleRepository } from '@dudousxd/nestjs-authz-mikro-orm';
|
|
65
|
+
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
|
66
|
+
|
|
67
|
+
@Module({
|
|
68
|
+
// forFeature matches on the entity CLASS — pass these, not the schemas.
|
|
69
|
+
imports: [MikroOrmModule.forFeature([...AUTHZ_ENTITY_CLASSES])],
|
|
70
|
+
})
|
|
71
|
+
export class RolesModule {}
|
|
72
|
+
|
|
73
|
+
@Injectable()
|
|
74
|
+
export class RolesService {
|
|
75
|
+
constructor(private readonly roles: AuthzRoleRepository) {}
|
|
76
|
+
|
|
77
|
+
findByName(name: string) {
|
|
78
|
+
return this.roles.findOne({ name });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Without `@mikro-orm/nestjs`, `em.getRepository(RoleEntity)` returns the same instance and is
|
|
84
|
+
typed as `AuthzRoleRepository`. The four classes are `AuthzRoleRepository`,
|
|
85
|
+
`AuthzPermissionRepository`, `AuthzRolePermissionRepository` and `AuthzUserRoleRepository`;
|
|
86
|
+
their bodies are empty — this package ships no query surface beyond `MikroOrmAuthzStore`.
|
|
87
|
+
|
|
88
|
+
`MikroOrmAuthzStore` is unaffected — it still takes an `EntityManager` and owns no connection.
|
|
38
89
|
|
|
39
90
|
## Usage
|
|
40
91
|
|
package/dist/entities.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { EntityRepositoryType, EntitySchema } from '@mikro-orm/core';
|
|
2
|
+
import { AuthzPermissionRepository, AuthzRolePermissionRepository, AuthzRoleRepository, AuthzUserRoleRepository } from './repositories.js';
|
|
1
3
|
/**
|
|
2
|
-
* Default table names
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Default physical table names. MikroORM resolves the table from entity metadata, so an app
|
|
5
|
+
* that wants different names builds its own set of schemas with
|
|
6
|
+
* {@link createAuthzEntitySchemas}; the store + schema helpers operate purely through the
|
|
7
|
+
* EntityManager and read the physical names back off the live metadata.
|
|
6
8
|
*/
|
|
7
9
|
export declare const DEFAULT_TABLE_NAMES: {
|
|
8
10
|
readonly roles: "authz_roles";
|
|
@@ -10,20 +12,41 @@ export declare const DEFAULT_TABLE_NAMES: {
|
|
|
10
12
|
readonly rolePermission: "authz_role_permission";
|
|
11
13
|
readonly userRole: "authz_user_role";
|
|
12
14
|
};
|
|
15
|
+
/** Physical table names for the four authz tables. */
|
|
16
|
+
export interface AuthzTableNames {
|
|
17
|
+
roles: string;
|
|
18
|
+
permissions: string;
|
|
19
|
+
rolePermission: string;
|
|
20
|
+
userRole: string;
|
|
21
|
+
}
|
|
13
22
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
23
|
+
* The entities are described with {@link EntitySchema} (the schema-first definition style)
|
|
24
|
+
* rather than property decorators. This is the ONE definition surface that lives entirely
|
|
25
|
+
* in `@mikro-orm/core` and is identical across MikroORM 6 and 7 — v7 relocated the
|
|
26
|
+
* `@Entity/@Property/...` decorators to a separate `@mikro-orm/decorators` package, so a
|
|
27
|
+
* decorator-based definition would force an extra peer and break on v6. The plain classes
|
|
28
|
+
* below stay the public reference the store keys on (`em.find(RoleEntity, ...)`,
|
|
29
|
+
* `meta.get(RoleEntity.name)`); the schemas attach metadata to them.
|
|
16
30
|
*
|
|
17
|
-
* Every column declares an explicit `type
|
|
18
|
-
*
|
|
19
|
-
*
|
|
31
|
+
* Every column declares an explicit `type`, so discovery works even when the consuming app
|
|
32
|
+
* compiles with SWC/esbuild/Vite (which don't emit decorator metadata — irrelevant here
|
|
33
|
+
* since we don't rely on reflection, but kept explicit for clarity and parity).
|
|
20
34
|
*
|
|
21
35
|
* Forward-compat rule: any column added to these entities AFTER v1 MUST be nullable or
|
|
22
36
|
* carry a default — `ensureAuthzSchema` only ever runs the non-destructive `safe` diff
|
|
23
37
|
* (create table + add-missing-column), and `ADD COLUMN NOT NULL` without a default fails
|
|
24
38
|
* on a populated table.
|
|
39
|
+
*
|
|
40
|
+
* `[EntityRepositoryType]` is a `declare`d marker: it carries no runtime field (the symbol is
|
|
41
|
+
* skipped by MikroORM's property discovery either way) and only tells the type system what
|
|
42
|
+
* `em.getRepository(RoleEntity)` returns.
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* A named role (e.g. `editor`). Permissions are attached via {@link RolePermissionEntity};
|
|
46
|
+
* users are attached via {@link UserRoleEntity}.
|
|
25
47
|
*/
|
|
26
48
|
export declare class RoleEntity {
|
|
49
|
+
[EntityRepositoryType]?: AuthzRoleRepository;
|
|
27
50
|
id: string;
|
|
28
51
|
name: string;
|
|
29
52
|
guard?: string | null;
|
|
@@ -31,6 +54,7 @@ export declare class RoleEntity {
|
|
|
31
54
|
}
|
|
32
55
|
/** A named permission (e.g. `posts.publish`). Granted to roles via {@link RolePermissionEntity}. */
|
|
33
56
|
export declare class PermissionEntity {
|
|
57
|
+
[EntityRepositoryType]?: AuthzPermissionRepository;
|
|
34
58
|
id: string;
|
|
35
59
|
name: string;
|
|
36
60
|
guard?: string | null;
|
|
@@ -38,6 +62,7 @@ export declare class PermissionEntity {
|
|
|
38
62
|
}
|
|
39
63
|
/** Pivot: role ↔ permission. Composite PK `(roleId, permissionId)`. */
|
|
40
64
|
export declare class RolePermissionEntity {
|
|
65
|
+
[EntityRepositoryType]?: AuthzRolePermissionRepository;
|
|
41
66
|
roleId: string;
|
|
42
67
|
permissionId: string;
|
|
43
68
|
}
|
|
@@ -47,10 +72,53 @@ export declare class RolePermissionEntity {
|
|
|
47
72
|
* (mirrors nestjs-context's `UserRef` shape).
|
|
48
73
|
*/
|
|
49
74
|
export declare class UserRoleEntity {
|
|
75
|
+
[EntityRepositoryType]?: AuthzUserRoleRepository;
|
|
50
76
|
userType: string;
|
|
51
77
|
userId: string;
|
|
52
78
|
roleId: string;
|
|
53
79
|
}
|
|
54
|
-
/**
|
|
55
|
-
export
|
|
80
|
+
/** The four {@link EntitySchema} definitions produced by {@link createAuthzEntitySchemas}. */
|
|
81
|
+
export interface AuthzEntitySchemas {
|
|
82
|
+
role: EntitySchema<RoleEntity>;
|
|
83
|
+
permission: EntitySchema<PermissionEntity>;
|
|
84
|
+
rolePermission: EntitySchema<RolePermissionEntity>;
|
|
85
|
+
userRole: EntitySchema<UserRoleEntity>;
|
|
86
|
+
/** All four, in dependency order — spread into `entities: [...]`. */
|
|
87
|
+
all: [
|
|
88
|
+
EntitySchema<RoleEntity>,
|
|
89
|
+
EntitySchema<PermissionEntity>,
|
|
90
|
+
EntitySchema<RolePermissionEntity>,
|
|
91
|
+
EntitySchema<UserRoleEntity>
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Build the four authz {@link EntitySchema} definitions, optionally under your own table
|
|
96
|
+
* names — this is the supported way to relocate the tables:
|
|
97
|
+
*
|
|
98
|
+
* ```ts
|
|
99
|
+
* const authz = createAuthzEntitySchemas({ roles: 'app_roles' });
|
|
100
|
+
* await MikroORM.init({ entities: [...authz.all] });
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* Going through the factory (rather than hand-writing `new EntitySchema({ tableName })`)
|
|
104
|
+
* keeps the custom repository binding and the index names attached to the renamed tables;
|
|
105
|
+
* a hand-rolled re-declaration silently drops both.
|
|
106
|
+
*/
|
|
107
|
+
export declare function createAuthzEntitySchemas(tableNames?: Partial<AuthzTableNames>): AuthzEntitySchemas;
|
|
108
|
+
export declare const RoleEntitySchema: EntitySchema<RoleEntity, never>;
|
|
109
|
+
export declare const PermissionEntitySchema: EntitySchema<PermissionEntity, never>;
|
|
110
|
+
export declare const RolePermissionEntitySchema: EntitySchema<RolePermissionEntity, never>;
|
|
111
|
+
export declare const UserRoleEntitySchema: EntitySchema<UserRoleEntity, never>;
|
|
112
|
+
/**
|
|
113
|
+
* All entity SCHEMAS, in dependency order — pass to `entities: [...]` registration. These
|
|
114
|
+
* are the {@link EntitySchema} objects MikroORM discovers; the store keys on the plain
|
|
115
|
+
* classes ({@link RoleEntity} etc.), which the schemas are bound to via `class`.
|
|
116
|
+
*/
|
|
117
|
+
export declare const AUTHZ_ENTITIES: [EntitySchema<RoleEntity, never>, EntitySchema<PermissionEntity, never>, EntitySchema<RolePermissionEntity, never>, EntitySchema<UserRoleEntity, never>];
|
|
118
|
+
/**
|
|
119
|
+
* The four entity CLASSES, in the same order. Pass these (not the schemas) to
|
|
120
|
+
* `MikroOrmModule.forFeature()` — it matches on `meta.class`, and only then does it register
|
|
121
|
+
* {@link AuthzRoleRepository} & friends as DI tokens.
|
|
122
|
+
*/
|
|
123
|
+
export declare const AUTHZ_ENTITY_CLASSES: readonly [typeof RoleEntity, typeof PermissionEntity, typeof RolePermissionEntity, typeof UserRoleEntity];
|
|
56
124
|
//# sourceMappingURL=entities.d.ts.map
|
package/dist/entities.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;CAKtB,CAAC;AAEX,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;GAGG;AACH,qBAAa,UAAU;IACb,CAAC,oBAAoB,CAAC,CAAC,EAAE,mBAAmB,CAAC;IACrD,EAAE,EAAG,MAAM,CAAC;IACZ,IAAI,EAAG,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAG,IAAI,CAAC;CAClB;AAED,oGAAoG;AACpG,qBAAa,gBAAgB;IACnB,CAAC,oBAAoB,CAAC,CAAC,EAAE,yBAAyB,CAAC;IAC3D,EAAE,EAAG,MAAM,CAAC;IACZ,IAAI,EAAG,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAG,IAAI,CAAC;CAClB;AAED,uEAAuE;AACvE,qBAAa,oBAAoB;IACvB,CAAC,oBAAoB,CAAC,CAAC,EAAE,6BAA6B,CAAC;IAC/D,MAAM,EAAG,MAAM,CAAC;IAChB,YAAY,EAAG,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACjB,CAAC,oBAAoB,CAAC,CAAC,EAAE,uBAAuB,CAAC;IACzD,QAAQ,EAAG,MAAM,CAAC;IAClB,MAAM,EAAG,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;CACjB;AAED,8FAA8F;AAC9F,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IAC/B,UAAU,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAC3C,cAAc,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;IACnD,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IACvC,qEAAqE;IACrE,GAAG,EAAE;QACH,YAAY,CAAC,UAAU,CAAC;QACxB,YAAY,CAAC,gBAAgB,CAAC;QAC9B,YAAY,CAAC,oBAAoB,CAAC;QAClC,YAAY,CAAC,cAAc,CAAC;KAC7B,CAAC;CACH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,GAAE,OAAO,CAAC,eAAe,CAAM,GACxC,kBAAkB,CAkEpB;AAID,eAAO,MAAM,gBAAgB,iCAAsB,CAAC;AACpD,eAAO,MAAM,sBAAsB,uCAA4B,CAAC;AAChE,eAAO,MAAM,0BAA0B,2CAAgC,CAAC;AACxE,eAAO,MAAM,oBAAoB,qCAA0B,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,cAAc,0JAAqB,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,2GAKvB,CAAC"}
|
package/dist/entities.js
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
-
};
|
|
10
|
-
import { Entity, Index, PrimaryKey, Property } from '@mikro-orm/core';
|
|
1
|
+
import { EntitySchema } from '@mikro-orm/core';
|
|
2
|
+
import { AuthzPermissionRepository, AuthzRolePermissionRepository, AuthzRoleRepository, AuthzUserRoleRepository, } from './repositories.js';
|
|
11
3
|
/**
|
|
12
|
-
* Default table names
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
4
|
+
* Default physical table names. MikroORM resolves the table from entity metadata, so an app
|
|
5
|
+
* that wants different names builds its own set of schemas with
|
|
6
|
+
* {@link createAuthzEntitySchemas}; the store + schema helpers operate purely through the
|
|
7
|
+
* EntityManager and read the physical names back off the live metadata.
|
|
16
8
|
*/
|
|
17
9
|
export const DEFAULT_TABLE_NAMES = {
|
|
18
10
|
roles: 'authz_roles',
|
|
@@ -21,119 +13,151 @@ export const DEFAULT_TABLE_NAMES = {
|
|
|
21
13
|
userRole: 'authz_user_role',
|
|
22
14
|
};
|
|
23
15
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
16
|
+
* The entities are described with {@link EntitySchema} (the schema-first definition style)
|
|
17
|
+
* rather than property decorators. This is the ONE definition surface that lives entirely
|
|
18
|
+
* in `@mikro-orm/core` and is identical across MikroORM 6 and 7 — v7 relocated the
|
|
19
|
+
* `@Entity/@Property/...` decorators to a separate `@mikro-orm/decorators` package, so a
|
|
20
|
+
* decorator-based definition would force an extra peer and break on v6. The plain classes
|
|
21
|
+
* below stay the public reference the store keys on (`em.find(RoleEntity, ...)`,
|
|
22
|
+
* `meta.get(RoleEntity.name)`); the schemas attach metadata to them.
|
|
26
23
|
*
|
|
27
|
-
* Every column declares an explicit `type
|
|
28
|
-
*
|
|
29
|
-
*
|
|
24
|
+
* Every column declares an explicit `type`, so discovery works even when the consuming app
|
|
25
|
+
* compiles with SWC/esbuild/Vite (which don't emit decorator metadata — irrelevant here
|
|
26
|
+
* since we don't rely on reflection, but kept explicit for clarity and parity).
|
|
30
27
|
*
|
|
31
28
|
* Forward-compat rule: any column added to these entities AFTER v1 MUST be nullable or
|
|
32
29
|
* carry a default — `ensureAuthzSchema` only ever runs the non-destructive `safe` diff
|
|
33
30
|
* (create table + add-missing-column), and `ADD COLUMN NOT NULL` without a default fails
|
|
34
31
|
* on a populated table.
|
|
32
|
+
*
|
|
33
|
+
* `[EntityRepositoryType]` is a `declare`d marker: it carries no runtime field (the symbol is
|
|
34
|
+
* skipped by MikroORM's property discovery either way) and only tells the type system what
|
|
35
|
+
* `em.getRepository(RoleEntity)` returns.
|
|
35
36
|
*/
|
|
36
|
-
|
|
37
|
+
/**
|
|
38
|
+
* A named role (e.g. `editor`). Permissions are attached via {@link RolePermissionEntity};
|
|
39
|
+
* users are attached via {@link UserRoleEntity}.
|
|
40
|
+
*/
|
|
41
|
+
export class RoleEntity {
|
|
37
42
|
id;
|
|
38
43
|
name;
|
|
39
44
|
guard;
|
|
40
45
|
createdAt;
|
|
41
|
-
}
|
|
42
|
-
__decorate([
|
|
43
|
-
PrimaryKey({ type: 'string', length: 191 }),
|
|
44
|
-
__metadata("design:type", String)
|
|
45
|
-
], RoleEntity.prototype, "id", void 0);
|
|
46
|
-
__decorate([
|
|
47
|
-
Index({ name: 'authz_roles_name_uniq' }),
|
|
48
|
-
Property({ type: 'string', length: 191, unique: true }),
|
|
49
|
-
__metadata("design:type", String)
|
|
50
|
-
], RoleEntity.prototype, "name", void 0);
|
|
51
|
-
__decorate([
|
|
52
|
-
Property({ type: 'string', nullable: true }),
|
|
53
|
-
__metadata("design:type", Object)
|
|
54
|
-
], RoleEntity.prototype, "guard", void 0);
|
|
55
|
-
__decorate([
|
|
56
|
-
Property({ type: 'datetime' }),
|
|
57
|
-
__metadata("design:type", Date)
|
|
58
|
-
], RoleEntity.prototype, "createdAt", void 0);
|
|
59
|
-
RoleEntity = __decorate([
|
|
60
|
-
Entity({ tableName: DEFAULT_TABLE_NAMES.roles })
|
|
61
|
-
], RoleEntity);
|
|
62
|
-
export { RoleEntity };
|
|
46
|
+
}
|
|
63
47
|
/** A named permission (e.g. `posts.publish`). Granted to roles via {@link RolePermissionEntity}. */
|
|
64
|
-
|
|
48
|
+
export class PermissionEntity {
|
|
65
49
|
id;
|
|
66
50
|
name;
|
|
67
51
|
guard;
|
|
68
52
|
createdAt;
|
|
69
|
-
}
|
|
70
|
-
__decorate([
|
|
71
|
-
PrimaryKey({ type: 'string', length: 191 }),
|
|
72
|
-
__metadata("design:type", String)
|
|
73
|
-
], PermissionEntity.prototype, "id", void 0);
|
|
74
|
-
__decorate([
|
|
75
|
-
Index({ name: 'authz_permissions_name_uniq' }),
|
|
76
|
-
Property({ type: 'string', length: 191, unique: true }),
|
|
77
|
-
__metadata("design:type", String)
|
|
78
|
-
], PermissionEntity.prototype, "name", void 0);
|
|
79
|
-
__decorate([
|
|
80
|
-
Property({ type: 'string', nullable: true }),
|
|
81
|
-
__metadata("design:type", Object)
|
|
82
|
-
], PermissionEntity.prototype, "guard", void 0);
|
|
83
|
-
__decorate([
|
|
84
|
-
Property({ type: 'datetime' }),
|
|
85
|
-
__metadata("design:type", Date)
|
|
86
|
-
], PermissionEntity.prototype, "createdAt", void 0);
|
|
87
|
-
PermissionEntity = __decorate([
|
|
88
|
-
Entity({ tableName: DEFAULT_TABLE_NAMES.permissions })
|
|
89
|
-
], PermissionEntity);
|
|
90
|
-
export { PermissionEntity };
|
|
53
|
+
}
|
|
91
54
|
/** Pivot: role ↔ permission. Composite PK `(roleId, permissionId)`. */
|
|
92
|
-
|
|
55
|
+
export class RolePermissionEntity {
|
|
93
56
|
roleId;
|
|
94
57
|
permissionId;
|
|
95
|
-
}
|
|
96
|
-
__decorate([
|
|
97
|
-
PrimaryKey({ type: 'string', length: 191 }),
|
|
98
|
-
__metadata("design:type", String)
|
|
99
|
-
], RolePermissionEntity.prototype, "roleId", void 0);
|
|
100
|
-
__decorate([
|
|
101
|
-
PrimaryKey({ type: 'string', length: 191 }),
|
|
102
|
-
__metadata("design:type", String)
|
|
103
|
-
], RolePermissionEntity.prototype, "permissionId", void 0);
|
|
104
|
-
RolePermissionEntity = __decorate([
|
|
105
|
-
Entity({ tableName: DEFAULT_TABLE_NAMES.rolePermission })
|
|
106
|
-
], RolePermissionEntity);
|
|
107
|
-
export { RolePermissionEntity };
|
|
58
|
+
}
|
|
108
59
|
/**
|
|
109
60
|
* Pivot: user ↔ role. References the user BY ID ONLY — this package NEVER defines or
|
|
110
61
|
* owns a users table. `userType` lets the same table key polymorphic principals
|
|
111
62
|
* (mirrors nestjs-context's `UserRef` shape).
|
|
112
63
|
*/
|
|
113
|
-
|
|
64
|
+
export class UserRoleEntity {
|
|
114
65
|
userType;
|
|
115
66
|
userId;
|
|
116
67
|
roleId;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Build the four authz {@link EntitySchema} definitions, optionally under your own table
|
|
71
|
+
* names — this is the supported way to relocate the tables:
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* const authz = createAuthzEntitySchemas({ roles: 'app_roles' });
|
|
75
|
+
* await MikroORM.init({ entities: [...authz.all] });
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* Going through the factory (rather than hand-writing `new EntitySchema({ tableName })`)
|
|
79
|
+
* keeps the custom repository binding and the index names attached to the renamed tables;
|
|
80
|
+
* a hand-rolled re-declaration silently drops both.
|
|
81
|
+
*/
|
|
82
|
+
export function createAuthzEntitySchemas(tableNames = {}) {
|
|
83
|
+
const names = { ...DEFAULT_TABLE_NAMES, ...tableNames };
|
|
84
|
+
const role = new EntitySchema({
|
|
85
|
+
class: RoleEntity,
|
|
86
|
+
tableName: names.roles,
|
|
87
|
+
repository: () => AuthzRoleRepository,
|
|
88
|
+
properties: {
|
|
89
|
+
id: { type: 'string', length: 191, primary: true },
|
|
90
|
+
name: {
|
|
91
|
+
type: 'string',
|
|
92
|
+
length: 191,
|
|
93
|
+
unique: true,
|
|
94
|
+
index: `${names.roles}_name_uniq`,
|
|
95
|
+
},
|
|
96
|
+
guard: { type: 'string', nullable: true },
|
|
97
|
+
createdAt: { type: 'datetime' },
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
const permission = new EntitySchema({
|
|
101
|
+
class: PermissionEntity,
|
|
102
|
+
tableName: names.permissions,
|
|
103
|
+
repository: () => AuthzPermissionRepository,
|
|
104
|
+
properties: {
|
|
105
|
+
id: { type: 'string', length: 191, primary: true },
|
|
106
|
+
name: {
|
|
107
|
+
type: 'string',
|
|
108
|
+
length: 191,
|
|
109
|
+
unique: true,
|
|
110
|
+
index: `${names.permissions}_name_uniq`,
|
|
111
|
+
},
|
|
112
|
+
guard: { type: 'string', nullable: true },
|
|
113
|
+
createdAt: { type: 'datetime' },
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
const rolePermission = new EntitySchema({
|
|
117
|
+
class: RolePermissionEntity,
|
|
118
|
+
tableName: names.rolePermission,
|
|
119
|
+
repository: () => AuthzRolePermissionRepository,
|
|
120
|
+
properties: {
|
|
121
|
+
roleId: { type: 'string', length: 191, primary: true },
|
|
122
|
+
permissionId: { type: 'string', length: 191, primary: true },
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
const userRole = new EntitySchema({
|
|
126
|
+
class: UserRoleEntity,
|
|
127
|
+
tableName: names.userRole,
|
|
128
|
+
repository: () => AuthzUserRoleRepository,
|
|
129
|
+
properties: {
|
|
130
|
+
userType: { type: 'string', length: 191, primary: true },
|
|
131
|
+
userId: { type: 'string', length: 191, primary: true },
|
|
132
|
+
roleId: { type: 'string', length: 191, primary: true },
|
|
133
|
+
},
|
|
134
|
+
indexes: [{ name: `${names.userRole}_user_idx`, properties: ['userType', 'userId'] }],
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
role,
|
|
138
|
+
permission,
|
|
139
|
+
rolePermission,
|
|
140
|
+
userRole,
|
|
141
|
+
all: [role, permission, rolePermission, userRole],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const defaultSchemas = createAuthzEntitySchemas();
|
|
145
|
+
export const RoleEntitySchema = defaultSchemas.role;
|
|
146
|
+
export const PermissionEntitySchema = defaultSchemas.permission;
|
|
147
|
+
export const RolePermissionEntitySchema = defaultSchemas.rolePermission;
|
|
148
|
+
export const UserRoleEntitySchema = defaultSchemas.userRole;
|
|
149
|
+
/**
|
|
150
|
+
* All entity SCHEMAS, in dependency order — pass to `entities: [...]` registration. These
|
|
151
|
+
* are the {@link EntitySchema} objects MikroORM discovers; the store keys on the plain
|
|
152
|
+
* classes ({@link RoleEntity} etc.), which the schemas are bound to via `class`.
|
|
153
|
+
*/
|
|
154
|
+
export const AUTHZ_ENTITIES = defaultSchemas.all;
|
|
155
|
+
/**
|
|
156
|
+
* The four entity CLASSES, in the same order. Pass these (not the schemas) to
|
|
157
|
+
* `MikroOrmModule.forFeature()` — it matches on `meta.class`, and only then does it register
|
|
158
|
+
* {@link AuthzRoleRepository} & friends as DI tokens.
|
|
159
|
+
*/
|
|
160
|
+
export const AUTHZ_ENTITY_CLASSES = [
|
|
137
161
|
RoleEntity,
|
|
138
162
|
PermissionEntity,
|
|
139
163
|
RolePermissionEntity,
|
package/dist/entities.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export { AUTHZ_ENTITIES, DEFAULT_TABLE_NAMES, PermissionEntity, RoleEntity, RolePermissionEntity, UserRoleEntity, } from './entities.js';
|
|
1
|
+
export { AUTHZ_ENTITIES, AUTHZ_ENTITY_CLASSES, createAuthzEntitySchemas, DEFAULT_TABLE_NAMES, PermissionEntity, PermissionEntitySchema, RoleEntity, RoleEntitySchema, RolePermissionEntity, RolePermissionEntitySchema, UserRoleEntity, UserRoleEntitySchema, } from './entities.js';
|
|
2
|
+
export type { AuthzEntitySchemas, AuthzTableNames } from './entities.js';
|
|
3
|
+
export { AuthzPermissionRepository, AuthzRolePermissionRepository, AuthzRoleRepository, AuthzUserRoleRepository, } from './repositories.js';
|
|
2
4
|
export { authzSchemaSql, ensureAuthzSchema } from './schema.js';
|
|
3
5
|
export { MikroOrmAuthzStore } from './mikro-orm-authz.store.js';
|
|
4
6
|
export type { UserAuthz } from './mikro-orm-authz.store.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,YAAY,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,2BAA2B,EAC3B,sBAAsB,EACtB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export { AUTHZ_ENTITIES, DEFAULT_TABLE_NAMES, PermissionEntity, RoleEntity, RolePermissionEntity, UserRoleEntity, } from './entities.js';
|
|
1
|
+
export { AUTHZ_ENTITIES, AUTHZ_ENTITY_CLASSES, createAuthzEntitySchemas, DEFAULT_TABLE_NAMES, PermissionEntity, PermissionEntitySchema, RoleEntity, RoleEntitySchema, RolePermissionEntity, RolePermissionEntitySchema, UserRoleEntity, UserRoleEntitySchema, } from './entities.js';
|
|
2
|
+
// VALUE exports on purpose: these classes are the DI tokens `MikroOrmModule.forFeature()`
|
|
3
|
+
// registers, so `export type` would compile green and be `undefined` at runtime.
|
|
4
|
+
export { AuthzPermissionRepository, AuthzRolePermissionRepository, AuthzRoleRepository, AuthzUserRoleRepository, } from './repositories.js';
|
|
2
5
|
export { authzSchemaSql, ensureAuthzSchema } from './schema.js';
|
|
3
6
|
export { MikroOrmAuthzStore } from './mikro-orm-authz.store.js';
|
|
4
7
|
export { AUTHZ_RBAC_OPTIONS, AUTHZ_RBAC_STORE, AuthzRbacModule, defaultUserRefMapper, } from './authz-rbac.module.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAEvB,0FAA0F;AAC1F,iFAAiF;AACjF,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EntityRepository } from '@mikro-orm/core';
|
|
2
|
+
import type { PermissionEntity, RoleEntity, RolePermissionEntity, UserRoleEntity } from './entities.js';
|
|
3
|
+
/**
|
|
4
|
+
* Typed repositories for the four authz entities, so a host app injects `AuthzRoleRepository`
|
|
5
|
+
* by type instead of threading the entity class through `em.find(RoleEntity, ...)` at every
|
|
6
|
+
* call site.
|
|
7
|
+
*
|
|
8
|
+
* The binding is two-sided: `repository: () => ...` on each `EntitySchema` (what
|
|
9
|
+
* `em.getRepository()` and `MikroOrmModule.forFeature()` read at runtime) plus the
|
|
10
|
+
* `[EntityRepositoryType]` marker on each entity class (what makes the return type narrow).
|
|
11
|
+
*
|
|
12
|
+
* `EntityRepository` is exported from `@mikro-orm/core` on both MikroORM 6 and 7, so this
|
|
13
|
+
* needs no extra peer and no decorator import.
|
|
14
|
+
*
|
|
15
|
+
* The bodies are intentionally empty — this package ships no query surface beyond
|
|
16
|
+
* `MikroOrmAuthzStore`; they exist to give the four entities an injectable identity.
|
|
17
|
+
*/
|
|
18
|
+
export declare class AuthzRoleRepository extends EntityRepository<RoleEntity> {
|
|
19
|
+
}
|
|
20
|
+
export declare class AuthzPermissionRepository extends EntityRepository<PermissionEntity> {
|
|
21
|
+
}
|
|
22
|
+
export declare class AuthzRolePermissionRepository extends EntityRepository<RolePermissionEntity> {
|
|
23
|
+
}
|
|
24
|
+
export declare class AuthzUserRoleRepository extends EntityRepository<UserRoleEntity> {
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=repositories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repositories.d.ts","sourceRoot":"","sources":["../src/repositories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EACV,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,cAAc,EACf,MAAM,eAAe,CAAC;AAEvB;;;;;;;;;;;;;;GAcG;AACH,qBAAa,mBAAoB,SAAQ,gBAAgB,CAAC,UAAU,CAAC;CAAG;AAExE,qBAAa,yBAA0B,SAAQ,gBAAgB,CAAC,gBAAgB,CAAC;CAAG;AAEpF,qBAAa,6BAA8B,SAAQ,gBAAgB,CAAC,oBAAoB,CAAC;CAAG;AAE5F,qBAAa,uBAAwB,SAAQ,gBAAgB,CAAC,cAAc,CAAC;CAAG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EntityRepository } from '@mikro-orm/core';
|
|
2
|
+
/**
|
|
3
|
+
* Typed repositories for the four authz entities, so a host app injects `AuthzRoleRepository`
|
|
4
|
+
* by type instead of threading the entity class through `em.find(RoleEntity, ...)` at every
|
|
5
|
+
* call site.
|
|
6
|
+
*
|
|
7
|
+
* The binding is two-sided: `repository: () => ...` on each `EntitySchema` (what
|
|
8
|
+
* `em.getRepository()` and `MikroOrmModule.forFeature()` read at runtime) plus the
|
|
9
|
+
* `[EntityRepositoryType]` marker on each entity class (what makes the return type narrow).
|
|
10
|
+
*
|
|
11
|
+
* `EntityRepository` is exported from `@mikro-orm/core` on both MikroORM 6 and 7, so this
|
|
12
|
+
* needs no extra peer and no decorator import.
|
|
13
|
+
*
|
|
14
|
+
* The bodies are intentionally empty — this package ships no query surface beyond
|
|
15
|
+
* `MikroOrmAuthzStore`; they exist to give the four entities an injectable identity.
|
|
16
|
+
*/
|
|
17
|
+
export class AuthzRoleRepository extends EntityRepository {
|
|
18
|
+
}
|
|
19
|
+
export class AuthzPermissionRepository extends EntityRepository {
|
|
20
|
+
}
|
|
21
|
+
export class AuthzRolePermissionRepository extends EntityRepository {
|
|
22
|
+
}
|
|
23
|
+
export class AuthzUserRoleRepository extends EntityRepository {
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=repositories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repositories.js","sourceRoot":"","sources":["../src/repositories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAQnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,mBAAoB,SAAQ,gBAA4B;CAAG;AAExE,MAAM,OAAO,yBAA0B,SAAQ,gBAAkC;CAAG;AAEpF,MAAM,OAAO,6BAA8B,SAAQ,gBAAsC;CAAG;AAE5F,MAAM,OAAO,uBAAwB,SAAQ,gBAAgC;CAAG"}
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AA4D/D;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvF;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,QAAQ,GAAG,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxF"}
|
package/dist/schema.js
CHANGED
|
@@ -1,16 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { DEFAULT_TABLE_NAMES, PermissionEntity, RoleEntity, RolePermissionEntity, UserRoleEntity, } from './entities.js';
|
|
2
|
+
/** Entity class → the table name to fall back to when the entity is not registered. */
|
|
3
|
+
const AUTHZ_ENTITY_TABLE_DEFAULTS = [
|
|
4
|
+
[RoleEntity, DEFAULT_TABLE_NAMES.roles],
|
|
5
|
+
[PermissionEntity, DEFAULT_TABLE_NAMES.permissions],
|
|
6
|
+
[RolePermissionEntity, DEFAULT_TABLE_NAMES.rolePermission],
|
|
7
|
+
[UserRoleEntity, DEFAULT_TABLE_NAMES.userRole],
|
|
7
8
|
];
|
|
9
|
+
/**
|
|
10
|
+
* The four authz table names — used to filter the schema diff down to our tables. Read off
|
|
11
|
+
* the live metadata so a host that relocated the tables (see `createAuthzEntitySchemas`)
|
|
12
|
+
* still gets them created.
|
|
13
|
+
*/
|
|
14
|
+
function authzTables(em) {
|
|
15
|
+
const metadata = em.getMetadata();
|
|
16
|
+
return AUTHZ_ENTITY_TABLE_DEFAULTS.map(([entity, fallback]) => metadata.find(entity.name)?.tableName ?? fallback);
|
|
17
|
+
}
|
|
8
18
|
/** Resolve an {@link EntityManager} from a {@link MikroORM} or an EM. */
|
|
9
19
|
function toEm(ormOrEm) {
|
|
10
20
|
return isOrm(ormOrEm) ? ormOrEm.em : ormOrEm;
|
|
11
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* A {@link MikroORM} instance exposes its {@link EntityManager} as a (non-null) `em`
|
|
24
|
+
* property; an EntityManager does not expose an `em`. That distinction is stable across
|
|
25
|
+
* MikroORM 6 and 7 — v7 removed `MikroORM.getSchemaGenerator()`, so we can no longer probe
|
|
26
|
+
* for it (the EM-bound generator is read via {@link generatorFor} instead).
|
|
27
|
+
*/
|
|
12
28
|
function isOrm(value) {
|
|
13
|
-
|
|
29
|
+
const candidate = value;
|
|
30
|
+
return candidate.em != null && typeof candidate.em === 'object';
|
|
14
31
|
}
|
|
15
32
|
/** The platform's schema generator for a given EM (driver + EM bound). */
|
|
16
33
|
function generatorFor(em) {
|
|
@@ -18,11 +35,12 @@ function generatorFor(em) {
|
|
|
18
35
|
}
|
|
19
36
|
/** Statements (split, trimmed) from the non-destructive schema diff that touch our tables. */
|
|
20
37
|
async function authzStatements(em) {
|
|
38
|
+
const tables = authzTables(em);
|
|
21
39
|
const sql = await generatorFor(em).getUpdateSchemaSQL({ safe: true, wrap: false });
|
|
22
40
|
return sql
|
|
23
41
|
.split(';')
|
|
24
42
|
.map((s) => s.trim())
|
|
25
|
-
.filter((s) => s.length > 0 &&
|
|
43
|
+
.filter((s) => s.length > 0 && tables.some((t) => new RegExp(`\\b${t}\\b`, 'i').test(s)));
|
|
26
44
|
}
|
|
27
45
|
/**
|
|
28
46
|
* Returns the non-destructive SQL needed to bring only the authz RBAC tables up to date
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dudousxd/nestjs-authz-mikro-orm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "MikroORM RBAC persistence for @dudousxd/nestjs-authz — roles, permissions, and a Gate seam (zero connection ownership).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
],
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@dudousxd/nestjs-authz": ">=0.1.0",
|
|
29
|
-
"@mikro-orm/core": "^6.0.0",
|
|
30
|
-
"@mikro-orm/nestjs": "^5.0.0 || ^6.0.0",
|
|
29
|
+
"@mikro-orm/core": "^6.0.0 || ^7.0.0",
|
|
30
|
+
"@mikro-orm/nestjs": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
|
31
31
|
"@nestjs/common": ">=10.0.0",
|
|
32
32
|
"@nestjs/core": ">=10.0.0",
|
|
33
33
|
"reflect-metadata": ">=0.1.13"
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"rxjs": "^7.8.1",
|
|
50
50
|
"typescript": "^5.4.0",
|
|
51
51
|
"vitest": "^3.0.0",
|
|
52
|
-
"@dudousxd/nestjs-authz": "^0.6.
|
|
52
|
+
"@dudousxd/nestjs-authz": "^0.6.4"
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
|
55
55
|
"node": ">=20"
|