@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,52 @@
1
+ import type { Blueprint } from '../blueprint-parser';
2
+ /**
3
+ * Generates a TypeScript file that exports a `ModelRegistration` object.
4
+ *
5
+ * The output file:
6
+ * - imports `z` from zod and `ModelRegistration` from the library
7
+ * - builds `validationStore` and `validationUpdate` as `Record<string, ZodSchema>`
8
+ * keyed by role (from `permissions.*.create_fields` / `update_fields`)
9
+ * - sets `allowedFilters`, `allowedSorts`, `allowedSearch` from column flags
10
+ * - sets `belongsToOrganization`, `softDeletes`, `hasAuditTrail` flags
11
+ *
12
+ * Design decisions:
13
+ * - Field entries with value `'required'` → `z.string()` (non-optional)
14
+ * - Field entries with value `'nullable'` → `z.string().nullable().optional()`
15
+ * - Field entries with value `'sometimes'` → `z.string().optional()`
16
+ * - When create_fields / update_fields is `['*']` or empty, we emit a
17
+ * passthrough schema `z.object({}).passthrough()` as a permissive default.
18
+ * - If all roles share the same schema we still emit a role-keyed map for
19
+ * uniformity (the runtime ValidationService uses the map form).
20
+ */
21
+ export declare class ResourceDefinitionGenerator {
22
+ generate(blueprint: Blueprint): string;
23
+ /**
24
+ * Build a map of role → Zod schema code string for a given field surface
25
+ * ('create_fields' or 'update_fields').
26
+ */
27
+ private buildRoleSchemas;
28
+ private buildZodSchema;
29
+ /**
30
+ * BP-003: derive presence from a column's `nullable` flag when no explicit
31
+ * modifier was given.
32
+ *
33
+ * nullable: false, no default → 'required' on create, 'sometimes' on update
34
+ * nullable: false, has default → 'sometimes' on both (DB will fill in)
35
+ * nullable: true → 'nullable' on both surfaces
36
+ *
37
+ * Fallback to 'optional' when the column isn't declared (unlikely but safe).
38
+ */
39
+ private inferPresenceFromColumn;
40
+ /**
41
+ * Determine the Zod type for a single field based on its column definition and presence modifier.
42
+ *
43
+ * Presence values:
44
+ * 'required' → z.string() (must be present, not null)
45
+ * 'nullable' → z.string().nullable().optional()
46
+ * 'sometimes' → z.string().optional()
47
+ * 'optional' → z.string().optional() (when presence not specified)
48
+ */
49
+ private zodTypeForColumn;
50
+ private zodBaseType;
51
+ private camelCase;
52
+ }
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResourceDefinitionGenerator = void 0;
4
+ // ---------------------------------------------------------------------------
5
+ // ResourceDefinitionGenerator
6
+ // ---------------------------------------------------------------------------
7
+ /**
8
+ * Generates a TypeScript file that exports a `ModelRegistration` object.
9
+ *
10
+ * The output file:
11
+ * - imports `z` from zod and `ModelRegistration` from the library
12
+ * - builds `validationStore` and `validationUpdate` as `Record<string, ZodSchema>`
13
+ * keyed by role (from `permissions.*.create_fields` / `update_fields`)
14
+ * - sets `allowedFilters`, `allowedSorts`, `allowedSearch` from column flags
15
+ * - sets `belongsToOrganization`, `softDeletes`, `hasAuditTrail` flags
16
+ *
17
+ * Design decisions:
18
+ * - Field entries with value `'required'` → `z.string()` (non-optional)
19
+ * - Field entries with value `'nullable'` → `z.string().nullable().optional()`
20
+ * - Field entries with value `'sometimes'` → `z.string().optional()`
21
+ * - When create_fields / update_fields is `['*']` or empty, we emit a
22
+ * passthrough schema `z.object({}).passthrough()` as a permissive default.
23
+ * - If all roles share the same schema we still emit a role-keyed map for
24
+ * uniformity (the runtime ValidationService uses the map form).
25
+ */
26
+ class ResourceDefinitionGenerator {
27
+ generate(blueprint) {
28
+ const lines = [];
29
+ lines.push(`// Generated by Rhino Blueprint — do not edit directly.`);
30
+ lines.push(`// Source: .rhino/blueprints/${blueprint.source_file}`);
31
+ lines.push(`import { z } from 'zod';`);
32
+ lines.push(`import type { ModelRegistration } from '@rhino-dev/rhino-nestjs';`);
33
+ lines.push('');
34
+ // Policy import (generated separately)
35
+ lines.push(`import { ${blueprint.model}Policy } from '../policies/${blueprint.model}Policy';`);
36
+ lines.push('');
37
+ // Zod schemas per role
38
+ const storeSchemas = this.buildRoleSchemas(blueprint, 'create_fields');
39
+ const updateSchemas = this.buildRoleSchemas(blueprint, 'update_fields');
40
+ lines.push('// ---------------------------------------------------------------------------');
41
+ lines.push('// Validation schemas per role');
42
+ lines.push('// ---------------------------------------------------------------------------');
43
+ lines.push('');
44
+ lines.push('const validationStore: Record<string, z.ZodTypeAny> = {');
45
+ for (const [role, schemaCode] of Object.entries(storeSchemas)) {
46
+ lines.push(` ${role}: ${schemaCode},`);
47
+ }
48
+ lines.push('};');
49
+ lines.push('');
50
+ lines.push('const validationUpdate: Record<string, z.ZodTypeAny> = {');
51
+ for (const [role, schemaCode] of Object.entries(updateSchemas)) {
52
+ lines.push(` ${role}: ${schemaCode},`);
53
+ }
54
+ lines.push('};');
55
+ lines.push('');
56
+ // Allowed query options from column flags
57
+ const allowedFilters = blueprint.columns.filter((c) => c.filterable).map((c) => c.name);
58
+ const allowedSorts = blueprint.columns.filter((c) => c.sortable).map((c) => c.name);
59
+ const allowedSearch = blueprint.columns.filter((c) => c.searchable).map((c) => c.name);
60
+ lines.push('// ---------------------------------------------------------------------------');
61
+ lines.push('// ModelRegistration');
62
+ lines.push('// ---------------------------------------------------------------------------');
63
+ lines.push('');
64
+ lines.push(`export const ${this.camelCase(blueprint.slug)}Registration: ModelRegistration = {`);
65
+ lines.push(` model: '${this.camelCase(blueprint.model)}',`);
66
+ lines.push(` policy: ${blueprint.model}Policy,`);
67
+ lines.push(` validationStore,`);
68
+ lines.push(` validationUpdate,`);
69
+ if (allowedFilters.length > 0) {
70
+ lines.push(` allowedFilters: ${JSON.stringify(allowedFilters)},`);
71
+ }
72
+ if (allowedSorts.length > 0) {
73
+ lines.push(` allowedSorts: ${JSON.stringify(allowedSorts)},`);
74
+ }
75
+ if (allowedSearch.length > 0) {
76
+ lines.push(` allowedSearch: ${JSON.stringify(allowedSearch)},`);
77
+ }
78
+ lines.push(` belongsToOrganization: ${blueprint.options.belongs_to_organization},`);
79
+ lines.push(` softDeletes: ${blueprint.options.soft_deletes},`);
80
+ lines.push(` hasAuditTrail: ${blueprint.options.audit_trail},`);
81
+ if (blueprint.options.has_uuid) {
82
+ // BP-005: surface the flag so ResourceService.castId preserves string IDs
83
+ lines.push(` hasUuid: true,`);
84
+ }
85
+ // BP-004: emit `owner` / `fkConstraints` from YAML when declared so
86
+ // ValidationService.verifyTenantFks (and the FK chain walker) can do
87
+ // cross-tenant validation without a hand-authored override.
88
+ const ownerStr = blueprint.options.owner_chain ?? blueprint.options.owner ?? null;
89
+ if (ownerStr) {
90
+ lines.push(` owner: ${JSON.stringify(ownerStr)},`);
91
+ }
92
+ if (blueprint.fk_constraints?.length > 0) {
93
+ lines.push(` fkConstraints: ${JSON.stringify(blueprint.fk_constraints)},`);
94
+ }
95
+ if (blueprint.options.except_actions?.length > 0) {
96
+ lines.push(` exceptActions: ${JSON.stringify(blueprint.options.except_actions)},`);
97
+ }
98
+ lines.push(`};`);
99
+ lines.push('');
100
+ return lines.join('\n');
101
+ }
102
+ // -------------------------------------------------------------------------
103
+ // Private helpers
104
+ // -------------------------------------------------------------------------
105
+ /**
106
+ * Build a map of role → Zod schema code string for a given field surface
107
+ * ('create_fields' or 'update_fields').
108
+ */
109
+ buildRoleSchemas(blueprint, surface) {
110
+ const result = {};
111
+ for (const [role, perm] of Object.entries(blueprint.permissions)) {
112
+ result[role] = this.buildZodSchema(perm, surface, blueprint.columns);
113
+ }
114
+ return result;
115
+ }
116
+ buildZodSchema(perm, surface, columns) {
117
+ const fields = perm[surface];
118
+ // Wildcard → passthrough permissive schema
119
+ if (Array.isArray(fields) && fields[0] === '*') {
120
+ return `z.object({}).passthrough()`;
121
+ }
122
+ // Array form (no presence modifiers) — BP-003: infer required from
123
+ // the column's `nullable: false` declaration. This lets blueprints
124
+ // express "required title" purely via the column definition, without
125
+ // forcing the object form { title: required } on every permission.
126
+ if (Array.isArray(fields)) {
127
+ if (fields.length === 0)
128
+ return `z.object({})`;
129
+ const entries = fields.map((f) => {
130
+ const col = columns.find((c) => c.name === f);
131
+ // For create surface: non-nullable column → required; nullable → optional/nullable.
132
+ // For update surface: always optional (partial update semantics); keep nullable.
133
+ const presence = this.inferPresenceFromColumn(col, surface);
134
+ return ` ${f}: ${this.zodTypeForColumn(f, columns, presence)}`;
135
+ });
136
+ return `z.object({\n${entries.join(',\n')},\n })`;
137
+ }
138
+ // Object form: { fieldName: 'required' | 'nullable' | 'sometimes' }
139
+ const entries = Object.entries(fields ?? {}).map(([field, presence]) => {
140
+ const zodType = this.zodTypeForColumn(field, columns, presence);
141
+ return ` ${field}: ${zodType}`;
142
+ });
143
+ // Empty object — role has no writable fields (e.g. read-only roles)
144
+ if (entries.length === 0)
145
+ return `z.object({})`;
146
+ return `z.object({\n${entries.join(',\n')},\n })`;
147
+ }
148
+ /**
149
+ * BP-003: derive presence from a column's `nullable` flag when no explicit
150
+ * modifier was given.
151
+ *
152
+ * nullable: false, no default → 'required' on create, 'sometimes' on update
153
+ * nullable: false, has default → 'sometimes' on both (DB will fill in)
154
+ * nullable: true → 'nullable' on both surfaces
155
+ *
156
+ * Fallback to 'optional' when the column isn't declared (unlikely but safe).
157
+ */
158
+ inferPresenceFromColumn(col, surface) {
159
+ if (!col)
160
+ return 'optional';
161
+ if (col.nullable)
162
+ return 'nullable';
163
+ // BP-003 followup: columns with a default value can be omitted on create
164
+ // — the DB (or Prisma @default) supplies the value.
165
+ if (col.default !== null && col.default !== undefined)
166
+ return 'sometimes';
167
+ return surface === 'create_fields' ? 'required' : 'sometimes';
168
+ }
169
+ /**
170
+ * Determine the Zod type for a single field based on its column definition and presence modifier.
171
+ *
172
+ * Presence values:
173
+ * 'required' → z.string() (must be present, not null)
174
+ * 'nullable' → z.string().nullable().optional()
175
+ * 'sometimes' → z.string().optional()
176
+ * 'optional' → z.string().optional() (when presence not specified)
177
+ */
178
+ zodTypeForColumn(fieldName, columns, presence) {
179
+ const col = columns.find((c) => c.name === fieldName);
180
+ const baseType = col ? this.zodBaseType(col) : 'z.string()';
181
+ switch (presence) {
182
+ case 'required':
183
+ return baseType;
184
+ case 'nullable':
185
+ return `${baseType}.nullable().optional()`;
186
+ case 'sometimes':
187
+ case 'optional':
188
+ return `${baseType}.optional()`;
189
+ default:
190
+ return `${baseType}.optional()`;
191
+ }
192
+ }
193
+ zodBaseType(col) {
194
+ switch (col.type) {
195
+ case 'string':
196
+ case 'text':
197
+ case 'uuid':
198
+ return 'z.string()';
199
+ case 'integer':
200
+ case 'bigInteger':
201
+ case 'foreignId':
202
+ return 'z.number().int()';
203
+ case 'float':
204
+ case 'decimal':
205
+ return 'z.number()';
206
+ case 'boolean':
207
+ return 'z.boolean()';
208
+ case 'date':
209
+ case 'datetime':
210
+ case 'timestamp':
211
+ return 'z.string().datetime({ offset: true }).or(z.date())';
212
+ case 'json':
213
+ return 'z.record(z.unknown())';
214
+ case 'enum':
215
+ if (col.values?.length) {
216
+ const vals = col.values.map((v) => `'${v}'`).join(', ');
217
+ return `z.enum([${vals}])`;
218
+ }
219
+ return 'z.string()';
220
+ default:
221
+ return 'z.string()';
222
+ }
223
+ }
224
+ camelCase(str) {
225
+ return str.replace(/[-_](.)/g, (_, c) => c.toUpperCase());
226
+ }
227
+ }
228
+ exports.ResourceDefinitionGenerator = ResourceDefinitionGenerator;
229
+ //# sourceMappingURL=resource-definition-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-definition-generator.js","sourceRoot":"","sources":["../../../src/blueprint/generators/resource-definition-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { Blueprint } from '../blueprint-parser';
2
+ /**
3
+ * Generates a TypeScript seeder file for a Blueprint resource.
4
+ *
5
+ * The generated file exports an async `seed` function that creates a small
6
+ * number of sample rows via the Prisma client.
7
+ *
8
+ * Design decisions:
9
+ * - We generate 3 sample rows with slightly varied data.
10
+ * - `organizationId` defaults to 1 when `belongs_to_organization` is true.
11
+ * - The seeder is a plain async function — not a NestJS service — so it can
12
+ * be run standalone via `ts-node src/seeders/<Model>Seeder.ts`.
13
+ */
14
+ export declare class SeederGenerator {
15
+ generate(blueprint: Blueprint): string;
16
+ private buildRow;
17
+ private sampleValue;
18
+ private humanize;
19
+ private formatObject;
20
+ private camelCase;
21
+ }
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SeederGenerator = void 0;
4
+ // ---------------------------------------------------------------------------
5
+ // SeederGenerator
6
+ // ---------------------------------------------------------------------------
7
+ /**
8
+ * Generates a TypeScript seeder file for a Blueprint resource.
9
+ *
10
+ * The generated file exports an async `seed` function that creates a small
11
+ * number of sample rows via the Prisma client.
12
+ *
13
+ * Design decisions:
14
+ * - We generate 3 sample rows with slightly varied data.
15
+ * - `organizationId` defaults to 1 when `belongs_to_organization` is true.
16
+ * - The seeder is a plain async function — not a NestJS service — so it can
17
+ * be run standalone via `ts-node src/seeders/<Model>Seeder.ts`.
18
+ */
19
+ class SeederGenerator {
20
+ generate(blueprint) {
21
+ const { model, options, columns } = blueprint;
22
+ const prismaModel = this.camelCase(model);
23
+ const lines = [];
24
+ lines.push(`// Generated by Rhino Blueprint — do not edit directly.`);
25
+ lines.push(`// Source: .rhino/blueprints/${blueprint.source_file}`);
26
+ lines.push(`import { PrismaClient } from '@prisma/client';`);
27
+ lines.push(``);
28
+ lines.push(`const prisma = new PrismaClient();`);
29
+ lines.push(``);
30
+ lines.push(`/**`);
31
+ lines.push(` * Seed sample ${model} rows.`);
32
+ lines.push(` * Run: npx ts-node src/seeders/${model}Seeder.ts`);
33
+ lines.push(` */`);
34
+ lines.push(`export async function seed(): Promise<void> {`);
35
+ lines.push(` console.log('Seeding ${model}...');`);
36
+ lines.push(``);
37
+ const rows = [1, 2, 3].map((i) => this.buildRow(blueprint, i));
38
+ for (let i = 0; i < rows.length; i++) {
39
+ lines.push(` await prisma.${prismaModel}.upsert({`);
40
+ // BP-005: UUID-PK models need string ids, not integer ids.
41
+ if (blueprint.options.has_uuid) {
42
+ const uuid = `00000000-0000-0000-0000-00000000000${i + 1}`;
43
+ lines.push(` where: { id: '${uuid}' },`);
44
+ }
45
+ else {
46
+ lines.push(` where: { id: ${i + 1} },`);
47
+ }
48
+ lines.push(` update: {},`);
49
+ lines.push(` create: ${this.formatObject(rows[i], 4)},`);
50
+ lines.push(` });`);
51
+ lines.push(``);
52
+ }
53
+ lines.push(` console.log('✓ ${model} seeded (${rows.length} rows)');`);
54
+ lines.push(`}`);
55
+ lines.push(``);
56
+ lines.push(`// Allow running directly`);
57
+ lines.push(`if (require.main === module) {`);
58
+ lines.push(` seed()`);
59
+ lines.push(` .catch(console.error)`);
60
+ lines.push(` .finally(() => prisma.$disconnect());`);
61
+ lines.push(`}`);
62
+ lines.push(``);
63
+ return lines.join('\n');
64
+ }
65
+ // -------------------------------------------------------------------------
66
+ // Private helpers
67
+ // -------------------------------------------------------------------------
68
+ buildRow(blueprint, index) {
69
+ // BP-005: UUID-PK models use deterministic UUID strings so seed is
70
+ // idempotent (upsert where id:'00...001' etc.).
71
+ const id = blueprint.options.has_uuid
72
+ ? `00000000-0000-0000-0000-00000000000${index}`
73
+ : index;
74
+ const row = { id };
75
+ if (blueprint.options.belongs_to_organization) {
76
+ row['organizationId'] = 1;
77
+ }
78
+ for (const col of blueprint.columns) {
79
+ row[col.name] = this.sampleValue(col, index);
80
+ }
81
+ return row;
82
+ }
83
+ sampleValue(col, index) {
84
+ if (col.default !== null && col.default !== undefined) {
85
+ // Use default when available
86
+ return col.default;
87
+ }
88
+ switch (col.type) {
89
+ case 'string':
90
+ return `Sample ${this.humanize(col.name)} ${index}`;
91
+ case 'text':
92
+ return `Sample ${this.humanize(col.name)} content for row ${index}.`;
93
+ case 'integer':
94
+ case 'bigInteger':
95
+ return index * 10;
96
+ case 'foreignId':
97
+ return 1; // reference first record
98
+ case 'float':
99
+ case 'decimal':
100
+ return parseFloat((index * 9.99).toFixed(2));
101
+ case 'boolean':
102
+ return index % 2 === 1;
103
+ case 'date':
104
+ case 'datetime':
105
+ case 'timestamp':
106
+ return new Date(`2024-0${index}-01T00:00:00Z`).toISOString();
107
+ case 'json':
108
+ return { sample: true, index };
109
+ case 'uuid':
110
+ return `00000000-0000-0000-0000-00000000000${index}`;
111
+ case 'enum':
112
+ return col.values?.[0] ?? 'draft';
113
+ default:
114
+ return `value_${index}`;
115
+ }
116
+ }
117
+ humanize(name) {
118
+ return name.replace(/[_-]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
119
+ }
120
+ formatObject(obj, indent) {
121
+ const pad = ' '.repeat(indent);
122
+ const innerPad = ' '.repeat(indent + 2);
123
+ const entries = Object.entries(obj).map(([k, v]) => {
124
+ const val = JSON.stringify(v);
125
+ return `${innerPad}${k}: ${val}`;
126
+ });
127
+ return `{\n${entries.join(',\n')},\n${pad}}`;
128
+ }
129
+ camelCase(str) {
130
+ const pascal = str.replace(/[-_](.)/g, (_, c) => c.toUpperCase());
131
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
132
+ }
133
+ }
134
+ exports.SeederGenerator = SeederGenerator;
135
+ //# sourceMappingURL=seeder-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seeder-generator.js","sourceRoot":"","sources":["../../../src/blueprint/generators/seeder-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { Blueprint } from '../blueprint-parser';
2
+ /**
3
+ * Generates a Jest spec for a blueprint resource.
4
+ *
5
+ * Produces a self-contained file using the library's `buildEnv` helper, which
6
+ * the library ships under `test/helpers/make-controller.ts`. Consumer apps
7
+ * can copy that helper into their own test tree or replace the import path
8
+ * with their own equivalent — a comment in the generated file explains how.
9
+ *
10
+ * Tests produced:
11
+ * 1. CRUD happy-path (index / show / store / update / destroy)
12
+ * 2. 403 when a restricted role attempts a write action
13
+ * 3. 404 for cross-tenant access (when `belongs_to_organization: true`)
14
+ *
15
+ * Controller invocation uses the real `GlobalController` public method
16
+ * signatures: `index(modelSlug, query, req)`, `show(modelSlug, id, query, req)`,
17
+ * `store(modelSlug, body, req)`, `update(modelSlug, id, body, req)`,
18
+ * `destroy(modelSlug, id, req)`.
19
+ */
20
+ export declare class TestGenerator {
21
+ generate(blueprint: Blueprint): string;
22
+ private permissionsFor;
23
+ private buildSampleRow;
24
+ private buildCreatePayload;
25
+ private buildUpdatePayload;
26
+ private sampleValue;
27
+ private camelCase;
28
+ }