@barissozen/csns 0.7.6 → 0.7.7
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/dist/orchestrator/entity-detector.d.ts +52 -0
- package/dist/orchestrator/entity-detector.d.ts.map +1 -0
- package/dist/orchestrator/entity-detector.js +297 -0
- package/dist/orchestrator/entity-detector.js.map +1 -0
- package/dist/orchestrator/index.d.ts +2 -0
- package/dist/orchestrator/index.d.ts.map +1 -1
- package/dist/orchestrator/index.js +2 -0
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/smart-scaffold.d.ts +36 -0
- package/dist/orchestrator/smart-scaffold.d.ts.map +1 -0
- package/dist/orchestrator/smart-scaffold.js +438 -0
- package/dist/orchestrator/smart-scaffold.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity Detector — Brief'ten Entity, Relation, Endpoint Çıkarma
|
|
3
|
+
*
|
|
4
|
+
* "Todo app with users, projects, and tasks. Users can share projects."
|
|
5
|
+
* →
|
|
6
|
+
* entities: [User, Project, Task]
|
|
7
|
+
* relations: [User↔Project (many-to-many), Project→Task (one-to-many)]
|
|
8
|
+
* endpoints: [CRUD for each + share endpoint]
|
|
9
|
+
*/
|
|
10
|
+
export interface DetectedEntity {
|
|
11
|
+
name: string;
|
|
12
|
+
slug: string;
|
|
13
|
+
pluralSlug: string;
|
|
14
|
+
fields: EntityField[];
|
|
15
|
+
isAuthEntity: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface EntityField {
|
|
18
|
+
name: string;
|
|
19
|
+
type: 'string' | 'number' | 'boolean' | 'date' | 'json' | 'reference';
|
|
20
|
+
required: boolean;
|
|
21
|
+
reference?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface DetectedRelation {
|
|
24
|
+
from: string;
|
|
25
|
+
to: string;
|
|
26
|
+
type: 'one-to-many' | 'many-to-many' | 'one-to-one';
|
|
27
|
+
throughField?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface DetectedEndpoints {
|
|
30
|
+
entity: string;
|
|
31
|
+
routes: Array<{
|
|
32
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
33
|
+
path: string;
|
|
34
|
+
description: string;
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
export interface EntityDetectionResult {
|
|
38
|
+
entities: DetectedEntity[];
|
|
39
|
+
relations: DetectedRelation[];
|
|
40
|
+
endpoints: DetectedEndpoints[];
|
|
41
|
+
}
|
|
42
|
+
export declare class EntityDetector {
|
|
43
|
+
/**
|
|
44
|
+
* Detect entities, relations, and endpoints from a brief description.
|
|
45
|
+
*/
|
|
46
|
+
detect(brief: string): EntityDetectionResult;
|
|
47
|
+
private detectRelations;
|
|
48
|
+
private generateEndpoints;
|
|
49
|
+
private matchEntityName;
|
|
50
|
+
private pluralize;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=entity-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-detector.d.ts","sourceRoot":"","sources":["../../src/orchestrator/entity-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;IACtE,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,GAAG,cAAc,GAAG,YAAY,CAAC;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,KAAK,CAAC;QACZ,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;QAC1C,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,SAAS,EAAE,iBAAiB,EAAE,CAAC;CAChC;AAuJD,qBAAa,cAAc;IAEzB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,qBAAqB;IAuE5C,OAAO,CAAC,eAAe;IAmCvB,OAAO,CAAC,iBAAiB;IAqDzB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,SAAS;CAKlB"}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity Detector — Brief'ten Entity, Relation, Endpoint Çıkarma
|
|
3
|
+
*
|
|
4
|
+
* "Todo app with users, projects, and tasks. Users can share projects."
|
|
5
|
+
* →
|
|
6
|
+
* entities: [User, Project, Task]
|
|
7
|
+
* relations: [User↔Project (many-to-many), Project→Task (one-to-many)]
|
|
8
|
+
* endpoints: [CRUD for each + share endpoint]
|
|
9
|
+
*/
|
|
10
|
+
// ═══════════════════════════════════════════════════════════
|
|
11
|
+
// Keyword → Entity Patterns
|
|
12
|
+
// ═══════════════════════════════════════════════════════════
|
|
13
|
+
/** Common nouns that indicate entities */
|
|
14
|
+
const ENTITY_PATTERNS = [
|
|
15
|
+
{
|
|
16
|
+
keywords: ['user', 'users', 'account', 'accounts', 'member', 'members', 'person', 'people'],
|
|
17
|
+
name: 'User',
|
|
18
|
+
fields: [
|
|
19
|
+
{ name: 'email', type: 'string', required: true },
|
|
20
|
+
{ name: 'name', type: 'string', required: true },
|
|
21
|
+
{ name: 'password', type: 'string', required: true },
|
|
22
|
+
{ name: 'role', type: 'string', required: false },
|
|
23
|
+
],
|
|
24
|
+
isAuth: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
keywords: ['todo', 'todos', 'task', 'tasks', 'item', 'items'],
|
|
28
|
+
name: 'Task',
|
|
29
|
+
fields: [
|
|
30
|
+
{ name: 'title', type: 'string', required: true },
|
|
31
|
+
{ name: 'description', type: 'string', required: false },
|
|
32
|
+
{ name: 'completed', type: 'boolean', required: false },
|
|
33
|
+
{ name: 'dueDate', type: 'date', required: false },
|
|
34
|
+
],
|
|
35
|
+
isAuth: false,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
keywords: ['project', 'projects', 'workspace', 'workspaces', 'board', 'boards'],
|
|
39
|
+
name: 'Project',
|
|
40
|
+
fields: [
|
|
41
|
+
{ name: 'name', type: 'string', required: true },
|
|
42
|
+
{ name: 'description', type: 'string', required: false },
|
|
43
|
+
],
|
|
44
|
+
isAuth: false,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
keywords: ['post', 'posts', 'article', 'articles', 'blog', 'entry', 'entries'],
|
|
48
|
+
name: 'Post',
|
|
49
|
+
fields: [
|
|
50
|
+
{ name: 'title', type: 'string', required: true },
|
|
51
|
+
{ name: 'content', type: 'string', required: true },
|
|
52
|
+
{ name: 'published', type: 'boolean', required: false },
|
|
53
|
+
{ name: 'publishedAt', type: 'date', required: false },
|
|
54
|
+
],
|
|
55
|
+
isAuth: false,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
keywords: ['comment', 'comments', 'reply', 'replies'],
|
|
59
|
+
name: 'Comment',
|
|
60
|
+
fields: [
|
|
61
|
+
{ name: 'content', type: 'string', required: true },
|
|
62
|
+
],
|
|
63
|
+
isAuth: false,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
keywords: ['product', 'products', 'listing', 'listings'],
|
|
67
|
+
name: 'Product',
|
|
68
|
+
fields: [
|
|
69
|
+
{ name: 'name', type: 'string', required: true },
|
|
70
|
+
{ name: 'description', type: 'string', required: false },
|
|
71
|
+
{ name: 'price', type: 'number', required: true },
|
|
72
|
+
{ name: 'stock', type: 'number', required: false },
|
|
73
|
+
],
|
|
74
|
+
isAuth: false,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
keywords: ['order', 'orders', 'purchase', 'purchases'],
|
|
78
|
+
name: 'Order',
|
|
79
|
+
fields: [
|
|
80
|
+
{ name: 'status', type: 'string', required: true },
|
|
81
|
+
{ name: 'total', type: 'number', required: true },
|
|
82
|
+
],
|
|
83
|
+
isAuth: false,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
keywords: ['category', 'categories', 'tag', 'tags', 'label', 'labels'],
|
|
87
|
+
name: 'Category',
|
|
88
|
+
fields: [
|
|
89
|
+
{ name: 'name', type: 'string', required: true },
|
|
90
|
+
{ name: 'slug', type: 'string', required: false },
|
|
91
|
+
],
|
|
92
|
+
isAuth: false,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
keywords: ['message', 'messages', 'chat', 'conversation', 'conversations'],
|
|
96
|
+
name: 'Message',
|
|
97
|
+
fields: [
|
|
98
|
+
{ name: 'content', type: 'string', required: true },
|
|
99
|
+
{ name: 'read', type: 'boolean', required: false },
|
|
100
|
+
],
|
|
101
|
+
isAuth: false,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
keywords: ['notification', 'notifications', 'alert', 'alerts'],
|
|
105
|
+
name: 'Notification',
|
|
106
|
+
fields: [
|
|
107
|
+
{ name: 'title', type: 'string', required: true },
|
|
108
|
+
{ name: 'message', type: 'string', required: true },
|
|
109
|
+
{ name: 'read', type: 'boolean', required: false },
|
|
110
|
+
],
|
|
111
|
+
isAuth: false,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
keywords: ['file', 'files', 'upload', 'uploads', 'attachment', 'attachments', 'image', 'images'],
|
|
115
|
+
name: 'File',
|
|
116
|
+
fields: [
|
|
117
|
+
{ name: 'filename', type: 'string', required: true },
|
|
118
|
+
{ name: 'url', type: 'string', required: true },
|
|
119
|
+
{ name: 'size', type: 'number', required: false },
|
|
120
|
+
{ name: 'mimeType', type: 'string', required: false },
|
|
121
|
+
],
|
|
122
|
+
isAuth: false,
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
keywords: ['link', 'links', 'url', 'urls', 'shortener', 'redirect'],
|
|
126
|
+
name: 'Link',
|
|
127
|
+
fields: [
|
|
128
|
+
{ name: 'originalUrl', type: 'string', required: true },
|
|
129
|
+
{ name: 'shortCode', type: 'string', required: true },
|
|
130
|
+
{ name: 'clicks', type: 'number', required: false },
|
|
131
|
+
{ name: 'expiresAt', type: 'date', required: false },
|
|
132
|
+
],
|
|
133
|
+
isAuth: false,
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
/** Relation detection patterns */
|
|
137
|
+
const RELATION_PATTERNS = [
|
|
138
|
+
{ pattern: /(\w+)\s+(?:can\s+)?(?:have|has|contain|own|create)\s+(?:many|multiple|several)\s+(\w+)/i, type: 'one-to-many' },
|
|
139
|
+
{ pattern: /(\w+)\s+(?:belong|assigned)\s+to\s+(?:a|one|an)\s+(\w+)/i, type: 'one-to-many' },
|
|
140
|
+
{ pattern: /(\w+)\s+(?:can\s+)?(?:share|join|belong\s+to\s+many|participate)\s+(\w+)/i, type: 'many-to-many' },
|
|
141
|
+
{ pattern: /(\w+)\s+and\s+(\w+)\s+(?:can\s+)?(?:share|collaborate)/i, type: 'many-to-many' },
|
|
142
|
+
{ pattern: /each\s+(\w+)\s+has\s+(?:one|a|an)\s+(\w+)/i, type: 'one-to-one' },
|
|
143
|
+
];
|
|
144
|
+
// ═══════════════════════════════════════════════════════════
|
|
145
|
+
// Detector
|
|
146
|
+
// ═══════════════════════════════════════════════════════════
|
|
147
|
+
export class EntityDetector {
|
|
148
|
+
/**
|
|
149
|
+
* Detect entities, relations, and endpoints from a brief description.
|
|
150
|
+
*/
|
|
151
|
+
detect(brief) {
|
|
152
|
+
const briefLower = brief.toLowerCase();
|
|
153
|
+
const words = briefLower.split(/[\s,.;:!?/\\()\[\]{}"'`—–-]+/).filter(w => w.length > 1);
|
|
154
|
+
// 1. Detect entities
|
|
155
|
+
const entities = [];
|
|
156
|
+
const entityNames = new Set();
|
|
157
|
+
for (const pattern of ENTITY_PATTERNS) {
|
|
158
|
+
const found = pattern.keywords.some(kw => words.includes(kw) || briefLower.includes(kw));
|
|
159
|
+
if (found && !entityNames.has(pattern.name)) {
|
|
160
|
+
entityNames.add(pattern.name);
|
|
161
|
+
entities.push({
|
|
162
|
+
name: pattern.name,
|
|
163
|
+
slug: pattern.name.toLowerCase(),
|
|
164
|
+
pluralSlug: this.pluralize(pattern.name.toLowerCase()),
|
|
165
|
+
fields: [...pattern.fields],
|
|
166
|
+
isAuthEntity: pattern.isAuth,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// If no entities detected, create a generic "Resource"
|
|
171
|
+
if (entities.length === 0) {
|
|
172
|
+
entities.push({
|
|
173
|
+
name: 'Resource',
|
|
174
|
+
slug: 'resource',
|
|
175
|
+
pluralSlug: 'resources',
|
|
176
|
+
fields: [
|
|
177
|
+
{ name: 'name', type: 'string', required: true },
|
|
178
|
+
{ name: 'description', type: 'string', required: false },
|
|
179
|
+
],
|
|
180
|
+
isAuthEntity: false,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
// 2. Detect relations
|
|
184
|
+
const relations = this.detectRelations(brief, entities);
|
|
185
|
+
// 3. Add ownership relations (User → everything, if User exists)
|
|
186
|
+
const userEntity = entities.find(e => e.isAuthEntity);
|
|
187
|
+
if (userEntity) {
|
|
188
|
+
for (const entity of entities) {
|
|
189
|
+
if (entity.isAuthEntity)
|
|
190
|
+
continue;
|
|
191
|
+
const exists = relations.some(r => (r.from === userEntity.name && r.to === entity.name) ||
|
|
192
|
+
(r.from === entity.name && r.to === userEntity.name));
|
|
193
|
+
if (!exists) {
|
|
194
|
+
relations.push({
|
|
195
|
+
from: userEntity.name,
|
|
196
|
+
to: entity.name,
|
|
197
|
+
type: 'one-to-many',
|
|
198
|
+
});
|
|
199
|
+
// Add userId reference field
|
|
200
|
+
entity.fields.push({
|
|
201
|
+
name: 'userId',
|
|
202
|
+
type: 'reference',
|
|
203
|
+
required: true,
|
|
204
|
+
reference: userEntity.name,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// 4. Generate endpoints
|
|
210
|
+
const endpoints = this.generateEndpoints(entities, relations);
|
|
211
|
+
return { entities, relations, endpoints };
|
|
212
|
+
}
|
|
213
|
+
detectRelations(brief, entities) {
|
|
214
|
+
const relations = [];
|
|
215
|
+
const entityNames = entities.map(e => e.name.toLowerCase());
|
|
216
|
+
for (const rp of RELATION_PATTERNS) {
|
|
217
|
+
const match = brief.match(rp.pattern);
|
|
218
|
+
if (match) {
|
|
219
|
+
const from = this.matchEntityName(match[1] ?? '', entityNames, entities);
|
|
220
|
+
const to = this.matchEntityName(match[2] ?? '', entityNames, entities);
|
|
221
|
+
if (from && to && from !== to) {
|
|
222
|
+
const exists = relations.some(r => r.from === from && r.to === to);
|
|
223
|
+
if (!exists) {
|
|
224
|
+
relations.push({ from, to, type: rp.type });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Detect parent-child from "X's Y" or "Y of X" patterns
|
|
230
|
+
const possessivePattern = /(\w+)(?:'s|s')\s+(\w+)/gi;
|
|
231
|
+
let match;
|
|
232
|
+
while ((match = possessivePattern.exec(brief)) !== null) {
|
|
233
|
+
const from = this.matchEntityName(match[1] ?? '', entityNames, entities);
|
|
234
|
+
const to = this.matchEntityName(match[2] ?? '', entityNames, entities);
|
|
235
|
+
if (from && to && from !== to) {
|
|
236
|
+
const exists = relations.some(r => r.from === from && r.to === to);
|
|
237
|
+
if (!exists) {
|
|
238
|
+
relations.push({ from, to, type: 'one-to-many' });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return relations;
|
|
243
|
+
}
|
|
244
|
+
generateEndpoints(entities, relations) {
|
|
245
|
+
const endpoints = [];
|
|
246
|
+
for (const entity of entities) {
|
|
247
|
+
const routes = [];
|
|
248
|
+
const base = `/${entity.pluralSlug}`;
|
|
249
|
+
if (entity.isAuthEntity) {
|
|
250
|
+
routes.push({ method: 'POST', path: '/auth/register', description: `Register new ${entity.slug}` }, { method: 'POST', path: '/auth/login', description: `Login ${entity.slug}` }, { method: 'GET', path: '/auth/me', description: `Get current ${entity.slug}` });
|
|
251
|
+
}
|
|
252
|
+
// CRUD
|
|
253
|
+
routes.push({ method: 'GET', path: base, description: `List all ${entity.pluralSlug}` }, { method: 'GET', path: `${base}/:id`, description: `Get ${entity.slug} by ID` }, { method: 'POST', path: base, description: `Create ${entity.slug}` }, { method: 'PUT', path: `${base}/:id`, description: `Update ${entity.slug}` }, { method: 'DELETE', path: `${base}/:id`, description: `Delete ${entity.slug}` });
|
|
254
|
+
// Relation-based endpoints
|
|
255
|
+
for (const rel of relations) {
|
|
256
|
+
if (rel.from === entity.name) {
|
|
257
|
+
const childEntity = entities.find(e => e.name === rel.to);
|
|
258
|
+
if (childEntity) {
|
|
259
|
+
routes.push({
|
|
260
|
+
method: 'GET',
|
|
261
|
+
path: `${base}/:id/${childEntity.pluralSlug}`,
|
|
262
|
+
description: `List ${childEntity.pluralSlug} for ${entity.slug}`,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (rel.type === 'many-to-many' && rel.to === entity.name) {
|
|
267
|
+
const parentEntity = entities.find(e => e.name === rel.from);
|
|
268
|
+
if (parentEntity) {
|
|
269
|
+
routes.push({ method: 'POST', path: `${base}/:id/${parentEntity.pluralSlug}/:${parentEntity.slug}Id`, description: `Add ${parentEntity.slug} to ${entity.slug}` }, { method: 'DELETE', path: `${base}/:id/${parentEntity.pluralSlug}/:${parentEntity.slug}Id`, description: `Remove ${parentEntity.slug} from ${entity.slug}` });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
endpoints.push({ entity: entity.name, routes });
|
|
274
|
+
}
|
|
275
|
+
return endpoints;
|
|
276
|
+
}
|
|
277
|
+
matchEntityName(word, _entityNames, entities) {
|
|
278
|
+
const lower = word.toLowerCase();
|
|
279
|
+
// Direct match
|
|
280
|
+
const direct = entities.find(e => e.slug === lower || e.pluralSlug === lower);
|
|
281
|
+
if (direct)
|
|
282
|
+
return direct.name;
|
|
283
|
+
// Fuzzy — check if word starts with entity name
|
|
284
|
+
const fuzzy = entities.find(e => lower.startsWith(e.slug) || e.slug.startsWith(lower));
|
|
285
|
+
if (fuzzy)
|
|
286
|
+
return fuzzy.name;
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
pluralize(word) {
|
|
290
|
+
if (word.endsWith('y') && !/[aeiou]y$/.test(word))
|
|
291
|
+
return word.slice(0, -1) + 'ies';
|
|
292
|
+
if (word.endsWith('s') || word.endsWith('x') || word.endsWith('z') || word.endsWith('ch') || word.endsWith('sh'))
|
|
293
|
+
return word + 'es';
|
|
294
|
+
return word + 's';
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=entity-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-detector.js","sourceRoot":"","sources":["../../src/orchestrator/entity-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,4 +8,6 @@ export { RecoveryManager } from './recovery.js';
|
|
|
8
8
|
export { IntegrationEvaluator } from './integration-evaluator.js';
|
|
9
9
|
export { AuditGate } from './audit-gate.js';
|
|
10
10
|
export { scaffoldProject } from './scaffold.js';
|
|
11
|
+
export { SmartScaffold } from './smart-scaffold.js';
|
|
12
|
+
export { EntityDetector } from './entity-detector.js';
|
|
11
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/orchestrator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/orchestrator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -8,4 +8,6 @@ export { RecoveryManager } from './recovery.js';
|
|
|
8
8
|
export { IntegrationEvaluator } from './integration-evaluator.js';
|
|
9
9
|
export { AuditGate } from './audit-gate.js';
|
|
10
10
|
export { scaffoldProject } from './scaffold.js';
|
|
11
|
+
export { SmartScaffold } from './smart-scaffold.js';
|
|
12
|
+
export { EntityDetector } from './entity-detector.js';
|
|
11
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/orchestrator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/orchestrator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Scaffold — Brief'ten Multi-Entity Layered Code Generation
|
|
3
|
+
*
|
|
4
|
+
* EntityDetector sonuçlarını alıp her entity için:
|
|
5
|
+
* - Route (Express router + CRUD + relation endpoints)
|
|
6
|
+
* - Service (business logic)
|
|
7
|
+
* - Repository (data access)
|
|
8
|
+
* - Schema (Zod validation)
|
|
9
|
+
* - DB model (Drizzle-style)
|
|
10
|
+
* üretir.
|
|
11
|
+
*/
|
|
12
|
+
import type { EntityDetectionResult } from './entity-detector.js';
|
|
13
|
+
import type { ArchitectureDecisions } from '../types/index.js';
|
|
14
|
+
export interface SmartScaffoldResult {
|
|
15
|
+
files: string[];
|
|
16
|
+
routes: string[];
|
|
17
|
+
entities: string[];
|
|
18
|
+
detection: EntityDetectionResult;
|
|
19
|
+
}
|
|
20
|
+
export declare class SmartScaffold {
|
|
21
|
+
private root;
|
|
22
|
+
private detector;
|
|
23
|
+
constructor(projectRoot: string);
|
|
24
|
+
generate(brief: string, decisions: ArchitectureDecisions): Promise<SmartScaffoldResult>;
|
|
25
|
+
private writeConfig;
|
|
26
|
+
private writeApp;
|
|
27
|
+
private writeServer;
|
|
28
|
+
private writeHealthRoute;
|
|
29
|
+
private writeSchema;
|
|
30
|
+
private writeService;
|
|
31
|
+
private writeRepository;
|
|
32
|
+
private writeRoute;
|
|
33
|
+
private writeAuth;
|
|
34
|
+
private writeModels;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=smart-scaffold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-scaffold.d.ts","sourceRoot":"","sources":["../../src/orchestrator/smart-scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAoC,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,qBAAqB,CAAC;CAClC;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAiB;gBAErB,WAAW,EAAE,MAAM;IAKzB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC;YA4D/E,WAAW;YA4BX,QAAQ;YAyCR,WAAW;YAaX,gBAAgB;YAchB,WAAW;YA8BX,YAAY;YAqDZ,eAAe;YAyCf,UAAU;YA0DV,SAAS;YA+DT,WAAW;CAuC1B"}
|
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Scaffold — Brief'ten Multi-Entity Layered Code Generation
|
|
3
|
+
*
|
|
4
|
+
* EntityDetector sonuçlarını alıp her entity için:
|
|
5
|
+
* - Route (Express router + CRUD + relation endpoints)
|
|
6
|
+
* - Service (business logic)
|
|
7
|
+
* - Repository (data access)
|
|
8
|
+
* - Schema (Zod validation)
|
|
9
|
+
* - DB model (Drizzle-style)
|
|
10
|
+
* üretir.
|
|
11
|
+
*/
|
|
12
|
+
import { writeFile, mkdir } from 'node:fs/promises';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { EntityDetector } from './entity-detector.js';
|
|
15
|
+
export class SmartScaffold {
|
|
16
|
+
root;
|
|
17
|
+
detector;
|
|
18
|
+
constructor(projectRoot) {
|
|
19
|
+
this.root = projectRoot;
|
|
20
|
+
this.detector = new EntityDetector();
|
|
21
|
+
}
|
|
22
|
+
async generate(brief, decisions) {
|
|
23
|
+
const detection = this.detector.detect(brief);
|
|
24
|
+
const files = [];
|
|
25
|
+
const routes = [];
|
|
26
|
+
// Directories
|
|
27
|
+
const dirs = [
|
|
28
|
+
'src', 'src/routes', 'src/services', 'src/middleware',
|
|
29
|
+
'src/config', 'src/schemas', 'src/models', 'tests',
|
|
30
|
+
...(decisions.database !== 'in-memory' ? ['src/repositories'] : []),
|
|
31
|
+
];
|
|
32
|
+
for (const d of dirs)
|
|
33
|
+
await mkdir(join(this.root, d), { recursive: true });
|
|
34
|
+
// Config
|
|
35
|
+
files.push(await this.writeConfig(decisions));
|
|
36
|
+
// App + server
|
|
37
|
+
files.push(await this.writeApp(detection, decisions));
|
|
38
|
+
files.push(await this.writeServer());
|
|
39
|
+
// Health endpoint
|
|
40
|
+
files.push(await this.writeHealthRoute());
|
|
41
|
+
routes.push('GET /health');
|
|
42
|
+
// Auth (if auth entity exists)
|
|
43
|
+
const authEntity = detection.entities.find(e => e.isAuthEntity);
|
|
44
|
+
if (authEntity && decisions.auth !== 'none') {
|
|
45
|
+
files.push(...await this.writeAuth(authEntity, decisions));
|
|
46
|
+
routes.push('POST /auth/register', 'POST /auth/login', 'GET /auth/me');
|
|
47
|
+
}
|
|
48
|
+
// Each entity → route + service + repo + schema
|
|
49
|
+
for (const entity of detection.entities) {
|
|
50
|
+
if (entity.isAuthEntity)
|
|
51
|
+
continue; // auth handled above
|
|
52
|
+
files.push(await this.writeSchema(entity));
|
|
53
|
+
files.push(await this.writeService(entity, decisions));
|
|
54
|
+
if (decisions.database !== 'in-memory') {
|
|
55
|
+
files.push(await this.writeRepository(entity));
|
|
56
|
+
}
|
|
57
|
+
files.push(await this.writeRoute(entity, detection.relations));
|
|
58
|
+
for (const ep of detection.endpoints.find(e => e.entity === entity.name)?.routes ?? []) {
|
|
59
|
+
routes.push(`${ep.method} ${ep.path}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// DB model (all entities in one file)
|
|
63
|
+
files.push(await this.writeModels(detection));
|
|
64
|
+
return {
|
|
65
|
+
files,
|
|
66
|
+
routes,
|
|
67
|
+
entities: detection.entities.map(e => e.name),
|
|
68
|
+
detection,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// ── Generators ──────────────────────────────────────────
|
|
72
|
+
async writeConfig(d) {
|
|
73
|
+
const path = 'src/config/index.ts';
|
|
74
|
+
const content = `import { z } from 'zod';
|
|
75
|
+
|
|
76
|
+
export const envSchema = z.object({
|
|
77
|
+
PORT: z.coerce.number().default(3000),
|
|
78
|
+
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
|
|
79
|
+
${d.database === 'postgresql' ? " DATABASE_URL: z.string().default('postgresql://localhost:5432/app')," : ''}
|
|
80
|
+
${d.database === 'sqlite' ? " DB_PATH: z.string().default('./data.sqlite')," : ''}
|
|
81
|
+
${d.auth === 'jwt' ? " JWT_SECRET: z.string().min(16, 'JWT_SECRET must be at least 16 characters')," : ''}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export type Config = z.infer<typeof envSchema>;
|
|
85
|
+
|
|
86
|
+
// Validate at startup — fail fast
|
|
87
|
+
let _config: Config;
|
|
88
|
+
try {
|
|
89
|
+
_config = envSchema.parse(process.env);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
console.error('❌ Invalid environment configuration:', err);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
export const config = _config;
|
|
95
|
+
`;
|
|
96
|
+
await writeFile(join(this.root, path), content);
|
|
97
|
+
return path;
|
|
98
|
+
}
|
|
99
|
+
async writeApp(det, d) {
|
|
100
|
+
const path = 'src/app.ts';
|
|
101
|
+
const imports = ["import express from 'express';"];
|
|
102
|
+
const mounts = [];
|
|
103
|
+
// Health
|
|
104
|
+
imports.push("import { healthRouter } from './routes/health.js';");
|
|
105
|
+
mounts.push("app.use('/health', healthRouter);");
|
|
106
|
+
// Auth
|
|
107
|
+
const hasAuth = det.entities.some(e => e.isAuthEntity) && d.auth !== 'none';
|
|
108
|
+
if (hasAuth) {
|
|
109
|
+
imports.push("import { authRouter } from './routes/auth.js';");
|
|
110
|
+
imports.push("import { authMiddleware } from './middleware/auth.js';");
|
|
111
|
+
mounts.push("app.use('/auth', authRouter);");
|
|
112
|
+
}
|
|
113
|
+
// Entity routes
|
|
114
|
+
for (const entity of det.entities) {
|
|
115
|
+
if (entity.isAuthEntity)
|
|
116
|
+
continue;
|
|
117
|
+
const varName = `${entity.slug}Router`;
|
|
118
|
+
imports.push(`import { ${varName} } from './routes/${entity.pluralSlug}.js';`);
|
|
119
|
+
if (hasAuth) {
|
|
120
|
+
mounts.push(`app.use('/${entity.pluralSlug}', authMiddleware, ${varName});`);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
mounts.push(`app.use('/${entity.pluralSlug}', ${varName});`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const content = `${imports.join('\n')}
|
|
127
|
+
|
|
128
|
+
export const app = express();
|
|
129
|
+
app.use(express.json());
|
|
130
|
+
|
|
131
|
+
// Routes
|
|
132
|
+
${mounts.join('\n')}
|
|
133
|
+
`;
|
|
134
|
+
await writeFile(join(this.root, path), content);
|
|
135
|
+
return path;
|
|
136
|
+
}
|
|
137
|
+
async writeServer() {
|
|
138
|
+
const path = 'src/server.ts';
|
|
139
|
+
const content = `import { app } from './app.js';
|
|
140
|
+
import { config } from './config/index.js';
|
|
141
|
+
|
|
142
|
+
app.listen(config.PORT, () => {
|
|
143
|
+
console.log(\`Server listening on port \${config.PORT}\`);
|
|
144
|
+
});
|
|
145
|
+
`;
|
|
146
|
+
await writeFile(join(this.root, path), content);
|
|
147
|
+
return path;
|
|
148
|
+
}
|
|
149
|
+
async writeHealthRoute() {
|
|
150
|
+
const path = 'src/routes/health.ts';
|
|
151
|
+
const content = `import { Router } from 'express';
|
|
152
|
+
|
|
153
|
+
export const healthRouter = Router();
|
|
154
|
+
|
|
155
|
+
healthRouter.get('/', (_req, res) => {
|
|
156
|
+
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
157
|
+
});
|
|
158
|
+
`;
|
|
159
|
+
await writeFile(join(this.root, path), content);
|
|
160
|
+
return path;
|
|
161
|
+
}
|
|
162
|
+
async writeSchema(entity) {
|
|
163
|
+
const path = `src/schemas/${entity.slug}.ts`;
|
|
164
|
+
const fields = entity.fields
|
|
165
|
+
.filter(f => f.name !== 'userId') // userId comes from auth
|
|
166
|
+
.map(f => {
|
|
167
|
+
let zodType = 'z.string()';
|
|
168
|
+
if (f.type === 'number')
|
|
169
|
+
zodType = 'z.number()';
|
|
170
|
+
else if (f.type === 'boolean')
|
|
171
|
+
zodType = 'z.boolean().default(false)';
|
|
172
|
+
else if (f.type === 'date')
|
|
173
|
+
zodType = 'z.string().datetime().optional()';
|
|
174
|
+
else if (f.type === 'reference')
|
|
175
|
+
zodType = 'z.string().uuid()';
|
|
176
|
+
if (!f.required && f.type !== 'boolean' && f.type !== 'date')
|
|
177
|
+
zodType += '.optional()';
|
|
178
|
+
return ` ${f.name}: ${zodType},`;
|
|
179
|
+
})
|
|
180
|
+
.join('\n');
|
|
181
|
+
const content = `import { z } from 'zod';
|
|
182
|
+
|
|
183
|
+
export const create${entity.name}Schema = z.object({
|
|
184
|
+
${fields}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
export const update${entity.name}Schema = create${entity.name}Schema.partial();
|
|
188
|
+
|
|
189
|
+
export type Create${entity.name}Input = z.infer<typeof create${entity.name}Schema>;
|
|
190
|
+
export type Update${entity.name}Input = z.infer<typeof update${entity.name}Schema>;
|
|
191
|
+
`;
|
|
192
|
+
await writeFile(join(this.root, path), content);
|
|
193
|
+
return path;
|
|
194
|
+
}
|
|
195
|
+
async writeService(entity, d) {
|
|
196
|
+
const path = `src/services/${entity.slug}-service.ts`;
|
|
197
|
+
const usesRepo = d.database !== 'in-memory';
|
|
198
|
+
const E = entity.name;
|
|
199
|
+
const items = entity.pluralSlug;
|
|
200
|
+
const content = usesRepo ? `import { ${E}Repository } from '../repositories/${entity.slug}-repo.js';
|
|
201
|
+
import type { Create${E}Input, Update${E}Input } from '../schemas/${entity.slug}.js';
|
|
202
|
+
|
|
203
|
+
export class ${E}Service {
|
|
204
|
+
private repo = new ${E}Repository();
|
|
205
|
+
|
|
206
|
+
findAll(userId?: string) { return this.repo.findAll(userId); }
|
|
207
|
+
findById(id: string) { return this.repo.findById(id); }
|
|
208
|
+
create(data: Create${E}Input, userId?: string) { return this.repo.create({ ...data, userId }); }
|
|
209
|
+
update(id: string, data: Update${E}Input) { return this.repo.update(id, data); }
|
|
210
|
+
delete(id: string) { return this.repo.delete(id); }
|
|
211
|
+
}
|
|
212
|
+
` : `import type { Create${E}Input, Update${E}Input } from '../schemas/${entity.slug}.js';
|
|
213
|
+
|
|
214
|
+
interface ${E} { id: string; [key: string]: unknown; }
|
|
215
|
+
|
|
216
|
+
export class ${E}Service {
|
|
217
|
+
private ${items}: ${E}[] = [];
|
|
218
|
+
private counter = 0;
|
|
219
|
+
|
|
220
|
+
findAll(userId?: string): ${E}[] {
|
|
221
|
+
return userId ? this.${items}.filter(i => i.userId === userId) : this.${items};
|
|
222
|
+
}
|
|
223
|
+
findById(id: string): ${E} | undefined { return this.${items}.find(i => i.id === id); }
|
|
224
|
+
create(data: Create${E}Input & { userId?: string }): ${E} {
|
|
225
|
+
const item: ${E} = { ...data, id: String(++this.counter) };
|
|
226
|
+
this.${items}.push(item);
|
|
227
|
+
return item;
|
|
228
|
+
}
|
|
229
|
+
update(id: string, data: Update${E}Input): ${E} | undefined {
|
|
230
|
+
const idx = this.${items}.findIndex(i => i.id === id);
|
|
231
|
+
if (idx < 0) return undefined;
|
|
232
|
+
this.${items}[idx] = { ...this.${items}[idx]!, ...data, id };
|
|
233
|
+
return this.${items}[idx];
|
|
234
|
+
}
|
|
235
|
+
delete(id: string): boolean {
|
|
236
|
+
const idx = this.${items}.findIndex(i => i.id === id);
|
|
237
|
+
if (idx < 0) return false;
|
|
238
|
+
this.${items}.splice(idx, 1);
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
`;
|
|
243
|
+
await writeFile(join(this.root, path), content);
|
|
244
|
+
return path;
|
|
245
|
+
}
|
|
246
|
+
async writeRepository(entity) {
|
|
247
|
+
const path = `src/repositories/${entity.slug}-repo.ts`;
|
|
248
|
+
const E = entity.name;
|
|
249
|
+
const content = `/**
|
|
250
|
+
* ${E} Repository — data access layer
|
|
251
|
+
* TODO: Replace with real database queries
|
|
252
|
+
*/
|
|
253
|
+
|
|
254
|
+
interface ${E} { id: string; [key: string]: unknown; }
|
|
255
|
+
|
|
256
|
+
export class ${E}Repository {
|
|
257
|
+
private items: ${E}[] = [];
|
|
258
|
+
private counter = 0;
|
|
259
|
+
|
|
260
|
+
findAll(userId?: string): ${E}[] {
|
|
261
|
+
return userId ? this.items.filter(i => i.userId === userId) : this.items;
|
|
262
|
+
}
|
|
263
|
+
findById(id: string): ${E} | undefined { return this.items.find(i => i.id === id); }
|
|
264
|
+
create(data: Record<string, unknown>): ${E} {
|
|
265
|
+
const item = { ...data, id: String(++this.counter) } as ${E};
|
|
266
|
+
this.items.push(item);
|
|
267
|
+
return item;
|
|
268
|
+
}
|
|
269
|
+
update(id: string, data: Record<string, unknown>): ${E} | undefined {
|
|
270
|
+
const idx = this.items.findIndex(i => i.id === id);
|
|
271
|
+
if (idx < 0) return undefined;
|
|
272
|
+
this.items[idx] = { ...this.items[idx]!, ...data, id };
|
|
273
|
+
return this.items[idx];
|
|
274
|
+
}
|
|
275
|
+
delete(id: string): boolean {
|
|
276
|
+
const idx = this.items.findIndex(i => i.id === id);
|
|
277
|
+
if (idx < 0) return false;
|
|
278
|
+
this.items.splice(idx, 1);
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
`;
|
|
283
|
+
await writeFile(join(this.root, path), content);
|
|
284
|
+
return path;
|
|
285
|
+
}
|
|
286
|
+
async writeRoute(entity, _relations) {
|
|
287
|
+
const path = `src/routes/${entity.pluralSlug}.ts`;
|
|
288
|
+
const E = entity.name;
|
|
289
|
+
const service = `${entity.slug}Service`;
|
|
290
|
+
const validation = `create${E}Schema`;
|
|
291
|
+
const updateValidation = `update${E}Schema`;
|
|
292
|
+
let content = `import { Router } from 'express';
|
|
293
|
+
import { ${E}Service } from '../services/${entity.slug}-service.js';
|
|
294
|
+
import { ${validation}, ${updateValidation} } from '../schemas/${entity.slug}.js';
|
|
295
|
+
|
|
296
|
+
export const ${entity.slug}Router = Router();
|
|
297
|
+
const ${service} = new ${E}Service();
|
|
298
|
+
|
|
299
|
+
// GET /${entity.pluralSlug}
|
|
300
|
+
${entity.slug}Router.get('/', (req, res) => {
|
|
301
|
+
const userId = (req as any).userId; // from auth middleware
|
|
302
|
+
const items = ${service}.findAll(userId);
|
|
303
|
+
res.json(items);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// GET /${entity.pluralSlug}/:id
|
|
307
|
+
${entity.slug}Router.get('/:id', (req, res) => {
|
|
308
|
+
const item = ${service}.findById(req.params.id!);
|
|
309
|
+
if (!item) { res.status(404).json({ error: '${E} not found' }); return; }
|
|
310
|
+
res.json(item);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// POST /${entity.pluralSlug}
|
|
314
|
+
${entity.slug}Router.post('/', (req, res) => {
|
|
315
|
+
const parsed = ${validation}.safeParse(req.body);
|
|
316
|
+
if (!parsed.success) { res.status(400).json({ error: parsed.error.flatten() }); return; }
|
|
317
|
+
const userId = (req as any).userId;
|
|
318
|
+
const item = ${service}.create(parsed.data, userId);
|
|
319
|
+
res.status(201).json(item);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// PUT /${entity.pluralSlug}/:id
|
|
323
|
+
${entity.slug}Router.put('/:id', (req, res) => {
|
|
324
|
+
const parsed = ${updateValidation}.safeParse(req.body);
|
|
325
|
+
if (!parsed.success) { res.status(400).json({ error: parsed.error.flatten() }); return; }
|
|
326
|
+
const item = ${service}.update(req.params.id!, parsed.data);
|
|
327
|
+
if (!item) { res.status(404).json({ error: '${E} not found' }); return; }
|
|
328
|
+
res.json(item);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// DELETE /${entity.pluralSlug}/:id
|
|
332
|
+
${entity.slug}Router.delete('/:id', (req, res) => {
|
|
333
|
+
const ok = ${service}.delete(req.params.id!);
|
|
334
|
+
if (!ok) { res.status(404).json({ error: '${E} not found' }); return; }
|
|
335
|
+
res.status(204).end();
|
|
336
|
+
});
|
|
337
|
+
`;
|
|
338
|
+
await writeFile(join(this.root, path), content);
|
|
339
|
+
return path;
|
|
340
|
+
}
|
|
341
|
+
async writeAuth(_entity, _d) {
|
|
342
|
+
const files = [];
|
|
343
|
+
// Auth route
|
|
344
|
+
const routeContent = `import { Router } from 'express';
|
|
345
|
+
import { z } from 'zod';
|
|
346
|
+
|
|
347
|
+
export const authRouter = Router();
|
|
348
|
+
|
|
349
|
+
const registerSchema = z.object({
|
|
350
|
+
email: z.string().email(),
|
|
351
|
+
password: z.string().min(8),
|
|
352
|
+
name: z.string().min(1),
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
const loginSchema = z.object({
|
|
356
|
+
email: z.string().email(),
|
|
357
|
+
password: z.string(),
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// In-memory store (replace with real DB)
|
|
361
|
+
const users: Array<{ id: string; email: string; password: string; name: string }> = [];
|
|
362
|
+
let counter = 0;
|
|
363
|
+
|
|
364
|
+
authRouter.post('/register', (req, res) => {
|
|
365
|
+
const parsed = registerSchema.safeParse(req.body);
|
|
366
|
+
if (!parsed.success) { res.status(400).json({ error: parsed.error.flatten() }); return; }
|
|
367
|
+
const exists = users.find(u => u.email === parsed.data.email);
|
|
368
|
+
if (exists) { res.status(409).json({ error: 'Email already registered' }); return; }
|
|
369
|
+
const user = { id: String(++counter), ...parsed.data };
|
|
370
|
+
users.push(user);
|
|
371
|
+
res.status(201).json({ id: user.id, email: user.email, name: user.name });
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
authRouter.post('/login', (req, res) => {
|
|
375
|
+
const parsed = loginSchema.safeParse(req.body);
|
|
376
|
+
if (!parsed.success) { res.status(400).json({ error: parsed.error.flatten() }); return; }
|
|
377
|
+
const user = users.find(u => u.email === parsed.data.email && u.password === parsed.data.password);
|
|
378
|
+
if (!user) { res.status(401).json({ error: 'Invalid credentials' }); return; }
|
|
379
|
+
res.json({ token: \`token-\${user.id}-\${Date.now()}\`, userId: user.id });
|
|
380
|
+
});
|
|
381
|
+
`;
|
|
382
|
+
await writeFile(join(this.root, 'src/routes/auth.ts'), routeContent);
|
|
383
|
+
files.push('src/routes/auth.ts');
|
|
384
|
+
// Auth middleware
|
|
385
|
+
const middlewareContent = `import type { Request, Response, NextFunction } from 'express';
|
|
386
|
+
|
|
387
|
+
export function authMiddleware(req: Request, res: Response, next: NextFunction): void {
|
|
388
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
|
389
|
+
if (!token) { res.status(401).json({ error: 'Authentication required' }); return; }
|
|
390
|
+
// TODO: Validate token properly (JWT verify)
|
|
391
|
+
const userId = token.split('-')[1]; // extract from token-{userId}-{timestamp}
|
|
392
|
+
(req as any).userId = userId;
|
|
393
|
+
next();
|
|
394
|
+
}
|
|
395
|
+
`;
|
|
396
|
+
await writeFile(join(this.root, 'src/middleware/auth.ts'), middlewareContent);
|
|
397
|
+
files.push('src/middleware/auth.ts');
|
|
398
|
+
return files;
|
|
399
|
+
}
|
|
400
|
+
async writeModels(det) {
|
|
401
|
+
const path = 'src/models/schema.ts';
|
|
402
|
+
const tables = det.entities.map(entity => {
|
|
403
|
+
const fields = entity.fields.map(f => {
|
|
404
|
+
const colType = f.type === 'number' ? 'integer' :
|
|
405
|
+
f.type === 'boolean' ? 'boolean' :
|
|
406
|
+
f.type === 'date' ? 'timestamp' :
|
|
407
|
+
f.type === 'reference' ? `text /* FK → ${f.reference} */` :
|
|
408
|
+
'text';
|
|
409
|
+
return ` ${f.name}: ${colType}('${f.name}')${f.required ? '.notNull()' : ''},`;
|
|
410
|
+
}).join('\n');
|
|
411
|
+
return `// ${entity.name}
|
|
412
|
+
export const ${entity.pluralSlug} = {
|
|
413
|
+
tableName: '${entity.pluralSlug}',
|
|
414
|
+
columns: {
|
|
415
|
+
id: 'text("id").primaryKey()',
|
|
416
|
+
${fields}
|
|
417
|
+
createdAt: 'timestamp("created_at").defaultNow()',
|
|
418
|
+
updatedAt: 'timestamp("updated_at").defaultNow()',
|
|
419
|
+
},
|
|
420
|
+
};`;
|
|
421
|
+
}).join('\n\n');
|
|
422
|
+
const relSummary = det.relations.map(r => r.from + ' → ' + r.to + ' (' + r.type + ')').join(', ') || 'none';
|
|
423
|
+
const entitySummary = det.entities.map(e => e.name).join(', ');
|
|
424
|
+
const content = `/**
|
|
425
|
+
* Database Schema — All entities
|
|
426
|
+
* Generated by CSNS Smart Scaffold
|
|
427
|
+
*
|
|
428
|
+
* Entities: ${entitySummary}
|
|
429
|
+
* Relations: ${relSummary}
|
|
430
|
+
*/
|
|
431
|
+
|
|
432
|
+
${tables}
|
|
433
|
+
`;
|
|
434
|
+
await writeFile(join(this.root, path), content);
|
|
435
|
+
return path;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
//# sourceMappingURL=smart-scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-scaffold.js","sourceRoot":"","sources":["../../src/orchestrator/smart-scaffold.ts"],"names":[],"mappings":"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"}
|