db-model-router 1.0.19 → 1.0.21
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/dbmr.schema.mysql.json +360 -0
- package/package.json +3 -1
- package/scripts/demo-create.js +11 -5
- package/src/cli/commands/generate.js +18 -9
- package/src/cli/commands/init.js +8 -4
- package/src/cli/diff-engine.js +5 -1
- package/src/cli/init/generators.js +9 -1
- package/src/mysql/db.js +6 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adapter": "mysql",
|
|
3
|
+
"framework": "express",
|
|
4
|
+
"options": {
|
|
5
|
+
"session": "memory",
|
|
6
|
+
"rateLimiting": true,
|
|
7
|
+
"helmet": true,
|
|
8
|
+
"logger": true,
|
|
9
|
+
"loki": false,
|
|
10
|
+
"saasStructure": false,
|
|
11
|
+
"apiBasePath": "/api",
|
|
12
|
+
"output": "backend",
|
|
13
|
+
"port": 6000
|
|
14
|
+
},
|
|
15
|
+
"tables": {
|
|
16
|
+
"languages": {
|
|
17
|
+
"columns": {
|
|
18
|
+
"language_id": "auto_increment",
|
|
19
|
+
"name": "required|string|maxLength:100",
|
|
20
|
+
"slug": "required|string|regex:^[a-z0-9-]+$|maxLength:100",
|
|
21
|
+
"file_extension": "required|string|maxLength:20",
|
|
22
|
+
"runtime_family": "string|maxLength:50",
|
|
23
|
+
"package_registry": "string|maxLength:50",
|
|
24
|
+
"is_active": "boolean",
|
|
25
|
+
"created_at": "datetime"
|
|
26
|
+
},
|
|
27
|
+
"pk": "language_id",
|
|
28
|
+
"unique": ["slug"],
|
|
29
|
+
"timestamps": {
|
|
30
|
+
"created_at": "created_at"
|
|
31
|
+
},
|
|
32
|
+
"parent": null
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
"frameworks": {
|
|
36
|
+
"columns": {
|
|
37
|
+
"framework_id": "auto_increment",
|
|
38
|
+
"language_id": "required|integer:unsigned",
|
|
39
|
+
"name": "required|string|maxLength:150",
|
|
40
|
+
"slug": "required|string|regex:^[a-z0-9-]+$|maxLength:150",
|
|
41
|
+
"package_name": "string|maxLength:150",
|
|
42
|
+
"homepage_url": "string|maxLength:500",
|
|
43
|
+
"latest_version": "string|maxLength:50",
|
|
44
|
+
"weekly_downloads": "integer:unsigned",
|
|
45
|
+
"popularity_index": "numeric:decimal(5,2)",
|
|
46
|
+
"popularity_updated_at": "datetime",
|
|
47
|
+
"created_at": "datetime"
|
|
48
|
+
},
|
|
49
|
+
"pk": "framework_id",
|
|
50
|
+
"unique": ["slug"],
|
|
51
|
+
"search_columns": ["name", "package_name"],
|
|
52
|
+
"timestamps": {
|
|
53
|
+
"created_at": "created_at"
|
|
54
|
+
},
|
|
55
|
+
"parent": null
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
"libraries": {
|
|
59
|
+
"columns": {
|
|
60
|
+
"library_id": "auto_increment",
|
|
61
|
+
"language_id": "required|integer:unsigned",
|
|
62
|
+
"framework_id": "integer:unsigned",
|
|
63
|
+
"name": "required|string|maxLength:150",
|
|
64
|
+
"slug": "required|string|regex:^[a-z0-9-]+$|maxLength:150",
|
|
65
|
+
"package_name": "string|maxLength:150",
|
|
66
|
+
"homepage_url": "string|maxLength:500",
|
|
67
|
+
"latest_version": "string|maxLength:50",
|
|
68
|
+
"weekly_downloads": "integer:unsigned",
|
|
69
|
+
"popularity_index": "numeric:decimal(5,2)",
|
|
70
|
+
"popularity_updated_at": "datetime",
|
|
71
|
+
"created_at": "datetime"
|
|
72
|
+
},
|
|
73
|
+
"pk": "library_id",
|
|
74
|
+
"unique": ["slug"],
|
|
75
|
+
"search_columns": ["name", "package_name"],
|
|
76
|
+
"timestamps": {
|
|
77
|
+
"created_at": "created_at"
|
|
78
|
+
},
|
|
79
|
+
"parent": null
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
"tasks": {
|
|
83
|
+
"columns": {
|
|
84
|
+
"task_id": "auto_increment",
|
|
85
|
+
"name": "required|string|maxLength:150",
|
|
86
|
+
"slug": "required|string|regex:^[a-z0-9-]+$|maxLength:150",
|
|
87
|
+
"category": "required|string|in:auth,storage,networking,data-processing,messaging,payments,caching,middleware,ai-integration,database,validation,integration,utility",
|
|
88
|
+
"description": "string:text",
|
|
89
|
+
"created_at": "datetime"
|
|
90
|
+
},
|
|
91
|
+
"pk": "task_id",
|
|
92
|
+
"unique": ["slug"],
|
|
93
|
+
"search_columns": ["name", "description"],
|
|
94
|
+
"timestamps": {
|
|
95
|
+
"created_at": "created_at"
|
|
96
|
+
},
|
|
97
|
+
"parent": null
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
"tags": {
|
|
101
|
+
"columns": {
|
|
102
|
+
"tag_id": "auto_increment",
|
|
103
|
+
"name": "required|string|maxLength:100",
|
|
104
|
+
"slug": "required|string|regex:^[a-z0-9-]+$|maxLength:100"
|
|
105
|
+
},
|
|
106
|
+
"pk": "tag_id",
|
|
107
|
+
"unique": [["name"], ["slug"]],
|
|
108
|
+
"parent": null
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
"popularity_snapshots": {
|
|
112
|
+
"columns": {
|
|
113
|
+
"snapshot_id": "auto_increment",
|
|
114
|
+
"entity_type": "required|string|in:framework,library",
|
|
115
|
+
"entity_id": "required|integer:unsigned",
|
|
116
|
+
"weekly_downloads": "required|integer:unsigned",
|
|
117
|
+
"source": "string|maxLength:50",
|
|
118
|
+
"snapshot_date": "required|datetime"
|
|
119
|
+
},
|
|
120
|
+
"pk": "snapshot_id",
|
|
121
|
+
"parent": null
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
"sandbox_images": {
|
|
125
|
+
"columns": {
|
|
126
|
+
"image_id": "auto_increment",
|
|
127
|
+
"language_id": "required|integer:unsigned",
|
|
128
|
+
"image_name": "required|string|maxLength:255",
|
|
129
|
+
"os_base": "string|maxLength:100",
|
|
130
|
+
"installed_toolchain": "string:text",
|
|
131
|
+
"is_active": "boolean",
|
|
132
|
+
"created_at": "datetime"
|
|
133
|
+
},
|
|
134
|
+
"pk": "image_id",
|
|
135
|
+
"unique": ["image_name"],
|
|
136
|
+
"timestamps": {
|
|
137
|
+
"created_at": "created_at"
|
|
138
|
+
},
|
|
139
|
+
"parent": null
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
"snippets": {
|
|
143
|
+
"columns": {
|
|
144
|
+
"snippet_id": "required|string:uuid",
|
|
145
|
+
"title": "required|string|maxLength:255",
|
|
146
|
+
"description": "string:text",
|
|
147
|
+
"usecase": "string:text",
|
|
148
|
+
"task_id": "required|integer:unsigned",
|
|
149
|
+
"language_id": "required|integer:unsigned",
|
|
150
|
+
"framework_id": "integer:unsigned",
|
|
151
|
+
"status": "required|string|in:draft,in_verification,verified,failed,deprecated",
|
|
152
|
+
"current_stage": "required|string|in:execution,lint,static_analysis,security_scan,performance,published",
|
|
153
|
+
"verified": "boolean",
|
|
154
|
+
"quality_score": "numeric:decimal(5,2)",
|
|
155
|
+
"source": "required|string|in:ai-generated,human-curated,imported",
|
|
156
|
+
"generation_provider": "string|maxLength:64",
|
|
157
|
+
"generation_model": "string|maxLength:128",
|
|
158
|
+
"enrichment_model": "string|maxLength:128",
|
|
159
|
+
"usage_count": "integer:unsigned",
|
|
160
|
+
"last_tested_at": "datetime",
|
|
161
|
+
"created_at": "datetime",
|
|
162
|
+
"modified_at": "datetime"
|
|
163
|
+
},
|
|
164
|
+
"pk": "snippet_id",
|
|
165
|
+
"search_columns": ["title", "description", "usecase"],
|
|
166
|
+
"timestamps": {
|
|
167
|
+
"created_at": "created_at",
|
|
168
|
+
"modified_at": "modified_at"
|
|
169
|
+
},
|
|
170
|
+
"parent": null
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
"snippet_files": {
|
|
174
|
+
"columns": {
|
|
175
|
+
"file_id": "auto_increment",
|
|
176
|
+
"snippet_id": "required|string:uuid",
|
|
177
|
+
"file_role": "required|string|in:code,test,dependency,readme",
|
|
178
|
+
"file_name": "required|string|maxLength:255",
|
|
179
|
+
"content": "required|string:longtext",
|
|
180
|
+
"sort_order": "integer:unsigned",
|
|
181
|
+
"created_at": "datetime",
|
|
182
|
+
"modified_at": "datetime"
|
|
183
|
+
},
|
|
184
|
+
"pk": "file_id",
|
|
185
|
+
"timestamps": {
|
|
186
|
+
"created_at": "created_at",
|
|
187
|
+
"modified_at": "modified_at"
|
|
188
|
+
},
|
|
189
|
+
"parent": "snippets"
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
"snippet_dependencies": {
|
|
193
|
+
"columns": {
|
|
194
|
+
"dependency_id": "auto_increment",
|
|
195
|
+
"snippet_id": "required|string:uuid",
|
|
196
|
+
"library_id": "required|integer:unsigned",
|
|
197
|
+
"version_constraint": "string|maxLength:50",
|
|
198
|
+
"is_primary": "boolean",
|
|
199
|
+
"created_at": "datetime"
|
|
200
|
+
},
|
|
201
|
+
"pk": "dependency_id",
|
|
202
|
+
"unique": [["snippet_id", "library_id"]],
|
|
203
|
+
"timestamps": {
|
|
204
|
+
"created_at": "created_at"
|
|
205
|
+
},
|
|
206
|
+
"parent": "snippets"
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
"snippet_tags": {
|
|
210
|
+
"columns": {
|
|
211
|
+
"snippet_id": "required|string:uuid",
|
|
212
|
+
"tag_id": "required|integer:unsigned"
|
|
213
|
+
},
|
|
214
|
+
"pk": "snippet_id",
|
|
215
|
+
"unique": [["snippet_id", "tag_id"]],
|
|
216
|
+
"parent": "snippets"
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
"testing_logs": {
|
|
220
|
+
"columns": {
|
|
221
|
+
"testing_id": "auto_increment",
|
|
222
|
+
"snippet_id": "required|string:uuid",
|
|
223
|
+
"queue_id": "integer:bigint",
|
|
224
|
+
"language_id": "required|integer:unsigned",
|
|
225
|
+
"framework_id": "integer:unsigned",
|
|
226
|
+
"code_snapshot": "required|string:longtext",
|
|
227
|
+
"test_snapshot": "required|string:longtext",
|
|
228
|
+
"dependency_snapshot": "required|string:longtext",
|
|
229
|
+
"result": "required|string|in:pass,fail,error,timeout",
|
|
230
|
+
"exit_code": "integer",
|
|
231
|
+
"stdout": "string:longtext",
|
|
232
|
+
"stderr": "string:longtext",
|
|
233
|
+
"response_time_ms": "integer",
|
|
234
|
+
"sandbox_image": "string|maxLength:128",
|
|
235
|
+
"tested_at": "datetime"
|
|
236
|
+
},
|
|
237
|
+
"pk": "testing_id",
|
|
238
|
+
"timestamps": {
|
|
239
|
+
"tested_at": "tested_at"
|
|
240
|
+
},
|
|
241
|
+
"parent": "snippets"
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
"verification_stage_results": {
|
|
245
|
+
"columns": {
|
|
246
|
+
"result_id": "auto_increment",
|
|
247
|
+
"snippet_id": "required|string:uuid",
|
|
248
|
+
"queue_id": "integer:bigint",
|
|
249
|
+
"stage": "required|string|in:lint,static_analysis,security_scan,performance",
|
|
250
|
+
"status": "required|string|in:pass,fail,warning",
|
|
251
|
+
"score": "numeric:decimal(5,2)",
|
|
252
|
+
"tool_used": "string|maxLength:64",
|
|
253
|
+
"findings": "object",
|
|
254
|
+
"executed_at": "datetime"
|
|
255
|
+
},
|
|
256
|
+
"pk": "result_id",
|
|
257
|
+
"timestamps": {
|
|
258
|
+
"executed_at": "executed_at"
|
|
259
|
+
},
|
|
260
|
+
"parent": "snippets"
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
"enrichment_jobs": {
|
|
264
|
+
"columns": {
|
|
265
|
+
"job_id": "auto_increment",
|
|
266
|
+
"snippet_id": "required|string:uuid",
|
|
267
|
+
"provider": "required|string|maxLength:64",
|
|
268
|
+
"model": "required|string|maxLength:128",
|
|
269
|
+
"prompt_version": "string|maxLength:50",
|
|
270
|
+
"status": "required|string|in:pending,success,failed",
|
|
271
|
+
"raw_response": "string:longtext",
|
|
272
|
+
"tokens_used": "integer",
|
|
273
|
+
"latency_ms": "integer",
|
|
274
|
+
"created_at": "datetime"
|
|
275
|
+
},
|
|
276
|
+
"pk": "job_id",
|
|
277
|
+
"timestamps": {
|
|
278
|
+
"created_at": "created_at"
|
|
279
|
+
},
|
|
280
|
+
"parent": "snippets"
|
|
281
|
+
},
|
|
282
|
+
|
|
283
|
+
"generation_attempts": {
|
|
284
|
+
"columns": {
|
|
285
|
+
"attempt_id": "auto_increment",
|
|
286
|
+
"snippet_id": "required|string:uuid",
|
|
287
|
+
"attempt_number": "required|integer|min:1",
|
|
288
|
+
"previous_attempt_id": "integer:unsigned",
|
|
289
|
+
"prompt": "required|string:longtext",
|
|
290
|
+
"generated_code": "required|string:longtext",
|
|
291
|
+
"generated_test": "required|string:longtext",
|
|
292
|
+
"generated_dependency_manifest": "required|string:longtext",
|
|
293
|
+
"failure_stage": "string|in:execution,lint,static_analysis,security_scan",
|
|
294
|
+
"error_output": "string:longtext",
|
|
295
|
+
"outcome": "required|string|in:failed,succeeded",
|
|
296
|
+
"generation_provider": "string|maxLength:64",
|
|
297
|
+
"generation_model": "string|maxLength:128",
|
|
298
|
+
"created_at": "datetime"
|
|
299
|
+
},
|
|
300
|
+
"pk": "attempt_id",
|
|
301
|
+
"timestamps": {
|
|
302
|
+
"created_at": "created_at"
|
|
303
|
+
},
|
|
304
|
+
"parent": "snippets"
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
"execution_queue": {
|
|
308
|
+
"columns": {
|
|
309
|
+
"queue_id": "auto_increment",
|
|
310
|
+
"snippet_id": "required|string:uuid",
|
|
311
|
+
"stage": "required|string|in:execution,lint,static_analysis,security_scan,performance",
|
|
312
|
+
"status": "required|string|in:pending,locked,completed,failed",
|
|
313
|
+
"locked_by": "string|maxLength:100",
|
|
314
|
+
"locked_at": "datetime",
|
|
315
|
+
"lease_expires_at": "datetime",
|
|
316
|
+
"attempt_count": "integer:unsigned",
|
|
317
|
+
"max_attempts": "integer:unsigned",
|
|
318
|
+
"created_at": "datetime",
|
|
319
|
+
"updated_at": "datetime"
|
|
320
|
+
},
|
|
321
|
+
"pk": "queue_id",
|
|
322
|
+
"timestamps": {
|
|
323
|
+
"created_at": "created_at",
|
|
324
|
+
"updated_at": "updated_at"
|
|
325
|
+
},
|
|
326
|
+
"parent": "snippets"
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
"search_query_log": {
|
|
330
|
+
"columns": {
|
|
331
|
+
"log_id": "auto_increment",
|
|
332
|
+
"queries_json": "required|object",
|
|
333
|
+
"results_snippet_ids": "required|object",
|
|
334
|
+
"agent_session_id": "string|maxLength:100",
|
|
335
|
+
"created_at": "datetime"
|
|
336
|
+
},
|
|
337
|
+
"pk": "log_id",
|
|
338
|
+
"timestamps": {
|
|
339
|
+
"created_at": "created_at"
|
|
340
|
+
},
|
|
341
|
+
"parent": null
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
"snippet_feedback": {
|
|
345
|
+
"columns": {
|
|
346
|
+
"feedback_id": "auto_increment",
|
|
347
|
+
"snippet_id": "required|string:uuid",
|
|
348
|
+
"outcome": "required|string|in:used-success,used-failure,rejected-irrelevant",
|
|
349
|
+
"notes": "string:text",
|
|
350
|
+
"agent_session_id": "string|maxLength:100",
|
|
351
|
+
"created_at": "datetime"
|
|
352
|
+
},
|
|
353
|
+
"pk": "feedback_id",
|
|
354
|
+
"timestamps": {
|
|
355
|
+
"created_at": "created_at"
|
|
356
|
+
},
|
|
357
|
+
"parent": "snippets"
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "db-model-router",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"description": "Generative API Creation using mysql2 and express libraries in node js",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
"test:command": "mocha test/commands/*.test.js --timeout 30000 --exit",
|
|
25
25
|
"demo:clear": "node -e \"var fs=require('fs'),p=require('path'),d=p.join(__dirname,'demo');fs.existsSync(d)&&fs.rmSync(d,{recursive:true,force:true});fs.mkdirSync(d,{recursive:true})\"",
|
|
26
26
|
"demo:create": "node scripts/demo-create.js",
|
|
27
|
+
"demo:create-mysql": "node scripts/demo-create.js mysql",
|
|
28
|
+
"demo:create-mariadb": "node scripts/demo-create.js mariadb",
|
|
27
29
|
"demo:create-postgres": "node scripts/demo-create.js postgres"
|
|
28
30
|
},
|
|
29
31
|
"repository": {
|
package/scripts/demo-create.js
CHANGED
|
@@ -29,20 +29,26 @@ const run = (cmd, cwd) => {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
// 2. Copy schema into the demo folder
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const SCHEMA_BY_ADAPTER = {
|
|
33
|
+
postgres: "dbmr.postgres.test.schema.json",
|
|
34
|
+
mysql: "dbmr.schema.mysql.json",
|
|
35
|
+
mariadb: "dbmr.schema.mysql.json",
|
|
36
|
+
sqlite3: "dbmr.schema.json",
|
|
37
|
+
};
|
|
38
|
+
const schemaPath = path.join(ROOT, SCHEMA_BY_ADAPTER[ADAPTER]);
|
|
36
39
|
|
|
37
40
|
const schema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
|
|
38
41
|
|
|
39
|
-
// Patch adapter
|
|
42
|
+
// Patch adapter for sqlite3/mariadb demos. mysql/postgres use dedicated
|
|
43
|
+
// schemas with adapter already set; mariadb reuses the mysql schema.
|
|
40
44
|
if (ADAPTER === "sqlite3") {
|
|
41
45
|
schema.adapter = "sqlite3";
|
|
42
46
|
if (schema.options) {
|
|
43
47
|
delete schema.options.session;
|
|
44
48
|
delete schema.options.loki;
|
|
45
49
|
}
|
|
50
|
+
} else if (ADAPTER === "mariadb") {
|
|
51
|
+
schema.adapter = "mariadb";
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
const schemaDest = path.join(DEMO, "dbmr.schema.json");
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const { schemaToModelMeta } = require("../../schema/schema-to-meta");
|
|
6
|
-
const { generateModelFile } = require("../generate-model");
|
|
6
|
+
const { generateModelFile, generateIndexFile } = require("../generate-model");
|
|
7
7
|
const {
|
|
8
8
|
generateRouteFile,
|
|
9
9
|
generateParentRouteFile,
|
|
@@ -104,6 +104,14 @@ async function buildSchemaArtifacts({ schema, baseDir, ctx, flags }) {
|
|
|
104
104
|
content: generateModelFile(m),
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
|
+
|
|
108
|
+
// Barrel re-exporting all schema models. When SaaS is enabled, the SaaS
|
|
109
|
+
// generator emits a combined barrel (SaaS + schema tables) and replaces
|
|
110
|
+
// this one below; without SaaS, this barrel is the final models/index.js.
|
|
111
|
+
planned.push({
|
|
112
|
+
relPath: "models/index.js",
|
|
113
|
+
content: generateIndexFile(meta),
|
|
114
|
+
});
|
|
107
115
|
}
|
|
108
116
|
|
|
109
117
|
// --- Route files ---
|
|
@@ -258,14 +266,15 @@ async function buildSchemaArtifacts({ schema, baseDir, ctx, flags }) {
|
|
|
258
266
|
baseDir,
|
|
259
267
|
});
|
|
260
268
|
|
|
261
|
-
// The SaaS generator produces a combined routes/index.js
|
|
262
|
-
// both SaaS
|
|
263
|
-
// planned
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
+
// The SaaS generator produces a combined routes/index.js and models/index.js
|
|
270
|
+
// that include both SaaS and dbmr schema-generated entries. Remove the
|
|
271
|
+
// plain barrels previously planned by the schema generator so the combined
|
|
272
|
+
// SaaS versions win.
|
|
273
|
+
for (const barrel of ["routes/index.js", "models/index.js"]) {
|
|
274
|
+
const existingIdx = planned.findIndex((p) => p.relPath === barrel);
|
|
275
|
+
if (existingIdx !== -1) {
|
|
276
|
+
planned.splice(existingIdx, 1);
|
|
277
|
+
}
|
|
269
278
|
}
|
|
270
279
|
|
|
271
280
|
for (const entry of saasFiles) {
|
package/src/cli/commands/init.js
CHANGED
|
@@ -132,9 +132,6 @@ async function init(args, flags, ctx) {
|
|
|
132
132
|
updatePackageJson(answers, outputDir);
|
|
133
133
|
|
|
134
134
|
const installed = !flags.noInstall;
|
|
135
|
-
if (installed) {
|
|
136
|
-
runInstall();
|
|
137
|
-
}
|
|
138
135
|
|
|
139
136
|
// Build init's JSON result first so it lands at ctx._results[0] (buildSchemaArtifacts
|
|
140
137
|
// pushes its own result afterward).
|
|
@@ -153,10 +150,17 @@ async function init(args, flags, ctx) {
|
|
|
153
150
|
});
|
|
154
151
|
}
|
|
155
152
|
|
|
156
|
-
// Schema-driven artifacts: models, routes, migrations, openapi, tests, SaaS
|
|
153
|
+
// Schema-driven artifacts: models, routes, migrations, openapi, tests, SaaS.
|
|
154
|
+
// Generated BEFORE npm install so all files exist on disk first; bail skips
|
|
155
|
+
// install if the build reported an error.
|
|
157
156
|
await buildSchemaArtifacts({ schema, baseDir, ctx, flags });
|
|
158
157
|
if (process.exitCode) return; // bail if build reported an error
|
|
159
158
|
|
|
159
|
+
// Install dependencies only after every project file has been written.
|
|
160
|
+
if (installed) {
|
|
161
|
+
runInstall();
|
|
162
|
+
}
|
|
163
|
+
|
|
160
164
|
// Human-readable summary (non-json only)
|
|
161
165
|
if (!flags.json) {
|
|
162
166
|
printSummary(generated);
|
package/src/cli/diff-engine.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const path = require("path");
|
|
5
|
-
const { generateModelFile } = require("./generate-model.js");
|
|
5
|
+
const { generateModelFile, generateIndexFile } = require("./generate-model.js");
|
|
6
6
|
const {
|
|
7
7
|
generateRouteFile,
|
|
8
8
|
generateParentRouteFile,
|
|
@@ -87,6 +87,10 @@ function buildExpectedFiles(meta, relationships, options = {}) {
|
|
|
87
87
|
expected.set(`models/${m.table}.js`, generateModelFile(m));
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
// Model barrel. SaaS mode overwrites this with the combined SaaS+dbmr
|
|
91
|
+
// barrel when saasFiles are merged below.
|
|
92
|
+
expected.set("models/index.js", generateIndexFile(meta));
|
|
93
|
+
|
|
90
94
|
// Route files: exactly one per table at its correct nested path
|
|
91
95
|
for (const m of meta) {
|
|
92
96
|
const tableName = m.table;
|
|
@@ -703,9 +703,17 @@ function generateInitialMigration(answers, date) {
|
|
|
703
703
|
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
704
704
|
checksum VARCHAR2(64) NOT NULL
|
|
705
705
|
);
|
|
706
|
+
`;
|
|
707
|
+
} else if (answers.database === "mysql" || answers.database === "mariadb") {
|
|
708
|
+
content = `CREATE TABLE IF NOT EXISTS _migrations (
|
|
709
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
710
|
+
filename VARCHAR(255) NOT NULL UNIQUE,
|
|
711
|
+
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
712
|
+
checksum VARCHAR(64) NOT NULL
|
|
713
|
+
);
|
|
706
714
|
`;
|
|
707
715
|
} else {
|
|
708
|
-
//
|
|
716
|
+
// sqlite3
|
|
709
717
|
content = `CREATE TABLE IF NOT EXISTS _migrations (
|
|
710
718
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
711
719
|
filename VARCHAR(255) NOT NULL UNIQUE,
|
package/src/mysql/db.js
CHANGED
|
@@ -7,6 +7,12 @@ function connect(credentails) {
|
|
|
7
7
|
// Force UTC timezone so timestamps are consistent
|
|
8
8
|
// dateStrings: true returns raw strings without JS Date conversion
|
|
9
9
|
credentails.timezone = "+00:00";
|
|
10
|
+
// Enable multiple statements by default so multi-query migration files
|
|
11
|
+
// (e.g. a single .sql with many CREATE TABLE statements) run in one call.
|
|
12
|
+
// Applied to mysql and mariadb (both use this adapter).
|
|
13
|
+
if (credentails.multipleStatements === undefined) {
|
|
14
|
+
credentails.multipleStatements = true;
|
|
15
|
+
}
|
|
10
16
|
pool = mysql.createPool(credentails);
|
|
11
17
|
return pool;
|
|
12
18
|
}
|