@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,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestGenerator = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Generates a Jest spec for a blueprint resource.
|
|
6
|
+
*
|
|
7
|
+
* Produces a self-contained file using the library's `buildEnv` helper, which
|
|
8
|
+
* the library ships under `test/helpers/make-controller.ts`. Consumer apps
|
|
9
|
+
* can copy that helper into their own test tree or replace the import path
|
|
10
|
+
* with their own equivalent — a comment in the generated file explains how.
|
|
11
|
+
*
|
|
12
|
+
* Tests produced:
|
|
13
|
+
* 1. CRUD happy-path (index / show / store / update / destroy)
|
|
14
|
+
* 2. 403 when a restricted role attempts a write action
|
|
15
|
+
* 3. 404 for cross-tenant access (when `belongs_to_organization: true`)
|
|
16
|
+
*
|
|
17
|
+
* Controller invocation uses the real `GlobalController` public method
|
|
18
|
+
* signatures: `index(modelSlug, query, req)`, `show(modelSlug, id, query, req)`,
|
|
19
|
+
* `store(modelSlug, body, req)`, `update(modelSlug, id, body, req)`,
|
|
20
|
+
* `destroy(modelSlug, id, req)`.
|
|
21
|
+
*/
|
|
22
|
+
class TestGenerator {
|
|
23
|
+
generate(blueprint) {
|
|
24
|
+
const { model, slug, options, permissions } = blueprint;
|
|
25
|
+
const roles = Object.keys(permissions);
|
|
26
|
+
const adminRole = roles.find((r) => r === 'admin') ?? roles[0] ?? 'admin';
|
|
27
|
+
const restrictedRole = roles.find((r) => {
|
|
28
|
+
const actions = permissions[r]?.actions ?? [];
|
|
29
|
+
return !actions.includes('store') || !actions.includes('update') || !actions.includes('destroy');
|
|
30
|
+
});
|
|
31
|
+
const modelKey = this.camelCase(model);
|
|
32
|
+
const sampleRow = this.buildSampleRow(blueprint);
|
|
33
|
+
const createPayload = this.buildCreatePayload(blueprint);
|
|
34
|
+
const updatePayload = this.buildUpdatePayload(blueprint);
|
|
35
|
+
const adminPerms = this.permissionsFor(slug, permissions[adminRole]);
|
|
36
|
+
// BP-005: UUID-PK models use strings in Prisma `where: { id: '...' }`.
|
|
37
|
+
const sampleId = options.has_uuid
|
|
38
|
+
? sampleRow.id // already UUID from buildSampleRow
|
|
39
|
+
: 1;
|
|
40
|
+
const idLiteral = options.has_uuid ? `'${sampleId}'` : '1';
|
|
41
|
+
const idRouteParam = options.has_uuid ? `'${sampleId}'` : "'1'";
|
|
42
|
+
const lines = [];
|
|
43
|
+
const push = (s = '') => lines.push(s);
|
|
44
|
+
push(`// Generated by Rhino Blueprint — do not edit directly.`);
|
|
45
|
+
push(`// Source: .rhino/blueprints/${blueprint.source_file}`);
|
|
46
|
+
push(`// NOTE: this spec imports \`buildEnv\` from the library test helper.`);
|
|
47
|
+
push(`// For your app, replace the import with your own test helper or the`);
|
|
48
|
+
push(`// published helper re-exported from \`@rhino-dev/rhino-nestjs/testing\`.`);
|
|
49
|
+
push(`import { buildEnv } from '../../test/helpers/make-controller';`);
|
|
50
|
+
push(`import type { RhinoConfig } from '@rhino-dev/rhino-nestjs';`);
|
|
51
|
+
push(``);
|
|
52
|
+
// Config helper
|
|
53
|
+
push(`function makeConfig(overrides: Partial<RhinoConfig> = {}): RhinoConfig {`);
|
|
54
|
+
push(` return {`);
|
|
55
|
+
push(` models: {`);
|
|
56
|
+
push(` ${slug}: {`);
|
|
57
|
+
push(` model: '${modelKey}',`);
|
|
58
|
+
push(` belongsToOrganization: ${options.belongs_to_organization},`);
|
|
59
|
+
push(` softDeletes: ${options.soft_deletes},`);
|
|
60
|
+
push(` hasAuditTrail: ${options.audit_trail},`);
|
|
61
|
+
push(` },`);
|
|
62
|
+
push(` },`);
|
|
63
|
+
push(` ...overrides,`);
|
|
64
|
+
push(` };`);
|
|
65
|
+
push(`}`);
|
|
66
|
+
push(``);
|
|
67
|
+
// User helper — matches the shape consumed by permission-matcher.ts
|
|
68
|
+
push(`/** Build a user with a role + permissions for the target organization. */`);
|
|
69
|
+
push(`function makeUser(role: string, perms: string[] = [], orgId = 1) {`);
|
|
70
|
+
push(` return {`);
|
|
71
|
+
push(` id: 1,`);
|
|
72
|
+
push(` userRoles: [`);
|
|
73
|
+
push(` { organizationId: orgId, permissions: perms, role: { slug: role } },`);
|
|
74
|
+
push(` ],`);
|
|
75
|
+
push(` };`);
|
|
76
|
+
push(`}`);
|
|
77
|
+
push(``);
|
|
78
|
+
push(`const sampleRow = ${JSON.stringify(sampleRow, null, 2)};`);
|
|
79
|
+
push(`const adminPerms = ${JSON.stringify(adminPerms)};`);
|
|
80
|
+
push(``);
|
|
81
|
+
push(`describe('${model} resource', () => {`);
|
|
82
|
+
// Happy path
|
|
83
|
+
push(` // -----------------------------------------------------------------`);
|
|
84
|
+
push(` // CRUD happy path`);
|
|
85
|
+
push(` // -----------------------------------------------------------------`);
|
|
86
|
+
push(``);
|
|
87
|
+
push(` it('index returns records for the current org', async () => {`);
|
|
88
|
+
push(` const env = buildEnv(makeConfig(), { ${modelKey}: [sampleRow] });`);
|
|
89
|
+
push(` const user = makeUser('${adminRole}', adminPerms);`);
|
|
90
|
+
push(` const req = { user, organization: { id: 1 } } as any;`);
|
|
91
|
+
push(` const res: any = await env.controllers.global.index('${slug}', {}, req);`);
|
|
92
|
+
push(` expect(res).toBeDefined();`);
|
|
93
|
+
push(` });`);
|
|
94
|
+
push(``);
|
|
95
|
+
push(` it('show returns a single record by id', async () => {`);
|
|
96
|
+
push(` const env = buildEnv(makeConfig(), { ${modelKey}: [{ ...sampleRow, id: ${idLiteral} }] });`);
|
|
97
|
+
push(` const user = makeUser('${adminRole}', adminPerms);`);
|
|
98
|
+
push(` const req = { user, organization: { id: 1 } } as any;`);
|
|
99
|
+
push(` const res: any = await env.controllers.global.show('${slug}', ${idRouteParam}, {}, req);`);
|
|
100
|
+
push(` expect(res).toMatchObject({ id: ${idLiteral} });`);
|
|
101
|
+
push(` });`);
|
|
102
|
+
push(``);
|
|
103
|
+
push(` it('store persists a new record', async () => {`);
|
|
104
|
+
push(` const env = buildEnv(makeConfig());`);
|
|
105
|
+
push(` const user = makeUser('${adminRole}', adminPerms);`);
|
|
106
|
+
push(` const req = { user, organization: { id: 1 } } as any;`);
|
|
107
|
+
push(` const body = ${JSON.stringify(createPayload)};`);
|
|
108
|
+
push(` await env.controllers.global.store('${slug}', body, req);`);
|
|
109
|
+
push(` const rows = env.client._data.${modelKey} ?? [];`);
|
|
110
|
+
push(` expect(rows.length).toBeGreaterThan(0);`);
|
|
111
|
+
push(` });`);
|
|
112
|
+
push(``);
|
|
113
|
+
push(` it('update modifies an existing record', async () => {`);
|
|
114
|
+
push(` const env = buildEnv(makeConfig(), { ${modelKey}: [{ ...sampleRow, id: ${idLiteral} }] });`);
|
|
115
|
+
push(` const user = makeUser('${adminRole}', adminPerms);`);
|
|
116
|
+
push(` const req = { user, organization: { id: 1 } } as any;`);
|
|
117
|
+
push(` const body = ${JSON.stringify(updatePayload)};`);
|
|
118
|
+
push(` const res: any = await env.controllers.global.update('${slug}', ${idRouteParam}, body, req);`);
|
|
119
|
+
push(` expect(res).toBeDefined();`);
|
|
120
|
+
push(` });`);
|
|
121
|
+
push(``);
|
|
122
|
+
push(` it('destroy removes (or soft-deletes) the record', async () => {`);
|
|
123
|
+
push(` const env = buildEnv(makeConfig(), { ${modelKey}: [{ ...sampleRow, id: ${idLiteral} }] });`);
|
|
124
|
+
push(` const user = makeUser('${adminRole}', adminPerms);`);
|
|
125
|
+
push(` const req = { user, organization: { id: 1 } } as any;`);
|
|
126
|
+
push(` await env.controllers.global.destroy('${slug}', ${idRouteParam}, req);`);
|
|
127
|
+
push(` const rows = env.client._data.${modelKey} ?? [];`);
|
|
128
|
+
push(` const active = rows.filter((r: any) => !r.deletedAt);`);
|
|
129
|
+
push(` expect(active).toHaveLength(0);`);
|
|
130
|
+
push(` });`);
|
|
131
|
+
push(``);
|
|
132
|
+
// 403 restricted role
|
|
133
|
+
if (restrictedRole) {
|
|
134
|
+
const restrictedPerms = this.permissionsFor(slug, permissions[restrictedRole]);
|
|
135
|
+
push(` // -----------------------------------------------------------------`);
|
|
136
|
+
push(` // 403 — role without store permission`);
|
|
137
|
+
push(` // -----------------------------------------------------------------`);
|
|
138
|
+
push(``);
|
|
139
|
+
push(` it('rejects store from a role without store permission', async () => {`);
|
|
140
|
+
push(` const env = buildEnv(makeConfig());`);
|
|
141
|
+
push(` const user = makeUser('${restrictedRole}', ${JSON.stringify(restrictedPerms)});`);
|
|
142
|
+
push(` const req = { user, organization: { id: 1 } } as any;`);
|
|
143
|
+
push(` const body = ${JSON.stringify(createPayload)};`);
|
|
144
|
+
push(` // Without \`${slug}.store\` in permissions, the policy check will reject.`);
|
|
145
|
+
push(` // The exact exception type depends on how the route is guarded;`);
|
|
146
|
+
push(` // here we assert store throws (not persists).`);
|
|
147
|
+
push(` await expect(`);
|
|
148
|
+
push(` env.controllers.global.store('${slug}', body, req),`);
|
|
149
|
+
push(` ).rejects.toBeDefined();`);
|
|
150
|
+
push(` });`);
|
|
151
|
+
push(``);
|
|
152
|
+
}
|
|
153
|
+
// 404 cross-tenant
|
|
154
|
+
if (options.belongs_to_organization) {
|
|
155
|
+
push(` // -----------------------------------------------------------------`);
|
|
156
|
+
push(` // 404 — cross-tenant access`);
|
|
157
|
+
push(` // -----------------------------------------------------------------`);
|
|
158
|
+
push(``);
|
|
159
|
+
push(` it('does not return records belonging to another organization', async () => {`);
|
|
160
|
+
push(` const env = buildEnv(makeConfig(), {`);
|
|
161
|
+
push(` ${modelKey}: [{ ...sampleRow, id: ${idLiteral}, organizationId: 99 }],`);
|
|
162
|
+
push(` });`);
|
|
163
|
+
push(` const user = makeUser('${adminRole}', adminPerms, 1);`);
|
|
164
|
+
push(` const req = { user, organization: { id: 1 } } as any;`);
|
|
165
|
+
push(` await expect(`);
|
|
166
|
+
push(` env.controllers.global.show('${slug}', ${idRouteParam}, {}, req),`);
|
|
167
|
+
push(` ).rejects.toMatchObject({ code: 'NOT_FOUND' });`);
|
|
168
|
+
push(` });`);
|
|
169
|
+
push(``);
|
|
170
|
+
}
|
|
171
|
+
push(`});`);
|
|
172
|
+
push(``);
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
}
|
|
175
|
+
// -------------------------------------------------------------------------
|
|
176
|
+
// Helpers
|
|
177
|
+
// -------------------------------------------------------------------------
|
|
178
|
+
permissionsFor(slug, perm) {
|
|
179
|
+
if (!perm?.actions)
|
|
180
|
+
return [];
|
|
181
|
+
if (perm.actions.includes('*'))
|
|
182
|
+
return [`${slug}.*`];
|
|
183
|
+
return perm.actions.map((a) => `${slug}.${a}`);
|
|
184
|
+
}
|
|
185
|
+
buildSampleRow(blueprint) {
|
|
186
|
+
// BP-005: UUID-PK models emit a deterministic UUID sample so generated
|
|
187
|
+
// tests pass Prisma's `where: { id: '...' }` validation.
|
|
188
|
+
const id = blueprint.options.has_uuid
|
|
189
|
+
? '00000000-0000-0000-0000-000000000001'
|
|
190
|
+
: 1;
|
|
191
|
+
const row = { id };
|
|
192
|
+
for (const col of blueprint.columns) {
|
|
193
|
+
row[col.name] = this.sampleValue(col.type, col.values);
|
|
194
|
+
}
|
|
195
|
+
if (blueprint.options.belongs_to_organization)
|
|
196
|
+
row['organizationId'] = 1;
|
|
197
|
+
return row;
|
|
198
|
+
}
|
|
199
|
+
buildCreatePayload(blueprint) {
|
|
200
|
+
const payload = {};
|
|
201
|
+
const adminPerm = Object.values(blueprint.permissions)[0];
|
|
202
|
+
if (!adminPerm) {
|
|
203
|
+
for (const col of blueprint.columns)
|
|
204
|
+
payload[col.name] = this.sampleValue(col.type, col.values);
|
|
205
|
+
return payload;
|
|
206
|
+
}
|
|
207
|
+
const createFields = adminPerm.create_fields;
|
|
208
|
+
if (!createFields || (Array.isArray(createFields) && createFields[0] === '*')) {
|
|
209
|
+
for (const col of blueprint.columns)
|
|
210
|
+
payload[col.name] = this.sampleValue(col.type, col.values);
|
|
211
|
+
return payload;
|
|
212
|
+
}
|
|
213
|
+
const fieldNames = Array.isArray(createFields) ? createFields : Object.keys(createFields);
|
|
214
|
+
for (const name of fieldNames) {
|
|
215
|
+
const col = blueprint.columns.find((c) => c.name === name);
|
|
216
|
+
payload[name] = this.sampleValue(col?.type ?? 'string', col?.values);
|
|
217
|
+
}
|
|
218
|
+
return payload;
|
|
219
|
+
}
|
|
220
|
+
buildUpdatePayload(blueprint) {
|
|
221
|
+
const payload = {};
|
|
222
|
+
const firstPerm = Object.values(blueprint.permissions)[0];
|
|
223
|
+
if (!firstPerm)
|
|
224
|
+
return payload;
|
|
225
|
+
const updateFields = firstPerm.update_fields;
|
|
226
|
+
if (!updateFields || (Array.isArray(updateFields) && updateFields[0] === '*')) {
|
|
227
|
+
const col = blueprint.columns[0];
|
|
228
|
+
if (col)
|
|
229
|
+
payload[col.name] = this.sampleValue(col.type, col.values);
|
|
230
|
+
return payload;
|
|
231
|
+
}
|
|
232
|
+
const fieldNames = Array.isArray(updateFields) ? updateFields : Object.keys(updateFields);
|
|
233
|
+
const name = fieldNames[0];
|
|
234
|
+
if (name) {
|
|
235
|
+
const col = blueprint.columns.find((c) => c.name === name);
|
|
236
|
+
payload[name] = this.sampleValue(col?.type ?? 'string', col?.values);
|
|
237
|
+
}
|
|
238
|
+
return payload;
|
|
239
|
+
}
|
|
240
|
+
sampleValue(type, enumValues) {
|
|
241
|
+
switch (type) {
|
|
242
|
+
case 'string':
|
|
243
|
+
case 'text':
|
|
244
|
+
return 'sample text';
|
|
245
|
+
case 'integer':
|
|
246
|
+
case 'bigInteger':
|
|
247
|
+
case 'foreignId':
|
|
248
|
+
return 1;
|
|
249
|
+
case 'float':
|
|
250
|
+
case 'decimal':
|
|
251
|
+
return 1.5;
|
|
252
|
+
case 'boolean':
|
|
253
|
+
return true;
|
|
254
|
+
case 'date':
|
|
255
|
+
case 'datetime':
|
|
256
|
+
case 'timestamp':
|
|
257
|
+
return '2024-01-01T00:00:00Z';
|
|
258
|
+
case 'json':
|
|
259
|
+
return {};
|
|
260
|
+
case 'uuid':
|
|
261
|
+
return '00000000-0000-0000-0000-000000000000';
|
|
262
|
+
case 'enum':
|
|
263
|
+
return enumValues?.[0] ?? 'draft';
|
|
264
|
+
default:
|
|
265
|
+
return 'value';
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
camelCase(str) {
|
|
269
|
+
if (!str)
|
|
270
|
+
return str;
|
|
271
|
+
return str.charAt(0).toLowerCase() + str.slice(1).replace(/[-_](.)/g, (_, c) => c.toUpperCase());
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
exports.TestGenerator = TestGenerator;
|
|
275
|
+
//# sourceMappingURL=test-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-generator.js","sourceRoot":"","sources":["../../../src/blueprint/generators/test-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
interface ManifestEntry {
|
|
2
|
+
content_hash: string;
|
|
3
|
+
generated_files: string[];
|
|
4
|
+
generated_at: string;
|
|
5
|
+
}
|
|
6
|
+
interface ManifestData {
|
|
7
|
+
version: number;
|
|
8
|
+
generated_at: string | null;
|
|
9
|
+
files: Record<string, ManifestEntry>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Tracks SHA-256 hashes of blueprint files in `.rhino/manifest.json`
|
|
13
|
+
* so unchanged files are skipped on re-generation.
|
|
14
|
+
*/
|
|
15
|
+
export declare class ManifestManager {
|
|
16
|
+
private readonly manifestPath;
|
|
17
|
+
private manifest;
|
|
18
|
+
constructor(blueprintsDir: string);
|
|
19
|
+
/**
|
|
20
|
+
* Check whether a blueprint file has changed since the last generation run.
|
|
21
|
+
*
|
|
22
|
+
* @param filename The blueprint filename (e.g. 'post.yaml')
|
|
23
|
+
* @param currentHash SHA-256 of the current file contents
|
|
24
|
+
* @returns true if the file is new or its hash differs from the stored one
|
|
25
|
+
*/
|
|
26
|
+
hasChanged(filename: string, currentHash: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Record a successful generation run for a blueprint file.
|
|
29
|
+
*
|
|
30
|
+
* @param filename The blueprint filename
|
|
31
|
+
* @param contentHash SHA-256 of the file at generation time
|
|
32
|
+
* @param generatedFiles Paths to all files produced by the generators
|
|
33
|
+
*/
|
|
34
|
+
recordGeneration(filename: string, contentHash: string, generatedFiles: string[]): void;
|
|
35
|
+
/**
|
|
36
|
+
* Return the list of files that were generated the last time a blueprint was processed.
|
|
37
|
+
*/
|
|
38
|
+
getGeneratedFiles(filename: string): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Return all blueprint filenames currently tracked in the manifest.
|
|
41
|
+
*/
|
|
42
|
+
getTrackedFiles(): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Remove a blueprint entry from the manifest (use when the source YAML is deleted).
|
|
45
|
+
*/
|
|
46
|
+
removeTracking(filename: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Persist the manifest to disk.
|
|
49
|
+
* Creates the parent directory if it does not exist.
|
|
50
|
+
*/
|
|
51
|
+
save(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Return the full in-memory manifest (useful for testing / debugging).
|
|
54
|
+
*/
|
|
55
|
+
getManifest(): ManifestData;
|
|
56
|
+
private load;
|
|
57
|
+
}
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,137 @@
|
|
|
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.ManifestManager = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// ManifestManager
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* Tracks SHA-256 hashes of blueprint files in `.rhino/manifest.json`
|
|
44
|
+
* so unchanged files are skipped on re-generation.
|
|
45
|
+
*/
|
|
46
|
+
class ManifestManager {
|
|
47
|
+
manifestPath;
|
|
48
|
+
manifest;
|
|
49
|
+
constructor(blueprintsDir) {
|
|
50
|
+
// Store manifest alongside blueprints under .rhino/manifest.json
|
|
51
|
+
this.manifestPath = path.join(blueprintsDir, 'manifest.json');
|
|
52
|
+
this.manifest = this.load();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check whether a blueprint file has changed since the last generation run.
|
|
56
|
+
*
|
|
57
|
+
* @param filename The blueprint filename (e.g. 'post.yaml')
|
|
58
|
+
* @param currentHash SHA-256 of the current file contents
|
|
59
|
+
* @returns true if the file is new or its hash differs from the stored one
|
|
60
|
+
*/
|
|
61
|
+
hasChanged(filename, currentHash) {
|
|
62
|
+
const entry = this.manifest.files[filename];
|
|
63
|
+
if (!entry)
|
|
64
|
+
return true; // new file
|
|
65
|
+
return entry.content_hash !== currentHash;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Record a successful generation run for a blueprint file.
|
|
69
|
+
*
|
|
70
|
+
* @param filename The blueprint filename
|
|
71
|
+
* @param contentHash SHA-256 of the file at generation time
|
|
72
|
+
* @param generatedFiles Paths to all files produced by the generators
|
|
73
|
+
*/
|
|
74
|
+
recordGeneration(filename, contentHash, generatedFiles) {
|
|
75
|
+
this.manifest.files[filename] = {
|
|
76
|
+
content_hash: contentHash,
|
|
77
|
+
generated_files: generatedFiles,
|
|
78
|
+
generated_at: new Date().toISOString(),
|
|
79
|
+
};
|
|
80
|
+
this.manifest.generated_at = new Date().toISOString();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Return the list of files that were generated the last time a blueprint was processed.
|
|
84
|
+
*/
|
|
85
|
+
getGeneratedFiles(filename) {
|
|
86
|
+
return this.manifest.files[filename]?.generated_files ?? [];
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Return all blueprint filenames currently tracked in the manifest.
|
|
90
|
+
*/
|
|
91
|
+
getTrackedFiles() {
|
|
92
|
+
return Object.keys(this.manifest.files);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Remove a blueprint entry from the manifest (use when the source YAML is deleted).
|
|
96
|
+
*/
|
|
97
|
+
removeTracking(filename) {
|
|
98
|
+
delete this.manifest.files[filename];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Persist the manifest to disk.
|
|
102
|
+
* Creates the parent directory if it does not exist.
|
|
103
|
+
*/
|
|
104
|
+
save() {
|
|
105
|
+
const dir = path.dirname(this.manifestPath);
|
|
106
|
+
if (!fs.existsSync(dir)) {
|
|
107
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
108
|
+
}
|
|
109
|
+
fs.writeFileSync(this.manifestPath, JSON.stringify(this.manifest, null, 2) + '\n', 'utf8');
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Return the full in-memory manifest (useful for testing / debugging).
|
|
113
|
+
*/
|
|
114
|
+
getManifest() {
|
|
115
|
+
return this.manifest;
|
|
116
|
+
}
|
|
117
|
+
// -------------------------------------------------------------------------
|
|
118
|
+
// Private
|
|
119
|
+
// -------------------------------------------------------------------------
|
|
120
|
+
load() {
|
|
121
|
+
const empty = { version: 1, generated_at: null, files: {} };
|
|
122
|
+
if (!fs.existsSync(this.manifestPath))
|
|
123
|
+
return empty;
|
|
124
|
+
try {
|
|
125
|
+
const raw = fs.readFileSync(this.manifestPath, 'utf8');
|
|
126
|
+
const parsed = JSON.parse(raw);
|
|
127
|
+
if (typeof parsed === 'object' && parsed !== null)
|
|
128
|
+
return parsed;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// corrupt manifest — start fresh
|
|
132
|
+
}
|
|
133
|
+
return empty;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.ManifestManager = ManifestManager;
|
|
137
|
+
//# sourceMappingURL=manifest-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-manager.js","sourceRoot":"","sources":["../../src/blueprint/manifest-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rhino blueprint [--force] [--dry-run] [--model=slug]
|
|
3
|
+
*
|
|
4
|
+
* Delegates to BlueprintRunner (src/blueprint/blueprint-runner.ts).
|
|
5
|
+
*
|
|
6
|
+
* NOTE: BlueprintRunner is loaded via a dynamic require() so that this CLI
|
|
7
|
+
* file compiles and runs even when blueprint-runner.ts has not yet been built.
|
|
8
|
+
* When the runner is absent, the command exits with code 1 and prints a
|
|
9
|
+
* helpful message.
|
|
10
|
+
*/
|
|
11
|
+
export interface BlueprintOptions {
|
|
12
|
+
force?: boolean;
|
|
13
|
+
dryRun?: boolean;
|
|
14
|
+
model?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function runBlueprint(opts: BlueprintOptions): Promise<void>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* rhino blueprint [--force] [--dry-run] [--model=slug]
|
|
4
|
+
*
|
|
5
|
+
* Delegates to BlueprintRunner (src/blueprint/blueprint-runner.ts).
|
|
6
|
+
*
|
|
7
|
+
* NOTE: BlueprintRunner is loaded via a dynamic require() so that this CLI
|
|
8
|
+
* file compiles and runs even when blueprint-runner.ts has not yet been built.
|
|
9
|
+
* When the runner is absent, the command exits with code 1 and prints a
|
|
10
|
+
* helpful message.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.runBlueprint = runBlueprint;
|
|
14
|
+
async function runBlueprint(opts) {
|
|
15
|
+
// Lazy-load the runner so the CLI still compiles without the dependency.
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
|
+
let runner;
|
|
18
|
+
try {
|
|
19
|
+
// Try compiled dist first, then fall back to ts source path.
|
|
20
|
+
// The runner module must export a default object or a named `BlueprintRunner`
|
|
21
|
+
// with a `run(opts)` method — or itself be the function.
|
|
22
|
+
const mod = require('../../blueprint/blueprint-runner');
|
|
23
|
+
const RunnerClass = mod.BlueprintRunner ?? mod.default;
|
|
24
|
+
runner = typeof RunnerClass === 'function' ? new RunnerClass() : RunnerClass;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
console.error(' Error: BlueprintRunner not found.\n' +
|
|
28
|
+
' Make sure src/blueprint/blueprint-runner.ts exists and the project is built.\n' +
|
|
29
|
+
' Expected export: class BlueprintRunner { async run(opts) { ... } }');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
await runner.run(opts);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=blueprint.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blueprint.command.js","sourceRoot":"","sources":["../../../src/cli/commands/blueprint.command.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAQH,oCAuBC;AAvBM,KAAK,UAAU,YAAY,CAAC,IAAsB;IACvD,yEAAyE;IACzE,iEAAiE;IACjE,IAAI,MAA0D,CAAC;IAE/D,IAAI,CAAC;QACH,6DAA6D;QAC7D,8EAA8E;QAC9E,yDAAyD;QACzD,MAAM,GAAG,GAAG,OAAO,CAAC,kCAAkC,CAAC,CAAC;QACxD,MAAM,WAAW,GAAG,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,OAAO,CAAC;QACvD,MAAM,GAAG,OAAO,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CACX,uCAAuC;YACrC,kFAAkF;YAClF,sEAAsE,CACzE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runExportPostman = runExportPostman;
|
|
4
|
+
/**
|
|
5
|
+
* rhino export-postman [--output=file.json] [--base-url=http://localhost:3000/api]
|
|
6
|
+
*
|
|
7
|
+
* Delegates to PostmanExporter (src/exporters/postman-exporter.ts).
|
|
8
|
+
*
|
|
9
|
+
* NOTE: PostmanExporter is loaded via a dynamic require() so that this CLI
|
|
10
|
+
* file compiles and runs even when the exporter has not yet been built.
|
|
11
|
+
*/
|
|
12
|
+
const io_1 = require("../utils/io");
|
|
13
|
+
async function runExportPostman(opts) {
|
|
14
|
+
const outputPath = opts.output ?? 'postman_collection.json';
|
|
15
|
+
const baseUrl = opts.baseUrl ?? 'http://localhost:3000/api';
|
|
16
|
+
// Lazy-load the exporter.
|
|
17
|
+
// Expected export: function generate(config, opts): string
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
19
|
+
let generate;
|
|
20
|
+
try {
|
|
21
|
+
const mod = require('../../exporters/postman-exporter');
|
|
22
|
+
generate = mod.generate ?? mod.default?.generate;
|
|
23
|
+
if (typeof generate !== 'function')
|
|
24
|
+
throw new Error('generate not a function');
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
console.error(' Error: PostmanExporter not found.\n' +
|
|
28
|
+
' Make sure src/exporters/postman-exporter.ts exists and the project is built.\n' +
|
|
29
|
+
' Expected export: function generate(config, opts): string');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// PostmanExporter reads the live config — pass empty config here;
|
|
34
|
+
// the exporter itself will load rhino.config or equivalent.
|
|
35
|
+
const json = generate({}, { output: outputPath, baseUrl });
|
|
36
|
+
(0, io_1.writeFileSafely)(outputPath, json);
|
|
37
|
+
console.log(` Postman collection written to: ${outputPath}`);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=export-postman.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-postman.command.js","sourceRoot":"","sources":["../../../src/cli/commands/export-postman.command.ts"],"names":[],"mappings":";;AAeA,4CA+BC;AA9CD;;;;;;;GAOG;AACH,oCAA8C;AAOvC,KAAK,UAAU,gBAAgB,CACpC,IAA0B;IAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,yBAAyB,CAAC;IAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,2BAA2B,CAAC;IAE5D,0BAA0B;IAC1B,2DAA2D;IAC3D,iEAAiE;IACjE,IAAI,QAAiF,CAAC;IAEtF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,kCAAkC,CAAC,CAAC;QACxD,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC;QACjD,IAAI,OAAO,QAAQ,KAAK,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACjF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CACX,uCAAuC;YACrC,kFAAkF;YAClF,4DAA4D,CAC/D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,kEAAkE;IAClE,4DAA4D;IAC5D,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IAE3D,IAAA,oBAAe,EAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,oCAAoC,UAAU,EAAE,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runExportTypes = runExportTypes;
|
|
4
|
+
/**
|
|
5
|
+
* rhino export-types [--output=path/to/types.d.ts]
|
|
6
|
+
*
|
|
7
|
+
* Delegates to TypeScriptExporter (src/exporters/typescript-exporter.ts).
|
|
8
|
+
*
|
|
9
|
+
* NOTE: TypeScriptExporter is loaded via a dynamic require() so that this CLI
|
|
10
|
+
* file compiles and runs even when the exporter has not yet been built.
|
|
11
|
+
*/
|
|
12
|
+
const io_1 = require("../utils/io");
|
|
13
|
+
async function runExportTypes(opts) {
|
|
14
|
+
const outputPath = opts.output ?? 'src/types/rhino.d.ts';
|
|
15
|
+
// Lazy-load the exporter.
|
|
16
|
+
// Expected export: function generate(config, opts): string
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
18
|
+
let generate;
|
|
19
|
+
try {
|
|
20
|
+
const mod = require('../../exporters/typescript-exporter');
|
|
21
|
+
generate = mod.generate ?? mod.default?.generate;
|
|
22
|
+
if (typeof generate !== 'function')
|
|
23
|
+
throw new Error('generate not a function');
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
console.error(' Error: TypeScriptExporter not found.\n' +
|
|
27
|
+
' Make sure src/exporters/typescript-exporter.ts exists and the project is built.\n' +
|
|
28
|
+
' Expected export: function generate(config, opts): string');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const dts = generate({}, { output: outputPath });
|
|
33
|
+
(0, io_1.writeFileSafely)(outputPath, dts);
|
|
34
|
+
console.log(` TypeScript types written to: ${outputPath}`);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=export-types.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-types.command.js","sourceRoot":"","sources":["../../../src/cli/commands/export-types.command.ts"],"names":[],"mappings":";;AAcA,wCA4BC;AA1CD;;;;;;;GAOG;AACH,oCAA8C;AAMvC,KAAK,UAAU,cAAc,CAClC,IAAwB;IAExB,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,sBAAsB,CAAC;IAEzD,0BAA0B;IAC1B,2DAA2D;IAC3D,iEAAiE;IACjE,IAAI,QAA+E,CAAC;IAEpF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,qCAAqC,CAAC,CAAC;QAC3D,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC;QACjD,IAAI,OAAO,QAAQ,KAAK,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACjF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CACX,0CAA0C;YACxC,qFAAqF;YACrF,4DAA4D,CAC/D,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAEjD,IAAA,oBAAe,EAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,kCAAkC,UAAU,EAAE,CAAC,CAAC;AAC9D,CAAC"}
|