@rhino-dev/rhino-nestjs 0.2.5

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 (191) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +427 -0
  3. package/dist/blueprint/blueprint-parser.d.ts +130 -0
  4. package/dist/blueprint/blueprint-parser.js +276 -0
  5. package/dist/blueprint/blueprint-parser.js.map +1 -0
  6. package/dist/blueprint/blueprint-runner.d.ts +51 -0
  7. package/dist/blueprint/blueprint-runner.js +238 -0
  8. package/dist/blueprint/blueprint-runner.js.map +1 -0
  9. package/dist/blueprint/blueprint-validator.d.ts +19 -0
  10. package/dist/blueprint/blueprint-validator.js +163 -0
  11. package/dist/blueprint/blueprint-validator.js.map +1 -0
  12. package/dist/blueprint/generators/policy-generator.d.ts +40 -0
  13. package/dist/blueprint/generators/policy-generator.js +157 -0
  14. package/dist/blueprint/generators/policy-generator.js.map +1 -0
  15. package/dist/blueprint/generators/prisma-schema-generator.d.ts +43 -0
  16. package/dist/blueprint/generators/prisma-schema-generator.js +197 -0
  17. package/dist/blueprint/generators/prisma-schema-generator.js.map +1 -0
  18. package/dist/blueprint/generators/resource-definition-generator.d.ts +52 -0
  19. package/dist/blueprint/generators/resource-definition-generator.js +229 -0
  20. package/dist/blueprint/generators/resource-definition-generator.js.map +1 -0
  21. package/dist/blueprint/generators/seeder-generator.d.ts +21 -0
  22. package/dist/blueprint/generators/seeder-generator.js +135 -0
  23. package/dist/blueprint/generators/seeder-generator.js.map +1 -0
  24. package/dist/blueprint/generators/test-generator.d.ts +28 -0
  25. package/dist/blueprint/generators/test-generator.js +275 -0
  26. package/dist/blueprint/generators/test-generator.js.map +1 -0
  27. package/dist/blueprint/manifest-manager.d.ts +58 -0
  28. package/dist/blueprint/manifest-manager.js +137 -0
  29. package/dist/blueprint/manifest-manager.js.map +1 -0
  30. package/dist/cli/commands/blueprint.command.d.ts +16 -0
  31. package/dist/cli/commands/blueprint.command.js +35 -0
  32. package/dist/cli/commands/blueprint.command.js.map +1 -0
  33. package/dist/cli/commands/export-postman.command.d.ts +5 -0
  34. package/dist/cli/commands/export-postman.command.js +39 -0
  35. package/dist/cli/commands/export-postman.command.js.map +1 -0
  36. package/dist/cli/commands/export-types.command.d.ts +4 -0
  37. package/dist/cli/commands/export-types.command.js +36 -0
  38. package/dist/cli/commands/export-types.command.js.map +1 -0
  39. package/dist/cli/commands/generate.command.d.ts +6 -0
  40. package/dist/cli/commands/generate.command.js +212 -0
  41. package/dist/cli/commands/generate.command.js.map +1 -0
  42. package/dist/cli/commands/install.command.d.ts +8 -0
  43. package/dist/cli/commands/install.command.js +205 -0
  44. package/dist/cli/commands/install.command.js.map +1 -0
  45. package/dist/cli/index.d.ts +17 -0
  46. package/dist/cli/index.js +123 -0
  47. package/dist/cli/index.js.map +1 -0
  48. package/dist/cli/utils/io.d.ts +12 -0
  49. package/dist/cli/utils/io.js +74 -0
  50. package/dist/cli/utils/io.js.map +1 -0
  51. package/dist/cli/utils/prompt.d.ts +12 -0
  52. package/dist/cli/utils/prompt.js +78 -0
  53. package/dist/cli/utils/prompt.js.map +1 -0
  54. package/dist/constants/tokens.d.ts +3 -0
  55. package/dist/constants/tokens.js +7 -0
  56. package/dist/constants/tokens.js.map +1 -0
  57. package/dist/controllers/auth.controller.d.ts +59 -0
  58. package/dist/controllers/auth.controller.js +121 -0
  59. package/dist/controllers/auth.controller.js.map +1 -0
  60. package/dist/controllers/global.controller.d.ts +44 -0
  61. package/dist/controllers/global.controller.js +357 -0
  62. package/dist/controllers/global.controller.js.map +1 -0
  63. package/dist/controllers/invitation.controller.d.ts +30 -0
  64. package/dist/controllers/invitation.controller.js +111 -0
  65. package/dist/controllers/invitation.controller.js.map +1 -0
  66. package/dist/controllers/nested.controller.d.ts +12 -0
  67. package/dist/controllers/nested.controller.js +69 -0
  68. package/dist/controllers/nested.controller.js.map +1 -0
  69. package/dist/decorators/index.d.ts +33 -0
  70. package/dist/decorators/index.js +79 -0
  71. package/dist/decorators/index.js.map +1 -0
  72. package/dist/errors/rhino-exception.d.ts +24 -0
  73. package/dist/errors/rhino-exception.js +47 -0
  74. package/dist/errors/rhino-exception.js.map +1 -0
  75. package/dist/exporters/postman-exporter.d.ts +21 -0
  76. package/dist/exporters/postman-exporter.js +396 -0
  77. package/dist/exporters/postman-exporter.js.map +1 -0
  78. package/dist/exporters/typescript-exporter.d.ts +23 -0
  79. package/dist/exporters/typescript-exporter.js +129 -0
  80. package/dist/exporters/typescript-exporter.js.map +1 -0
  81. package/dist/guards/jwt-auth.guard.d.ts +16 -0
  82. package/dist/guards/jwt-auth.guard.js +61 -0
  83. package/dist/guards/jwt-auth.guard.js.map +1 -0
  84. package/dist/guards/resource-policy.guard.d.ts +12 -0
  85. package/dist/guards/resource-policy.guard.js +111 -0
  86. package/dist/guards/resource-policy.guard.js.map +1 -0
  87. package/dist/index.d.ts +60 -0
  88. package/dist/index.js +171 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/interceptors/hidden-columns.interceptor.d.ts +18 -0
  91. package/dist/interceptors/hidden-columns.interceptor.js +66 -0
  92. package/dist/interceptors/hidden-columns.interceptor.js.map +1 -0
  93. package/dist/interceptors/response.interceptor.d.ts +19 -0
  94. package/dist/interceptors/response.interceptor.js +47 -0
  95. package/dist/interceptors/response.interceptor.js.map +1 -0
  96. package/dist/interfaces/rhino-config.interface.d.ts +103 -0
  97. package/dist/interfaces/rhino-config.interface.js +3 -0
  98. package/dist/interfaces/rhino-config.interface.js.map +1 -0
  99. package/dist/interfaces/rhino-request.interface.d.ts +12 -0
  100. package/dist/interfaces/rhino-request.interface.js +3 -0
  101. package/dist/interfaces/rhino-request.interface.js.map +1 -0
  102. package/dist/middleware/resolve-organization.middleware.d.ts +15 -0
  103. package/dist/middleware/resolve-organization.middleware.js +38 -0
  104. package/dist/middleware/resolve-organization.middleware.js.map +1 -0
  105. package/dist/middleware/route-group.middleware.d.ts +17 -0
  106. package/dist/middleware/route-group.middleware.js +60 -0
  107. package/dist/middleware/route-group.middleware.js.map +1 -0
  108. package/dist/middleware/tenant-route-rewrite.d.ts +76 -0
  109. package/dist/middleware/tenant-route-rewrite.js +124 -0
  110. package/dist/middleware/tenant-route-rewrite.js.map +1 -0
  111. package/dist/policies/resource-policy.d.ts +25 -0
  112. package/dist/policies/resource-policy.js +77 -0
  113. package/dist/policies/resource-policy.js.map +1 -0
  114. package/dist/prisma/prisma-soft-delete.extension.d.ts +16 -0
  115. package/dist/prisma/prisma-soft-delete.extension.js +57 -0
  116. package/dist/prisma/prisma-soft-delete.extension.js.map +1 -0
  117. package/dist/prisma/prisma-uuid.extension.d.ts +9 -0
  118. package/dist/prisma/prisma-uuid.extension.js +28 -0
  119. package/dist/prisma/prisma-uuid.extension.js.map +1 -0
  120. package/dist/prisma/prisma.service.d.ts +38 -0
  121. package/dist/prisma/prisma.service.js +100 -0
  122. package/dist/prisma/prisma.service.js.map +1 -0
  123. package/dist/rhino.config.d.ts +43 -0
  124. package/dist/rhino.config.js +130 -0
  125. package/dist/rhino.config.js.map +1 -0
  126. package/dist/rhino.module.d.ts +61 -0
  127. package/dist/rhino.module.js +268 -0
  128. package/dist/rhino.module.js.map +1 -0
  129. package/dist/services/audit.service.d.ts +35 -0
  130. package/dist/services/audit.service.js +92 -0
  131. package/dist/services/audit.service.js.map +1 -0
  132. package/dist/services/auth.service.d.ts +33 -0
  133. package/dist/services/auth.service.js +157 -0
  134. package/dist/services/auth.service.js.map +1 -0
  135. package/dist/services/invitation.service.d.ts +37 -0
  136. package/dist/services/invitation.service.js +143 -0
  137. package/dist/services/invitation.service.js.map +1 -0
  138. package/dist/services/nested.service.d.ts +34 -0
  139. package/dist/services/nested.service.js +163 -0
  140. package/dist/services/nested.service.js.map +1 -0
  141. package/dist/services/organization.service.d.ts +13 -0
  142. package/dist/services/organization.service.js +60 -0
  143. package/dist/services/organization.service.js.map +1 -0
  144. package/dist/services/query-builder.service.d.ts +31 -0
  145. package/dist/services/query-builder.service.js +151 -0
  146. package/dist/services/query-builder.service.js.map +1 -0
  147. package/dist/services/resource.service.d.ts +38 -0
  148. package/dist/services/resource.service.js +230 -0
  149. package/dist/services/resource.service.js.map +1 -0
  150. package/dist/services/route-registration.service.d.ts +40 -0
  151. package/dist/services/route-registration.service.js +68 -0
  152. package/dist/services/route-registration.service.js.map +1 -0
  153. package/dist/services/scope.service.d.ts +16 -0
  154. package/dist/services/scope.service.js +32 -0
  155. package/dist/services/scope.service.js.map +1 -0
  156. package/dist/services/serializer.service.d.ts +36 -0
  157. package/dist/services/serializer.service.js +90 -0
  158. package/dist/services/serializer.service.js.map +1 -0
  159. package/dist/services/validation.service.d.ts +50 -0
  160. package/dist/services/validation.service.js +203 -0
  161. package/dist/services/validation.service.js.map +1 -0
  162. package/dist/tsconfig.build.tsbuildinfo +1 -0
  163. package/dist/utils/fk-chain-walker.d.ts +30 -0
  164. package/dist/utils/fk-chain-walker.js +23 -0
  165. package/dist/utils/fk-chain-walker.js.map +1 -0
  166. package/dist/utils/format.d.ts +7 -0
  167. package/dist/utils/format.js +28 -0
  168. package/dist/utils/format.js.map +1 -0
  169. package/dist/utils/model-builder.d.ts +64 -0
  170. package/dist/utils/model-builder.js +67 -0
  171. package/dist/utils/model-builder.js.map +1 -0
  172. package/dist/utils/permission-matcher.d.ts +46 -0
  173. package/dist/utils/permission-matcher.js +120 -0
  174. package/dist/utils/permission-matcher.js.map +1 -0
  175. package/dist/utils/scope-discovery.d.ts +34 -0
  176. package/dist/utils/scope-discovery.js +102 -0
  177. package/dist/utils/scope-discovery.js.map +1 -0
  178. package/package.json +64 -0
  179. package/stubs/skills/rhino-audit.md +184 -0
  180. package/stubs/skills/rhino-bugfix.md +117 -0
  181. package/stubs/skills/rhino-deploy.md +5 -0
  182. package/stubs/skills/rhino-docs.md +147 -0
  183. package/stubs/skills/rhino-feature.md +146 -0
  184. package/stubs/skills/rhino-migrate.md +181 -0
  185. package/stubs/skills/rhino-model.md +180 -0
  186. package/stubs/skills/rhino-plan.md +5 -0
  187. package/stubs/skills/rhino-policy.md +183 -0
  188. package/stubs/skills/rhino-refactor.md +147 -0
  189. package/stubs/skills/rhino-review.md +113 -0
  190. package/stubs/skills/rhino-scope.md +140 -0
  191. package/stubs/skills/rhino-test.md +233 -0
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Base authorization policy. Subclass and override per-resource.
3
+ * Matches Laravel's `Rhino\Policies\ResourcePolicy` semantics 1:1.
4
+ */
5
+ export declare class ResourcePolicy {
6
+ /**
7
+ * Resource slug used in the `{slug}.{action}` permission lookup.
8
+ * If not set, the guard will inject it from the model registry at runtime.
9
+ */
10
+ resourceSlug?: string;
11
+ viewAny(user: any, organization?: any): boolean;
12
+ view(user: any, _model: any, organization?: any): boolean;
13
+ create(user: any, organization?: any): boolean;
14
+ update(user: any, _model: any, organization?: any): boolean;
15
+ delete(user: any, _model: any, organization?: any): boolean;
16
+ viewTrashed(user: any, organization?: any): boolean;
17
+ restore(user: any, _model: any, organization?: any): boolean;
18
+ forceDelete(user: any, _model: any, organization?: any): boolean;
19
+ permittedAttributesForShow(_user: any, _org?: any): string[];
20
+ hiddenAttributesForShow(_user: any, _org?: any): string[];
21
+ permittedAttributesForCreate(_user: any, _org?: any): string[];
22
+ permittedAttributesForUpdate(_user: any, _org?: any): string[];
23
+ protected checkPermission(user: any, action: string, organization?: any): boolean;
24
+ protected hasRole(user: any, role: string, organization?: any): boolean;
25
+ }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResourcePolicy = void 0;
4
+ const permission_matcher_1 = require("../utils/permission-matcher");
5
+ /**
6
+ * Base authorization policy. Subclass and override per-resource.
7
+ * Matches Laravel's `Rhino\Policies\ResourcePolicy` semantics 1:1.
8
+ */
9
+ class ResourcePolicy {
10
+ /**
11
+ * Resource slug used in the `{slug}.{action}` permission lookup.
12
+ * If not set, the guard will inject it from the model registry at runtime.
13
+ */
14
+ resourceSlug;
15
+ // ---------------- CRUD ----------------
16
+ viewAny(user, organization) {
17
+ return this.checkPermission(user, 'index', organization);
18
+ }
19
+ view(user, _model, organization) {
20
+ return this.checkPermission(user, 'show', organization);
21
+ }
22
+ create(user, organization) {
23
+ return this.checkPermission(user, 'store', organization);
24
+ }
25
+ update(user, _model, organization) {
26
+ return this.checkPermission(user, 'update', organization);
27
+ }
28
+ delete(user, _model, organization) {
29
+ return this.checkPermission(user, 'destroy', organization);
30
+ }
31
+ // ---------------- Soft delete ----------------
32
+ viewTrashed(user, organization) {
33
+ return this.checkPermission(user, 'trashed', organization);
34
+ }
35
+ restore(user, _model, organization) {
36
+ return this.checkPermission(user, 'restore', organization);
37
+ }
38
+ forceDelete(user, _model, organization) {
39
+ return this.checkPermission(user, 'forceDelete', organization);
40
+ }
41
+ // ---------------- Attribute permissions ----------------
42
+ // `org` is optional so subclasses can use `this.hasRole(user, '...', org)`.
43
+ // The built-in SerializerService / ValidationService call these without org —
44
+ // leave org `undefined` in that path and rely on role detection from the user
45
+ // itself (Laravel parity).
46
+ permittedAttributesForShow(_user, _org) {
47
+ return ['*'];
48
+ }
49
+ hiddenAttributesForShow(_user, _org) {
50
+ return [];
51
+ }
52
+ permittedAttributesForCreate(_user, _org) {
53
+ return ['*'];
54
+ }
55
+ permittedAttributesForUpdate(_user, _org) {
56
+ return ['*'];
57
+ }
58
+ // ---------------- Helpers ----------------
59
+ checkPermission(user, action, organization) {
60
+ if (!user)
61
+ return false;
62
+ const slug = this.resourceSlug;
63
+ if (!slug)
64
+ return false;
65
+ return (0, permission_matcher_1.userHasPermission)(user, `${slug}.${action}`, organization ?? null);
66
+ }
67
+ hasRole(user, role, organization) {
68
+ if (!user)
69
+ return false;
70
+ const orgId = organization?.id;
71
+ if (orgId == null)
72
+ return false;
73
+ return (0, permission_matcher_1.resolveUserRoleSlug)(user, orgId) === role;
74
+ }
75
+ }
76
+ exports.ResourcePolicy = ResourcePolicy;
77
+ //# sourceMappingURL=resource-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-policy.js","sourceRoot":"","sources":["../../src/policies/resource-policy.ts"],"names":[],"mappings":";;;AAAA,oEAAqF;AAErF;;;GAGG;AACH,MAAa,cAAc;IACzB;;;OAGG;IACH,YAAY,CAAU;IAEtB,yCAAyC;IACzC,OAAO,CAAC,IAAS,EAAE,YAAkB;QACnC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,IAAS,EAAE,MAAW,EAAE,YAAkB;QAC7C,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,CAAC,IAAS,EAAE,YAAkB;QAClC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,CAAC,IAAS,EAAE,MAAW,EAAE,YAAkB;QAC/C,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,CAAC,IAAS,EAAE,MAAW,EAAE,YAAkB;QAC/C,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;IAED,gDAAgD;IAChD,WAAW,CAAC,IAAS,EAAE,YAAkB;QACvC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,CAAC,IAAS,EAAE,MAAW,EAAE,YAAkB;QAChD,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;IACD,WAAW,CAAC,IAAS,EAAE,MAAW,EAAE,YAAkB;QACpD,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;IACjE,CAAC;IAED,0DAA0D;IAC1D,4EAA4E;IAC5E,8EAA8E;IAC9E,8EAA8E;IAC9E,2BAA2B;IAC3B,0BAA0B,CAAC,KAAU,EAAE,IAAU;QAC/C,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IACD,uBAAuB,CAAC,KAAU,EAAE,IAAU;QAC5C,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,4BAA4B,CAAC,KAAU,EAAE,IAAU;QACjD,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IACD,4BAA4B,CAAC,KAAU,EAAE,IAAU;QACjD,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IAED,4CAA4C;IAClC,eAAe,CAAC,IAAS,EAAE,MAAc,EAAE,YAAkB;QACrE,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,OAAO,IAAA,sCAAiB,EAAC,IAAI,EAAE,GAAG,IAAI,IAAI,MAAM,EAAE,EAAE,YAAY,IAAI,IAAI,CAAC,CAAC;IAC5E,CAAC;IAES,OAAO,CAAC,IAAS,EAAE,IAAY,EAAE,YAAkB;QAC3D,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,KAAK,GAAG,YAAY,EAAE,EAAE,CAAC;QAC/B,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,KAAK,CAAC;QAChC,OAAO,IAAA,wCAAmB,EAAC,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;IACnD,CAAC;CACF;AAnED,wCAmEC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Prisma client extension implementing Laravel-style soft deletes.
3
+ *
4
+ * import { PrismaClient } from '@prisma/client';
5
+ * import { withSoftDelete } from '@rhino-dev/rhino-nestjs';
6
+ *
7
+ * const prisma = withSoftDelete(new PrismaClient(), ['post', 'comment']);
8
+ *
9
+ * When applied, the extension:
10
+ * - auto-appends `deletedAt: null` to `findMany`, `findFirst`, `findUnique`, `count`
11
+ * - rewrites `delete` to `update { deletedAt: new Date() }`
12
+ * - leaves `deleteMany` untouched (hard delete) so the framework can offer forceDelete
13
+ */
14
+ export declare function withSoftDelete<T extends {
15
+ $extends: Function;
16
+ }>(prisma: T, softDeleteModels: string[]): T;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withSoftDelete = withSoftDelete;
4
+ /**
5
+ * Prisma client extension implementing Laravel-style soft deletes.
6
+ *
7
+ * import { PrismaClient } from '@prisma/client';
8
+ * import { withSoftDelete } from '@rhino-dev/rhino-nestjs';
9
+ *
10
+ * const prisma = withSoftDelete(new PrismaClient(), ['post', 'comment']);
11
+ *
12
+ * When applied, the extension:
13
+ * - auto-appends `deletedAt: null` to `findMany`, `findFirst`, `findUnique`, `count`
14
+ * - rewrites `delete` to `update { deletedAt: new Date() }`
15
+ * - leaves `deleteMany` untouched (hard delete) so the framework can offer forceDelete
16
+ */
17
+ function withSoftDelete(prisma, softDeleteModels) {
18
+ const softSet = new Set(softDeleteModels.map((m) => m.toLowerCase()));
19
+ const isSoft = (model) => !!model && softSet.has(model.toLowerCase());
20
+ const applyFilter = (args) => {
21
+ const base = args.where ?? {};
22
+ if (base.deletedAt !== undefined)
23
+ return args;
24
+ return { ...args, where: { ...base, deletedAt: null } };
25
+ };
26
+ return prisma.$extends({
27
+ name: 'rhino-soft-delete',
28
+ query: {
29
+ $allModels: {
30
+ async findMany({ model, args, query }) {
31
+ return isSoft(model) ? query(applyFilter(args)) : query(args);
32
+ },
33
+ async findFirst({ model, args, query }) {
34
+ return isSoft(model) ? query(applyFilter(args)) : query(args);
35
+ },
36
+ async findFirstOrThrow({ model, args, query }) {
37
+ return isSoft(model) ? query(applyFilter(args)) : query(args);
38
+ },
39
+ async count({ model, args, query }) {
40
+ return isSoft(model) ? query(applyFilter(args ?? {})) : query(args);
41
+ },
42
+ async delete({ model, args, query }) {
43
+ if (!isSoft(model))
44
+ return query(args);
45
+ return prisma[camel(model)].update({
46
+ where: args.where,
47
+ data: { deletedAt: new Date() },
48
+ });
49
+ },
50
+ },
51
+ },
52
+ });
53
+ }
54
+ function camel(name) {
55
+ return name.charAt(0).toLowerCase() + name.slice(1);
56
+ }
57
+ //# sourceMappingURL=prisma-soft-delete.extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-soft-delete.extension.js","sourceRoot":"","sources":["../../src/prisma/prisma-soft-delete.extension.ts"],"names":[],"mappings":";;AAaA,wCAwCC;AArDD;;;;;;;;;;;;GAYG;AACH,SAAgB,cAAc,CAC5B,MAAS,EACT,gBAA0B;IAE1B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAEtE,MAAM,MAAM,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAE/E,MAAM,WAAW,GAAG,CAAC,IAAS,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAC9C,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;IAC1D,CAAC,CAAC;IAEF,OAAQ,MAAc,CAAC,QAAQ,CAAC;QAC9B,IAAI,EAAE,mBAAmB;QACzB,KAAK,EAAE;YACL,UAAU,EAAE;gBACV,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAO;oBACxC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChE,CAAC;gBACD,KAAK,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAO;oBACzC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChE,CAAC;gBACD,KAAK,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAO;oBAChD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChE,CAAC;gBACD,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAO;oBACrC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACtE,CAAC;gBACD,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAO;oBACtC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;wBAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;oBACvC,OAAQ,MAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;wBAC1C,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE;qBAChC,CAAC,CAAC;gBACL,CAAC;aACF;SACF;KACF,CAAM,CAAC;AACV,CAAC;AAED,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Prisma client extension that auto-generates UUIDs for models listed in `uuidModels`.
3
+ * This is a convenience wrapper — Prisma's `@default(uuid())` on the schema is
4
+ * the preferred approach, but this helper covers cases where the schema is not
5
+ * owned by the library or migration-controlled.
6
+ */
7
+ export declare function withUuid<T extends {
8
+ $extends: Function;
9
+ }>(prisma: T, uuidModels: string[]): T;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withUuid = withUuid;
4
+ const crypto_1 = require("crypto");
5
+ /**
6
+ * Prisma client extension that auto-generates UUIDs for models listed in `uuidModels`.
7
+ * This is a convenience wrapper — Prisma's `@default(uuid())` on the schema is
8
+ * the preferred approach, but this helper covers cases where the schema is not
9
+ * owned by the library or migration-controlled.
10
+ */
11
+ function withUuid(prisma, uuidModels) {
12
+ const uuidSet = new Set(uuidModels.map((m) => m.toLowerCase()));
13
+ const needsUuid = (model) => !!model && uuidSet.has(model.toLowerCase());
14
+ return prisma.$extends({
15
+ name: 'rhino-uuid',
16
+ query: {
17
+ $allModels: {
18
+ async create({ model, args, query }) {
19
+ if (needsUuid(model) && args?.data && args.data.id == null) {
20
+ args = { ...args, data: { ...args.data, id: (0, crypto_1.randomUUID)() } };
21
+ }
22
+ return query(args);
23
+ },
24
+ },
25
+ },
26
+ });
27
+ }
28
+ //# sourceMappingURL=prisma-uuid.extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-uuid.extension.js","sourceRoot":"","sources":["../../src/prisma/prisma-uuid.extension.ts"],"names":[],"mappings":";;AAQA,4BAiBC;AAzBD,mCAAoC;AAEpC;;;;;GAKG;AACH,SAAgB,QAAQ,CAAmC,MAAS,EAAE,UAAoB;IACxF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAChE,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAElF,OAAQ,MAAc,CAAC,QAAQ,CAAC;QAC9B,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE;YACL,UAAU,EAAE;gBACV,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAO;oBACtC,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;wBAC3D,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAA,mBAAU,GAAE,EAAE,EAAE,CAAC;oBAC/D,CAAC;oBACD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;gBACrB,CAAC;aACF;SACF;KACF,CAAM,CAAC;AACV,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
2
+ /**
3
+ * Minimal PrismaClient surface Rhino relies on. Declared structurally so
4
+ * the library does not take a hard dep on `@prisma/client` (peer dep only).
5
+ */
6
+ export interface PrismaClientLike {
7
+ $connect?: () => Promise<void>;
8
+ $disconnect?: () => Promise<void>;
9
+ $transaction?: <T>(fn: (tx: any) => Promise<T>) => Promise<T>;
10
+ [model: string]: any;
11
+ }
12
+ /**
13
+ * Wraps the consuming app's PrismaClient. The client is provided to
14
+ * `RhinoModule.forRoot({ prismaClient })` and injected via DI — no
15
+ * post-construction `setClient()` dance required.
16
+ *
17
+ * For type-safe access, declare a subclass typed over your generated client:
18
+ *
19
+ * class AppPrisma extends PrismaService<PrismaClient> {}
20
+ *
21
+ * and inject `AppPrisma` instead of `PrismaService`.
22
+ */
23
+ export declare class PrismaService<TClient extends PrismaClientLike = PrismaClientLike> implements OnModuleInit, OnModuleDestroy {
24
+ private readonly logger;
25
+ private _client;
26
+ constructor(client?: TClient);
27
+ onModuleInit(): Promise<void>;
28
+ onModuleDestroy(): Promise<void>;
29
+ /** Escape hatch for tests. Not intended for production code. */
30
+ setClient(client: TClient): void;
31
+ get client(): TClient;
32
+ /**
33
+ * Resolve a Prisma delegate by model name, trying original / camelCase / lowercase.
34
+ * Returns `any` at the library level; subclass with generics for type inference.
35
+ */
36
+ model(name: string): any;
37
+ $transaction<T>(fn: (tx: any) => Promise<T>): Promise<T>;
38
+ }
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var PrismaService_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.PrismaService = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const tokens_1 = require("../constants/tokens");
19
+ /**
20
+ * Wraps the consuming app's PrismaClient. The client is provided to
21
+ * `RhinoModule.forRoot({ prismaClient })` and injected via DI — no
22
+ * post-construction `setClient()` dance required.
23
+ *
24
+ * For type-safe access, declare a subclass typed over your generated client:
25
+ *
26
+ * class AppPrisma extends PrismaService<PrismaClient> {}
27
+ *
28
+ * and inject `AppPrisma` instead of `PrismaService`.
29
+ */
30
+ let PrismaService = PrismaService_1 = class PrismaService {
31
+ logger = new common_1.Logger(PrismaService_1.name);
32
+ _client;
33
+ constructor(client) {
34
+ this._client = client;
35
+ }
36
+ async onModuleInit() {
37
+ if (this._client?.$connect) {
38
+ try {
39
+ await this._client.$connect();
40
+ }
41
+ catch (err) {
42
+ this.logger.warn(`Prisma $connect failed: ${err.message}`);
43
+ }
44
+ }
45
+ }
46
+ async onModuleDestroy() {
47
+ if (this._client?.$disconnect) {
48
+ try {
49
+ await this._client.$disconnect();
50
+ }
51
+ catch (err) {
52
+ this.logger.warn(`Prisma $disconnect failed: ${err.message}`);
53
+ }
54
+ }
55
+ }
56
+ /** Escape hatch for tests. Not intended for production code. */
57
+ setClient(client) {
58
+ this._client = client;
59
+ }
60
+ get client() {
61
+ if (!this._client) {
62
+ throw new Error('PrismaService: no Prisma client configured. ' +
63
+ 'Pass it via RhinoModule.forRoot({ prismaClient: new PrismaClient() }) ' +
64
+ 'or RhinoModule.forRootAsync({ useFactory: () => ({ prismaClient, ... }) }).');
65
+ }
66
+ return this._client;
67
+ }
68
+ /**
69
+ * Resolve a Prisma delegate by model name, trying original / camelCase / lowercase.
70
+ * Returns `any` at the library level; subclass with generics for type inference.
71
+ */
72
+ model(name) {
73
+ const client = this.client;
74
+ const candidates = [
75
+ name,
76
+ name.charAt(0).toLowerCase() + name.slice(1),
77
+ name.toLowerCase(),
78
+ ];
79
+ for (const c of candidates) {
80
+ const d = client[c];
81
+ if (d && typeof d === 'object')
82
+ return d;
83
+ }
84
+ throw new Error(`PrismaService: unknown model "${name}"`);
85
+ }
86
+ $transaction(fn) {
87
+ const tx = this.client.$transaction;
88
+ if (!tx)
89
+ throw new Error('PrismaService: configured client does not support $transaction');
90
+ return tx(fn);
91
+ }
92
+ };
93
+ exports.PrismaService = PrismaService;
94
+ exports.PrismaService = PrismaService = PrismaService_1 = __decorate([
95
+ (0, common_1.Injectable)(),
96
+ __param(0, (0, common_1.Optional)()),
97
+ __param(0, (0, common_1.Inject)(tokens_1.RHINO_PRISMA_CLIENT)),
98
+ __metadata("design:paramtypes", [Object])
99
+ ], PrismaService);
100
+ //# sourceMappingURL=prisma.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.service.js","sourceRoot":"","sources":["../../src/prisma/prisma.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAOwB;AACxB,gDAA0D;AAa1D;;;;;;;;;;GAUG;AAEI,IAAM,aAAa,qBAAnB,MAAM,aAAa;IAGP,MAAM,GAAG,IAAI,eAAM,CAAC,eAAa,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,CAAsB;IAErC,YAAqD,MAAgB;QACnE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAChC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA4B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACnC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA+B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,SAAS,CAAC,MAAe;QACvB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,IAAI,MAAM;QACR,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,8CAA8C;gBAC5C,wEAAwE;gBACxE,6EAA6E,CAChF,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAY;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAa,CAAC;QAClC,MAAM,UAAU,GAAG;YACjB,IAAI;YACJ,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5C,IAAI,CAAC,WAAW,EAAE;SACnB,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,YAAY,CAAI,EAA2B;QACzC,MAAM,EAAE,GAAI,IAAI,CAAC,MAAc,CAAC,YAAY,CAAC;QAC7C,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QAC3F,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;CACF,CAAA;AArEY,sCAAa;wBAAb,aAAa;IADzB,IAAA,mBAAU,GAAE;IAOE,WAAA,IAAA,iBAAQ,GAAE,CAAA;IAAE,WAAA,IAAA,eAAM,EAAC,4BAAmB,CAAC,CAAA;;GANzC,aAAa,CAqEzB"}
@@ -0,0 +1,43 @@
1
+ import type { RhinoConfig, ModelRegistration, RouteGroupConfig } from './interfaces/rhino-config.interface';
2
+ /**
3
+ * Injectable accessor for the consuming app's Rhino configuration.
4
+ * Wraps the raw config object with convenience lookup methods.
5
+ */
6
+ export declare class RhinoConfigService {
7
+ private readonly config;
8
+ constructor(config: RhinoConfig);
9
+ raw(): RhinoConfig;
10
+ models(): Record<string, ModelRegistration>;
11
+ model(slug: string): ModelRegistration | undefined;
12
+ hasModel(slug: string): boolean;
13
+ routeGroups(): Record<string, RouteGroupConfig>;
14
+ routeGroup(name: string): RouteGroupConfig | undefined;
15
+ /**
16
+ * Get all model slugs registered inside a route group.
17
+ * `'*'` expands to every registered model.
18
+ */
19
+ modelsInRouteGroup(name: string): string[];
20
+ multiTenantEnabled(): boolean;
21
+ organizationIdentifierColumn(): string;
22
+ nestedConfig(): {
23
+ path: string;
24
+ maxOperations: number;
25
+ allowedModels: string[];
26
+ };
27
+ invitationsConfig(): {
28
+ expiresDays: number;
29
+ allowedRoles: string[];
30
+ notificationHandler: (invitation: any) => Promise<void> | void;
31
+ };
32
+ authConfig(): {
33
+ jwtSecret: string;
34
+ jwtExpiresIn: string;
35
+ userModel: string;
36
+ emailField: string;
37
+ passwordField: string;
38
+ };
39
+ }
40
+ /**
41
+ * Normalize a raw config value (defaults applied) — used by the module in forRoot.
42
+ */
43
+ export declare function normalizeConfig(config: RhinoConfig): RhinoConfig;
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.RhinoConfigService = void 0;
16
+ exports.normalizeConfig = normalizeConfig;
17
+ const common_1 = require("@nestjs/common");
18
+ const tokens_1 = require("./constants/tokens");
19
+ /**
20
+ * Injectable accessor for the consuming app's Rhino configuration.
21
+ * Wraps the raw config object with convenience lookup methods.
22
+ */
23
+ let RhinoConfigService = class RhinoConfigService {
24
+ config;
25
+ constructor(config) {
26
+ this.config = config;
27
+ }
28
+ raw() {
29
+ return this.config;
30
+ }
31
+ models() {
32
+ return this.config.models ?? {};
33
+ }
34
+ model(slug) {
35
+ return this.config.models?.[slug];
36
+ }
37
+ hasModel(slug) {
38
+ return Boolean(this.config.models?.[slug]);
39
+ }
40
+ routeGroups() {
41
+ return this.config.routeGroups ?? {};
42
+ }
43
+ routeGroup(name) {
44
+ return this.config.routeGroups?.[name];
45
+ }
46
+ /**
47
+ * Get all model slugs registered inside a route group.
48
+ * `'*'` expands to every registered model.
49
+ */
50
+ modelsInRouteGroup(name) {
51
+ const group = this.routeGroup(name);
52
+ if (!group)
53
+ return [];
54
+ if (group.models === '*')
55
+ return Object.keys(this.models());
56
+ return group.models;
57
+ }
58
+ multiTenantEnabled() {
59
+ const mt = this.config.multiTenant;
60
+ if (!mt)
61
+ return false;
62
+ if (mt.enabled === false)
63
+ return false;
64
+ return Boolean(mt.organizationIdentifierColumn) || mt.enabled === true;
65
+ }
66
+ organizationIdentifierColumn() {
67
+ return this.config.multiTenant?.organizationIdentifierColumn ?? 'id';
68
+ }
69
+ nestedConfig() {
70
+ return {
71
+ path: this.config.nested?.path ?? 'nested',
72
+ maxOperations: this.config.nested?.maxOperations ?? 50,
73
+ allowedModels: this.config.nested?.allowedModels ?? null,
74
+ };
75
+ }
76
+ invitationsConfig() {
77
+ return {
78
+ expiresDays: this.config.invitations?.expiresDays ?? 7,
79
+ allowedRoles: this.config.invitations?.allowedRoles ?? null,
80
+ notificationHandler: this.config.invitations?.notificationHandler,
81
+ };
82
+ }
83
+ authConfig() {
84
+ return {
85
+ jwtSecret: this.config.auth?.jwtSecret ??
86
+ process.env.JWT_SECRET ??
87
+ 'change-me-in-production',
88
+ jwtExpiresIn: this.config.auth?.jwtExpiresIn ?? '7d',
89
+ userModel: this.config.auth?.userModel ?? 'user',
90
+ emailField: this.config.auth?.emailField ?? 'email',
91
+ passwordField: this.config.auth?.passwordField ?? 'password',
92
+ };
93
+ }
94
+ };
95
+ exports.RhinoConfigService = RhinoConfigService;
96
+ exports.RhinoConfigService = RhinoConfigService = __decorate([
97
+ (0, common_1.Injectable)(),
98
+ __param(0, (0, common_1.Inject)(tokens_1.RHINO_CONFIG)),
99
+ __metadata("design:paramtypes", [Object])
100
+ ], RhinoConfigService);
101
+ /**
102
+ * Normalize a raw config value (defaults applied) — used by the module in forRoot.
103
+ */
104
+ function normalizeConfig(config) {
105
+ return {
106
+ ...config,
107
+ models: config.models ?? {},
108
+ routeGroups: config.routeGroups ?? {},
109
+ multiTenant: config.multiTenant ?? { enabled: false },
110
+ nested: {
111
+ path: 'nested',
112
+ maxOperations: 50,
113
+ allowedModels: null,
114
+ ...(config.nested ?? {}),
115
+ },
116
+ invitations: {
117
+ expiresDays: 7,
118
+ allowedRoles: null,
119
+ ...(config.invitations ?? {}),
120
+ },
121
+ auth: {
122
+ jwtExpiresIn: '7d',
123
+ userModel: 'user',
124
+ emailField: 'email',
125
+ passwordField: 'password',
126
+ ...(config.auth ?? {}),
127
+ },
128
+ };
129
+ }
130
+ //# sourceMappingURL=rhino.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rhino.config.js","sourceRoot":"","sources":["../src/rhino.config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { DynamicModule, MiddlewareConsumer, NestModule } from '@nestjs/common';
2
+ import type { RhinoConfig, RhinoModuleAsyncOptions } from './interfaces/rhino-config.interface';
3
+ export interface RhinoModuleOptions {
4
+ /** Register the library's controllers automatically. Default true. */
5
+ registerControllers?: boolean;
6
+ /** Install JwtAuthGuard globally as APP_GUARD. Default false (opt-in). */
7
+ autoAuthGuard?: boolean;
8
+ /** Install ResourcePolicyGuard globally as APP_GUARD. Default false (opt-in). */
9
+ autoPolicyGuard?: boolean;
10
+ /** Install RouteGroupMiddleware globally. Default true. */
11
+ autoRouteGroupMiddleware?: boolean;
12
+ /** Wire per-model `middleware` / `actionMiddleware` via NestModule.configure. Default true. */
13
+ autoModelMiddleware?: boolean;
14
+ /** Wire ResolveOrganizationMiddleware for all routes when multiTenant enabled. Default true. */
15
+ autoTenantMiddleware?: boolean;
16
+ }
17
+ /**
18
+ * Rhino NestJS dynamic module.
19
+ *
20
+ * Example (synchronous):
21
+ *
22
+ * RhinoModule.forRoot({
23
+ * prismaClient: new PrismaClient(),
24
+ * models: {
25
+ * posts: { model: 'post', policy: PostPolicy, belongsToOrganization: true },
26
+ * },
27
+ * });
28
+ *
29
+ * Example (async — reading from a ConfigService):
30
+ *
31
+ * RhinoModule.forRootAsync({
32
+ * imports: [ConfigModule],
33
+ * inject: [ConfigService, PrismaService],
34
+ * middleware: [MyRateLimitMw], // <-- list middleware classes here
35
+ * useFactory: (cfg, prisma) => ({
36
+ * prismaClient: prisma,
37
+ * models: { ... },
38
+ * }),
39
+ * });
40
+ */
41
+ export declare class RhinoModule implements NestModule {
42
+ private readonly config;
43
+ private readonly options;
44
+ constructor(config: RhinoConfig, options: RhinoModuleOptions);
45
+ configure(consumer: MiddlewareConsumer): void;
46
+ /**
47
+ * Synchronous registration. All middleware classes are collected from the
48
+ * passed config at build time, so no extra `middleware` option is needed.
49
+ */
50
+ static forRoot(config: RhinoConfig, options?: RhinoModuleOptions): DynamicModule;
51
+ /**
52
+ * Asynchronous registration. Middleware classes referenced by models must
53
+ * be declared via `options.middleware` because NestJS providers cannot be
54
+ * resolved from an async useFactory.
55
+ */
56
+ static forRootAsync(options: RhinoModuleAsyncOptions & RhinoModuleOptions): DynamicModule;
57
+ private static build;
58
+ private static collectModelMiddleware;
59
+ private static coreProviders;
60
+ private static coreExports;
61
+ }