@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.
- package/LICENSE +21 -0
- package/README.md +427 -0
- package/dist/blueprint/blueprint-parser.d.ts +130 -0
- package/dist/blueprint/blueprint-parser.js +276 -0
- package/dist/blueprint/blueprint-parser.js.map +1 -0
- package/dist/blueprint/blueprint-runner.d.ts +51 -0
- package/dist/blueprint/blueprint-runner.js +238 -0
- package/dist/blueprint/blueprint-runner.js.map +1 -0
- package/dist/blueprint/blueprint-validator.d.ts +19 -0
- package/dist/blueprint/blueprint-validator.js +163 -0
- package/dist/blueprint/blueprint-validator.js.map +1 -0
- package/dist/blueprint/generators/policy-generator.d.ts +40 -0
- package/dist/blueprint/generators/policy-generator.js +157 -0
- package/dist/blueprint/generators/policy-generator.js.map +1 -0
- package/dist/blueprint/generators/prisma-schema-generator.d.ts +43 -0
- package/dist/blueprint/generators/prisma-schema-generator.js +197 -0
- package/dist/blueprint/generators/prisma-schema-generator.js.map +1 -0
- package/dist/blueprint/generators/resource-definition-generator.d.ts +52 -0
- package/dist/blueprint/generators/resource-definition-generator.js +229 -0
- package/dist/blueprint/generators/resource-definition-generator.js.map +1 -0
- package/dist/blueprint/generators/seeder-generator.d.ts +21 -0
- package/dist/blueprint/generators/seeder-generator.js +135 -0
- package/dist/blueprint/generators/seeder-generator.js.map +1 -0
- package/dist/blueprint/generators/test-generator.d.ts +28 -0
- package/dist/blueprint/generators/test-generator.js +275 -0
- package/dist/blueprint/generators/test-generator.js.map +1 -0
- package/dist/blueprint/manifest-manager.d.ts +58 -0
- package/dist/blueprint/manifest-manager.js +137 -0
- package/dist/blueprint/manifest-manager.js.map +1 -0
- package/dist/cli/commands/blueprint.command.d.ts +16 -0
- package/dist/cli/commands/blueprint.command.js +35 -0
- package/dist/cli/commands/blueprint.command.js.map +1 -0
- package/dist/cli/commands/export-postman.command.d.ts +5 -0
- package/dist/cli/commands/export-postman.command.js +39 -0
- package/dist/cli/commands/export-postman.command.js.map +1 -0
- package/dist/cli/commands/export-types.command.d.ts +4 -0
- package/dist/cli/commands/export-types.command.js +36 -0
- package/dist/cli/commands/export-types.command.js.map +1 -0
- package/dist/cli/commands/generate.command.d.ts +6 -0
- package/dist/cli/commands/generate.command.js +212 -0
- package/dist/cli/commands/generate.command.js.map +1 -0
- package/dist/cli/commands/install.command.d.ts +8 -0
- package/dist/cli/commands/install.command.js +205 -0
- package/dist/cli/commands/install.command.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.js +123 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/io.d.ts +12 -0
- package/dist/cli/utils/io.js +74 -0
- package/dist/cli/utils/io.js.map +1 -0
- package/dist/cli/utils/prompt.d.ts +12 -0
- package/dist/cli/utils/prompt.js +78 -0
- package/dist/cli/utils/prompt.js.map +1 -0
- package/dist/constants/tokens.d.ts +3 -0
- package/dist/constants/tokens.js +7 -0
- package/dist/constants/tokens.js.map +1 -0
- package/dist/controllers/auth.controller.d.ts +59 -0
- package/dist/controllers/auth.controller.js +121 -0
- package/dist/controllers/auth.controller.js.map +1 -0
- package/dist/controllers/global.controller.d.ts +44 -0
- package/dist/controllers/global.controller.js +357 -0
- package/dist/controllers/global.controller.js.map +1 -0
- package/dist/controllers/invitation.controller.d.ts +30 -0
- package/dist/controllers/invitation.controller.js +111 -0
- package/dist/controllers/invitation.controller.js.map +1 -0
- package/dist/controllers/nested.controller.d.ts +12 -0
- package/dist/controllers/nested.controller.js +69 -0
- package/dist/controllers/nested.controller.js.map +1 -0
- package/dist/decorators/index.d.ts +33 -0
- package/dist/decorators/index.js +79 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/errors/rhino-exception.d.ts +24 -0
- package/dist/errors/rhino-exception.js +47 -0
- package/dist/errors/rhino-exception.js.map +1 -0
- package/dist/exporters/postman-exporter.d.ts +21 -0
- package/dist/exporters/postman-exporter.js +396 -0
- package/dist/exporters/postman-exporter.js.map +1 -0
- package/dist/exporters/typescript-exporter.d.ts +23 -0
- package/dist/exporters/typescript-exporter.js +129 -0
- package/dist/exporters/typescript-exporter.js.map +1 -0
- package/dist/guards/jwt-auth.guard.d.ts +16 -0
- package/dist/guards/jwt-auth.guard.js +61 -0
- package/dist/guards/jwt-auth.guard.js.map +1 -0
- package/dist/guards/resource-policy.guard.d.ts +12 -0
- package/dist/guards/resource-policy.guard.js +111 -0
- package/dist/guards/resource-policy.guard.js.map +1 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +171 -0
- package/dist/index.js.map +1 -0
- package/dist/interceptors/hidden-columns.interceptor.d.ts +18 -0
- package/dist/interceptors/hidden-columns.interceptor.js +66 -0
- package/dist/interceptors/hidden-columns.interceptor.js.map +1 -0
- package/dist/interceptors/response.interceptor.d.ts +19 -0
- package/dist/interceptors/response.interceptor.js +47 -0
- package/dist/interceptors/response.interceptor.js.map +1 -0
- package/dist/interfaces/rhino-config.interface.d.ts +103 -0
- package/dist/interfaces/rhino-config.interface.js +3 -0
- package/dist/interfaces/rhino-config.interface.js.map +1 -0
- package/dist/interfaces/rhino-request.interface.d.ts +12 -0
- package/dist/interfaces/rhino-request.interface.js +3 -0
- package/dist/interfaces/rhino-request.interface.js.map +1 -0
- package/dist/middleware/resolve-organization.middleware.d.ts +15 -0
- package/dist/middleware/resolve-organization.middleware.js +38 -0
- package/dist/middleware/resolve-organization.middleware.js.map +1 -0
- package/dist/middleware/route-group.middleware.d.ts +17 -0
- package/dist/middleware/route-group.middleware.js +60 -0
- package/dist/middleware/route-group.middleware.js.map +1 -0
- package/dist/middleware/tenant-route-rewrite.d.ts +76 -0
- package/dist/middleware/tenant-route-rewrite.js +124 -0
- package/dist/middleware/tenant-route-rewrite.js.map +1 -0
- package/dist/policies/resource-policy.d.ts +25 -0
- package/dist/policies/resource-policy.js +77 -0
- package/dist/policies/resource-policy.js.map +1 -0
- package/dist/prisma/prisma-soft-delete.extension.d.ts +16 -0
- package/dist/prisma/prisma-soft-delete.extension.js +57 -0
- package/dist/prisma/prisma-soft-delete.extension.js.map +1 -0
- package/dist/prisma/prisma-uuid.extension.d.ts +9 -0
- package/dist/prisma/prisma-uuid.extension.js +28 -0
- package/dist/prisma/prisma-uuid.extension.js.map +1 -0
- package/dist/prisma/prisma.service.d.ts +38 -0
- package/dist/prisma/prisma.service.js +100 -0
- package/dist/prisma/prisma.service.js.map +1 -0
- package/dist/rhino.config.d.ts +43 -0
- package/dist/rhino.config.js +130 -0
- package/dist/rhino.config.js.map +1 -0
- package/dist/rhino.module.d.ts +61 -0
- package/dist/rhino.module.js +268 -0
- package/dist/rhino.module.js.map +1 -0
- package/dist/services/audit.service.d.ts +35 -0
- package/dist/services/audit.service.js +92 -0
- package/dist/services/audit.service.js.map +1 -0
- package/dist/services/auth.service.d.ts +33 -0
- package/dist/services/auth.service.js +157 -0
- package/dist/services/auth.service.js.map +1 -0
- package/dist/services/invitation.service.d.ts +37 -0
- package/dist/services/invitation.service.js +143 -0
- package/dist/services/invitation.service.js.map +1 -0
- package/dist/services/nested.service.d.ts +34 -0
- package/dist/services/nested.service.js +163 -0
- package/dist/services/nested.service.js.map +1 -0
- package/dist/services/organization.service.d.ts +13 -0
- package/dist/services/organization.service.js +60 -0
- package/dist/services/organization.service.js.map +1 -0
- package/dist/services/query-builder.service.d.ts +31 -0
- package/dist/services/query-builder.service.js +151 -0
- package/dist/services/query-builder.service.js.map +1 -0
- package/dist/services/resource.service.d.ts +38 -0
- package/dist/services/resource.service.js +230 -0
- package/dist/services/resource.service.js.map +1 -0
- package/dist/services/route-registration.service.d.ts +40 -0
- package/dist/services/route-registration.service.js +68 -0
- package/dist/services/route-registration.service.js.map +1 -0
- package/dist/services/scope.service.d.ts +16 -0
- package/dist/services/scope.service.js +32 -0
- package/dist/services/scope.service.js.map +1 -0
- package/dist/services/serializer.service.d.ts +36 -0
- package/dist/services/serializer.service.js +90 -0
- package/dist/services/serializer.service.js.map +1 -0
- package/dist/services/validation.service.d.ts +50 -0
- package/dist/services/validation.service.js +203 -0
- package/dist/services/validation.service.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/utils/fk-chain-walker.d.ts +30 -0
- package/dist/utils/fk-chain-walker.js +23 -0
- package/dist/utils/fk-chain-walker.js.map +1 -0
- package/dist/utils/format.d.ts +7 -0
- package/dist/utils/format.js +28 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/model-builder.d.ts +64 -0
- package/dist/utils/model-builder.js +67 -0
- package/dist/utils/model-builder.js.map +1 -0
- package/dist/utils/permission-matcher.d.ts +46 -0
- package/dist/utils/permission-matcher.js +120 -0
- package/dist/utils/permission-matcher.js.map +1 -0
- package/dist/utils/scope-discovery.d.ts +34 -0
- package/dist/utils/scope-discovery.js +102 -0
- package/dist/utils/scope-discovery.js.map +1 -0
- package/package.json +64 -0
- package/stubs/skills/rhino-audit.md +184 -0
- package/stubs/skills/rhino-bugfix.md +117 -0
- package/stubs/skills/rhino-deploy.md +5 -0
- package/stubs/skills/rhino-docs.md +147 -0
- package/stubs/skills/rhino-feature.md +146 -0
- package/stubs/skills/rhino-migrate.md +181 -0
- package/stubs/skills/rhino-model.md +180 -0
- package/stubs/skills/rhino-plan.md +5 -0
- package/stubs/skills/rhino-policy.md +183 -0
- package/stubs/skills/rhino-refactor.md +147 -0
- package/stubs/skills/rhino-review.md +113 -0
- package/stubs/skills/rhino-scope.md +140 -0
- package/stubs/skills/rhino-test.md +233 -0
|
@@ -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;
|