@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,6 @@
1
+ import { type ReadlineInterface } from '../utils/prompt';
2
+ export interface GenerateDeps {
3
+ rl?: ReadlineInterface;
4
+ cwd?: string;
5
+ }
6
+ export declare function runGenerate(deps?: GenerateDeps): Promise<void>;
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runGenerate = runGenerate;
37
+ /**
38
+ * rhino generate
39
+ *
40
+ * Interactive wizard that asks:
41
+ * - What to create: model | policy | scope
42
+ * - Name (PascalCase)
43
+ * - Columns (for model only)
44
+ *
45
+ * Writes a stub file under the right directory.
46
+ */
47
+ const path = __importStar(require("path"));
48
+ const prompt_1 = require("../utils/prompt");
49
+ const io_1 = require("../utils/io");
50
+ async function runGenerate(deps = {}) {
51
+ const cwd = deps.cwd ?? process.cwd();
52
+ const rl = deps.rl ?? (0, prompt_1.createInterface)();
53
+ console.log('\n Rhino :: Generate\n');
54
+ const kind = await (0, prompt_1.selectFromList)(rl, 'What would you like to generate?', ['model', 'policy', 'scope'], 0);
55
+ const rawName = await (0, prompt_1.ask)(rl, ` Name (PascalCase, e.g. "BlogPost"): `);
56
+ const name = toPascalCase(rawName);
57
+ if (!name) {
58
+ console.error(' Error: name is required.');
59
+ rl.close();
60
+ process.exit(1);
61
+ }
62
+ switch (kind) {
63
+ case 'model':
64
+ await generateModel(rl, cwd, name);
65
+ break;
66
+ case 'policy':
67
+ generatePolicy(cwd, name);
68
+ break;
69
+ case 'scope':
70
+ generateScope(cwd, name);
71
+ break;
72
+ default:
73
+ console.error(` Unknown type: ${kind}`);
74
+ rl.close();
75
+ process.exit(1);
76
+ }
77
+ rl.close();
78
+ }
79
+ // -----------------------------------------------------------------------
80
+ // Model
81
+ // -----------------------------------------------------------------------
82
+ async function generateModel(rl, cwd, name) {
83
+ const columnsRaw = await (0, prompt_1.ask)(rl, ' Columns (comma-separated, e.g. "title:string, body:text, published:boolean") []: ');
84
+ const columns = parseColumns(columnsRaw);
85
+ const destPath = path.join(cwd, 'src', 'models', `${name}.model.ts`);
86
+ if ((0, io_1.fileExists)(destPath)) {
87
+ console.log(` Skipped: ${destPath} already exists.`);
88
+ return;
89
+ }
90
+ const content = renderModelStub(name, columns);
91
+ (0, io_1.writeFileSafely)(destPath, content);
92
+ console.log(` Created: ${destPath}`);
93
+ }
94
+ function parseColumns(raw) {
95
+ if (!raw.trim())
96
+ return [];
97
+ return raw
98
+ .split(',')
99
+ .map((col) => col.trim())
100
+ .filter(Boolean)
101
+ .map((col) => {
102
+ const [name, type = 'string'] = col.split(':').map((s) => s.trim());
103
+ return { name: toCamelCase(name), type };
104
+ });
105
+ }
106
+ function renderModelStub(name, columns) {
107
+ const fieldLines = columns
108
+ .map((c) => ` ${c.name}?: ${mapTsType(c.type)};`)
109
+ .join('\n');
110
+ return `/**
111
+ * ${name} model stub — generated by \`npx rhino generate\`
112
+ * Register in rhino.setup.ts:
113
+ * ${toCamelCase(name)}s: { model: '${name}' }
114
+ */
115
+ import { RhinoModel } from '@rhino-dev/rhino-nestjs';
116
+
117
+ @RhinoModel()
118
+ export class ${name} {
119
+ id!: number;
120
+ ${fieldLines ? fieldLines + '\n' : ''} createdAt?: Date;
121
+ updatedAt?: Date;
122
+ }
123
+ `;
124
+ }
125
+ // -----------------------------------------------------------------------
126
+ // Policy
127
+ // -----------------------------------------------------------------------
128
+ function generatePolicy(cwd, name) {
129
+ const destPath = path.join(cwd, 'src', 'policies', `${name}.policy.ts`);
130
+ if ((0, io_1.fileExists)(destPath)) {
131
+ console.log(` Skipped: ${destPath} already exists.`);
132
+ return;
133
+ }
134
+ const content = renderPolicyStub(name);
135
+ (0, io_1.writeFileSafely)(destPath, content);
136
+ console.log(` Created: ${destPath}`);
137
+ }
138
+ function renderPolicyStub(name) {
139
+ return `/**
140
+ * ${name} policy stub — generated by \`npx rhino generate\`
141
+ * Extend ResourcePolicy and override the methods you need.
142
+ */
143
+ import { ResourcePolicy } from '@rhino-dev/rhino-nestjs';
144
+
145
+ export class ${name}Policy extends ResourcePolicy {
146
+ // override index(user: any): boolean { ... }
147
+ // override show(user: any, record: any): boolean { ... }
148
+ // override store(user: any): boolean { ... }
149
+ // override update(user: any, record: any): boolean { ... }
150
+ // override destroy(user: any, record: any): boolean { ... }
151
+ }
152
+ `;
153
+ }
154
+ // -----------------------------------------------------------------------
155
+ // Scope
156
+ // -----------------------------------------------------------------------
157
+ function generateScope(cwd, name) {
158
+ const destPath = path.join(cwd, 'src', 'scopes', `${name}.scope.ts`);
159
+ if ((0, io_1.fileExists)(destPath)) {
160
+ console.log(` Skipped: ${destPath} already exists.`);
161
+ return;
162
+ }
163
+ const content = renderScopeStub(name);
164
+ (0, io_1.writeFileSafely)(destPath, content);
165
+ console.log(` Created: ${destPath}`);
166
+ }
167
+ function renderScopeStub(name) {
168
+ return `/**
169
+ * ${name} scope stub — generated by \`npx rhino generate\`
170
+ * Implement the \`apply\` method to filter / order the default query.
171
+ */
172
+ import type { RhinoScope } from '@rhino-dev/rhino-nestjs';
173
+
174
+ export class ${name}Scope implements RhinoScope {
175
+ apply(query: Record<string, any>, _context: any): Record<string, any> {
176
+ // Example: return { ...query, where: { ...query.where, deletedAt: null } };
177
+ return query;
178
+ }
179
+ }
180
+ `;
181
+ }
182
+ // -----------------------------------------------------------------------
183
+ // String helpers
184
+ // -----------------------------------------------------------------------
185
+ function toPascalCase(str) {
186
+ if (!str)
187
+ return '';
188
+ return str
189
+ .replace(/[-_\s]+(.)/g, (_, c) => c.toUpperCase())
190
+ .replace(/^(.)/, (c) => c.toUpperCase());
191
+ }
192
+ function toCamelCase(str) {
193
+ const pascal = toPascalCase(str);
194
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
195
+ }
196
+ function mapTsType(prismaType) {
197
+ const map = {
198
+ string: 'string',
199
+ text: 'string',
200
+ int: 'number',
201
+ integer: 'number',
202
+ float: 'number',
203
+ decimal: 'number',
204
+ boolean: 'boolean',
205
+ bool: 'boolean',
206
+ date: 'Date',
207
+ datetime: 'Date',
208
+ json: 'Record<string, unknown>',
209
+ };
210
+ return map[prismaType.toLowerCase()] ?? 'string';
211
+ }
212
+ //# sourceMappingURL=generate.command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.command.js","sourceRoot":"","sources":["../../../src/cli/commands/generate.command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type ReadlineInterface } from '../utils/prompt';
2
+ export interface InstallDeps {
3
+ rl?: ReadlineInterface;
4
+ cwd?: string;
5
+ /** Override skill source dir (for tests). */
6
+ skillsSourceDir?: string;
7
+ }
8
+ export declare function runInstall(deps?: InstallDeps): Promise<void>;
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runInstall = runInstall;
37
+ /**
38
+ * rhino install
39
+ *
40
+ * Interactive setup wizard. Prompts the user to:
41
+ * (a) configure a model-registration stub file
42
+ * (b) enable multi-tenant mode
43
+ * (c) set the org identifier column
44
+ * (d) scaffold an audit-trail Prisma model
45
+ * (e) install .claude/commands/ AI skill files from stubs/skills
46
+ *
47
+ * Writes a stub config to src/rhino.setup.ts.
48
+ * Appends an AuditLog Prisma model snippet to prisma/schema.prisma.
49
+ */
50
+ const path = __importStar(require("path"));
51
+ const fs = __importStar(require("fs"));
52
+ const prompt_1 = require("../utils/prompt");
53
+ const io_1 = require("../utils/io");
54
+ const AUDIT_LOG_SNIPPET = `
55
+ model AuditLog {
56
+ id Int @id @default(autoincrement())
57
+ userId Int?
58
+ action String // create | update | delete
59
+ modelName String
60
+ modelId String
61
+ oldValues Json?
62
+ newValues Json?
63
+ ipAddress String?
64
+ createdAt DateTime @default(now())
65
+ }
66
+ `;
67
+ async function runInstall(deps = {}) {
68
+ const cwd = deps.cwd ?? process.cwd();
69
+ const rl = deps.rl ?? (0, prompt_1.createInterface)();
70
+ console.log('\n Rhino :: Install :: Let\'s build something great\n');
71
+ // ---------------------------------------------------------------
72
+ // (a) Model registration stub
73
+ // ---------------------------------------------------------------
74
+ const wantStub = await (0, prompt_1.confirm)(rl, 'Create a model-registration stub file (src/rhino.setup.ts)?', true);
75
+ if (wantStub) {
76
+ const stubPath = path.join(cwd, 'src', 'rhino.setup.ts');
77
+ if ((0, io_1.fileExists)(stubPath)) {
78
+ console.log(` Skipped: ${stubPath} already exists.`);
79
+ }
80
+ else {
81
+ const stubContent = generateSetupStub(false, 'id');
82
+ (0, io_1.writeFileSafely)(stubPath, stubContent);
83
+ console.log(` Created: ${stubPath}`);
84
+ }
85
+ }
86
+ // ---------------------------------------------------------------
87
+ // (b) Multi-tenant
88
+ // ---------------------------------------------------------------
89
+ const wantMultiTenant = await (0, prompt_1.confirm)(rl, 'Enable multi-tenant support (Organizations, Roles)?', false);
90
+ let orgIdentifierColumn = 'id';
91
+ if (wantMultiTenant) {
92
+ const col = await (0, prompt_1.ask)(rl, ' Which column identifies organizations? (id / slug / uuid) [id]: ');
93
+ orgIdentifierColumn = col || 'id';
94
+ // Re-write the setup stub if it was already written
95
+ const stubPath = path.join(cwd, 'src', 'rhino.setup.ts');
96
+ if ((0, io_1.fileExists)(stubPath)) {
97
+ const newContent = generateSetupStub(true, orgIdentifierColumn);
98
+ (0, io_1.writeFileSafely)(stubPath, newContent);
99
+ console.log(` Updated: ${stubPath} (multi-tenant enabled)`);
100
+ }
101
+ }
102
+ // ---------------------------------------------------------------
103
+ // (d) Audit trail
104
+ // ---------------------------------------------------------------
105
+ const wantAudit = await (0, prompt_1.confirm)(rl, 'Scaffold an AuditLog model in prisma/schema.prisma?', false);
106
+ if (wantAudit) {
107
+ const schemaPath = path.join(cwd, 'prisma', 'schema.prisma');
108
+ if ((0, io_1.fileExists)(schemaPath)) {
109
+ const existing = fs.readFileSync(schemaPath, 'utf8');
110
+ if (existing.includes('AuditLog')) {
111
+ console.log(' Skipped: AuditLog already present in prisma/schema.prisma.');
112
+ }
113
+ else {
114
+ fs.appendFileSync(schemaPath, `\n${AUDIT_LOG_SNIPPET}`, 'utf8');
115
+ console.log(` Appended AuditLog model to: ${schemaPath}`);
116
+ }
117
+ }
118
+ else {
119
+ console.log(' Could not find prisma/schema.prisma — please add the following snippet manually:');
120
+ console.log(AUDIT_LOG_SNIPPET);
121
+ }
122
+ }
123
+ // ---------------------------------------------------------------
124
+ // (e) AI skill files
125
+ // ---------------------------------------------------------------
126
+ const wantSkills = await (0, prompt_1.confirm)(rl, 'Install Rhino AI skills for Claude Code (.claude/commands/)?', true);
127
+ if (wantSkills) {
128
+ await installSkills(cwd, deps.skillsSourceDir);
129
+ }
130
+ rl.close();
131
+ console.log('\n Rhino installed successfully!\n');
132
+ console.log(' Next steps:');
133
+ console.log(' 1. Review src/rhino.setup.ts');
134
+ console.log(' 2. Add your blueprints to .rhino/blueprints/');
135
+ console.log(' 3. Run: npx rhino blueprint\n');
136
+ }
137
+ // -----------------------------------------------------------------------
138
+ // Helpers
139
+ // -----------------------------------------------------------------------
140
+ function generateSetupStub(multiTenant, orgIdentifierColumn) {
141
+ return `/**
142
+ * Rhino setup — generated by \`npx rhino install\`
143
+ * Adjust this file to match your application's model configuration.
144
+ */
145
+ import { RhinoModule } from '@rhino-dev/rhino-nestjs';
146
+ // import { PrismaService } from './prisma/prisma.service';
147
+
148
+ export const rhinoConfig = {
149
+ models: {
150
+ // Register your models here, e.g.:
151
+ // users: { model: 'User', policy: UserPolicy },
152
+ },
153
+ routeGroups: {
154
+ default: {
155
+ prefix: '',
156
+ models: '*' as const,
157
+ },
158
+ },
159
+ multiTenant: {
160
+ enabled: ${multiTenant},
161
+ organizationIdentifierColumn: '${orgIdentifierColumn}',
162
+ },
163
+ auth: {
164
+ jwtSecret: process.env.JWT_SECRET ?? 'change-me',
165
+ jwtExpiresIn: '7d',
166
+ userModel: 'user',
167
+ emailField: 'email',
168
+ passwordField: 'password',
169
+ },
170
+ };
171
+
172
+ // Add to your AppModule imports:
173
+ // RhinoModule.forRoot(rhinoConfig)
174
+ `;
175
+ }
176
+ async function installSkills(cwd, overrideSource) {
177
+ // The skills dir is shipped alongside the package under stubs/skills.
178
+ // Resolve relative to this file so it works from both source and dist.
179
+ const skillsSourceDir = overrideSource ??
180
+ path.resolve(__dirname, '..', '..', '..', 'stubs', 'skills');
181
+ const destDir = path.join(cwd, '.claude', 'commands');
182
+ fs.mkdirSync(destDir, { recursive: true });
183
+ if (!(0, io_1.fileExists)(skillsSourceDir)) {
184
+ console.log(' No skill files found (stubs/skills directory missing). Skipping.');
185
+ return;
186
+ }
187
+ const files = fs
188
+ .readdirSync(skillsSourceDir)
189
+ .filter((f) => f.startsWith('rhino-') && f.endsWith('.md'));
190
+ if (files.length === 0) {
191
+ console.log(' No rhino-*.md skill files found. Skipping.');
192
+ return;
193
+ }
194
+ let installed = 0;
195
+ for (const file of files) {
196
+ const src = path.join(skillsSourceDir, file);
197
+ const dest = path.join(destDir, file);
198
+ fs.copyFileSync(src, dest);
199
+ console.log(` Installed: .claude/commands/${file}`);
200
+ installed++;
201
+ }
202
+ console.log(`\n ${installed} Rhino skills installed to .claude/commands/`);
203
+ console.log(' Run any skill in Claude Code: /rhino-feature, /rhino-review, etc.');
204
+ }
205
+ //# sourceMappingURL=install.command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.command.js","sourceRoot":"","sources":["../../../src/cli/commands/install.command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Rhino CLI entry point.
4
+ *
5
+ * Usage:
6
+ * npx rhino install
7
+ * npx rhino generate
8
+ * npx rhino blueprint [--force] [--dry-run] [--model=slug]
9
+ * npx rhino export-postman [--output=file.json] [--base-url=http://localhost:3000/api]
10
+ * npx rhino export-types [--output=path/to/types.d.ts]
11
+ */
12
+ /** Extract --key=value or presence of --flag from argv. */
13
+ export declare function parseFlags(argv: string[]): Record<string, string | true>;
14
+ /** Return the first positional arg (not starting with --) after index `from`. */
15
+ export declare function extractCommand(argv: string[]): string | undefined;
16
+ export declare function printHelp(): void;
17
+ export declare function main(argv?: string[]): Promise<void>;
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * Rhino CLI entry point.
5
+ *
6
+ * Usage:
7
+ * npx rhino install
8
+ * npx rhino generate
9
+ * npx rhino blueprint [--force] [--dry-run] [--model=slug]
10
+ * npx rhino export-postman [--output=file.json] [--base-url=http://localhost:3000/api]
11
+ * npx rhino export-types [--output=path/to/types.d.ts]
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.parseFlags = parseFlags;
15
+ exports.extractCommand = extractCommand;
16
+ exports.printHelp = printHelp;
17
+ exports.main = main;
18
+ const install_command_1 = require("./commands/install.command");
19
+ const generate_command_1 = require("./commands/generate.command");
20
+ const blueprint_command_1 = require("./commands/blueprint.command");
21
+ const export_postman_command_1 = require("./commands/export-postman.command");
22
+ const export_types_command_1 = require("./commands/export-types.command");
23
+ // -----------------------------------------------------------------------
24
+ // Flag parsing helpers
25
+ // -----------------------------------------------------------------------
26
+ /** Extract --key=value or presence of --flag from argv. */
27
+ function parseFlags(argv) {
28
+ const flags = {};
29
+ for (const arg of argv) {
30
+ if (!arg.startsWith('--'))
31
+ continue;
32
+ const withoutDashes = arg.slice(2);
33
+ const eqIdx = withoutDashes.indexOf('=');
34
+ if (eqIdx === -1) {
35
+ flags[withoutDashes] = true;
36
+ }
37
+ else {
38
+ flags[withoutDashes.slice(0, eqIdx)] = withoutDashes.slice(eqIdx + 1);
39
+ }
40
+ }
41
+ return flags;
42
+ }
43
+ /** Return the first positional arg (not starting with --) after index `from`. */
44
+ function extractCommand(argv) {
45
+ return argv.find((a) => !a.startsWith('--') && !a.startsWith('-'));
46
+ }
47
+ // -----------------------------------------------------------------------
48
+ // Help
49
+ // -----------------------------------------------------------------------
50
+ function printHelp() {
51
+ console.log(`
52
+ rhino <command> [options]
53
+
54
+ Commands:
55
+ install Interactive setup wizard
56
+ generate Generate a model, policy, or scope stub
57
+ blueprint Generate code from YAML blueprints
58
+ export-postman Export a Postman collection
59
+ export-types Export TypeScript type definitions
60
+
61
+ Options (by command):
62
+ blueprint
63
+ --force Re-generate even if unchanged
64
+ --dry-run Preview without writing files
65
+ --model=<slug> Process a single blueprint by slug
66
+
67
+ export-postman
68
+ --output=<file> Output path (default: postman_collection.json)
69
+ --base-url=<url> Base URL (default: http://localhost:3000/api)
70
+
71
+ export-types
72
+ --output=<file> Output path (default: src/types/rhino.d.ts)
73
+ `);
74
+ }
75
+ // -----------------------------------------------------------------------
76
+ // Main dispatcher
77
+ // -----------------------------------------------------------------------
78
+ async function main(argv = process.argv.slice(2)) {
79
+ const command = extractCommand(argv);
80
+ const flags = parseFlags(argv);
81
+ switch (command) {
82
+ case 'install':
83
+ await (0, install_command_1.runInstall)();
84
+ break;
85
+ case 'generate':
86
+ await (0, generate_command_1.runGenerate)();
87
+ break;
88
+ case 'blueprint':
89
+ await (0, blueprint_command_1.runBlueprint)({
90
+ force: flags['force'] === true,
91
+ dryRun: flags['dry-run'] === true,
92
+ model: typeof flags['model'] === 'string' ? flags['model'] : undefined,
93
+ });
94
+ break;
95
+ case 'export-postman':
96
+ await (0, export_postman_command_1.runExportPostman)({
97
+ output: typeof flags['output'] === 'string' ? flags['output'] : undefined,
98
+ baseUrl: typeof flags['base-url'] === 'string' ? flags['base-url'] : undefined,
99
+ });
100
+ break;
101
+ case 'export-types':
102
+ await (0, export_types_command_1.runExportTypes)({
103
+ output: typeof flags['output'] === 'string' ? flags['output'] : undefined,
104
+ });
105
+ break;
106
+ default:
107
+ printHelp();
108
+ if (command !== undefined) {
109
+ // Unknown command — exit with error
110
+ console.error(` Unknown command: ${command}\n`);
111
+ process.exit(1);
112
+ }
113
+ break;
114
+ }
115
+ }
116
+ // Run only when invoked directly (not when require()'d in tests).
117
+ if (require.main === module) {
118
+ main().catch((err) => {
119
+ console.error(err);
120
+ process.exit(1);
121
+ });
122
+ }
123
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /** Return true when a file (or directory) exists. */
2
+ export declare function fileExists(filePath: string): boolean;
3
+ /**
4
+ * Write content to a file, creating parent directories as needed.
5
+ * Writes to a tmp path first then renames for an atomic-ish write.
6
+ */
7
+ export declare function writeFileSafely(filePath: string, content: string): void;
8
+ /**
9
+ * Append `content` to `filePath` only when the exact string is not
10
+ * already present (prevents duplicate entries on re-runs).
11
+ */
12
+ export declare function appendIfMissing(filePath: string, content: string): void;