tina4-nodejs 3.10.34 → 3.10.40
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/package.json +1 -1
- package/packages/cli/src/bin.ts +13 -26
- package/packages/cli/src/commands/seed.ts +72 -0
- package/packages/cli/src/commands/serve.ts +2 -1
- package/packages/core/src/ai.ts +241 -247
- package/packages/core/src/devAdmin.ts +289 -6
- package/packages/core/src/index.ts +3 -3
- package/packages/core/src/metrics.ts +800 -0
- package/packages/core/src/response.ts +98 -40
- package/packages/core/src/router.ts +5 -0
- package/packages/core/src/server.ts +3 -8
- package/packages/core/src/types.ts +2 -2
- package/packages/orm/src/baseModel.ts +25 -0
- package/packages/orm/src/database.ts +38 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tina4-nodejs",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.40",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "This is not a framework. Tina4 for Node.js/TypeScript — zero deps, 38 built-in features.",
|
|
6
6
|
"keywords": ["tina4", "framework", "web", "api", "orm", "graphql", "websocket", "typescript"],
|
package/packages/cli/src/bin.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { migrateRollback } from "./commands/migrateRollback.js";
|
|
|
7
7
|
import { listRoutes } from "./commands/routes.js";
|
|
8
8
|
import { runTests } from "./commands/test.js";
|
|
9
9
|
import { generate } from "./commands/generate.js";
|
|
10
|
+
import { runSeeds } from "./commands/seed.js";
|
|
10
11
|
|
|
11
12
|
const args = process.argv.slice(2);
|
|
12
13
|
const command = args[0];
|
|
@@ -24,7 +25,8 @@ const HELP = `
|
|
|
24
25
|
tina4nodejs routes List all registered routes
|
|
25
26
|
tina4nodejs test [file] Run project tests
|
|
26
27
|
tina4nodejs generate <what> <name> Generate scaffolding (model, route, migration, middleware)
|
|
27
|
-
tina4nodejs
|
|
28
|
+
tina4nodejs seed [file] Run database seed files from src/seeds/
|
|
29
|
+
tina4nodejs ai Install AI coding assistant context files
|
|
28
30
|
tina4nodejs help Show this help message
|
|
29
31
|
|
|
30
32
|
Options:
|
|
@@ -78,35 +80,20 @@ async function main(): Promise<void> {
|
|
|
78
80
|
await generate(what, genName);
|
|
79
81
|
break;
|
|
80
82
|
}
|
|
83
|
+
case "seed": {
|
|
84
|
+
await runSeeds(args[1]);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
81
87
|
case "ai": {
|
|
82
|
-
const {
|
|
88
|
+
const { showMenu, installSelected, installAll } = await import("../../core/src/ai.js");
|
|
83
89
|
const root = args[1] || ".";
|
|
84
|
-
const installAll = args.includes("--all");
|
|
85
|
-
const force = args.includes("--force");
|
|
86
90
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// Install context
|
|
91
|
-
if (installAll) {
|
|
92
|
-
const created = installAllAiContext(root, force);
|
|
93
|
-
if (created.length > 0) {
|
|
94
|
-
console.log("Installed AI context files:");
|
|
95
|
-
for (const f of created) {
|
|
96
|
-
console.log(` + ${f}`);
|
|
97
|
-
}
|
|
98
|
-
} else {
|
|
99
|
-
console.log("All AI context files already exist (use --force to overwrite).");
|
|
100
|
-
}
|
|
91
|
+
if (args.includes("--all")) {
|
|
92
|
+
installAll(root);
|
|
101
93
|
} else {
|
|
102
|
-
const
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
for (const f of created) {
|
|
106
|
-
console.log(` + ${f}`);
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
console.log("No new AI context files needed.");
|
|
94
|
+
const selection = await showMenu(root);
|
|
95
|
+
if (selection) {
|
|
96
|
+
installSelected(root, selection);
|
|
110
97
|
}
|
|
111
98
|
}
|
|
112
99
|
break;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI command: seed — Run database seed files.
|
|
3
|
+
*
|
|
4
|
+
* Scans src/seeds/ for .ts files and executes them with tsx in alphabetical order.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
7
|
+
import { resolve, join } from "node:path";
|
|
8
|
+
import { execSync } from "node:child_process";
|
|
9
|
+
|
|
10
|
+
export async function runSeeds(seedPath?: string): Promise<void> {
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
const seedDir = resolve(cwd, "src/seeds");
|
|
13
|
+
|
|
14
|
+
// If a specific seed file is provided, run it directly
|
|
15
|
+
if (seedPath) {
|
|
16
|
+
const file = resolve(seedPath);
|
|
17
|
+
if (!existsSync(file)) {
|
|
18
|
+
console.error(` Error: Seed file not found: ${seedPath}`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
console.log(` Running seed: ${seedPath}\n`);
|
|
22
|
+
try {
|
|
23
|
+
execSync(`npx tsx "${file}"`, { cwd, stdio: "inherit" });
|
|
24
|
+
} catch {
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Auto-discover seed files in src/seeds/
|
|
31
|
+
if (!existsSync(seedDir)) {
|
|
32
|
+
console.log(" No seeds directory found.");
|
|
33
|
+
console.log(" Create seed files in src/seeds/ (e.g. src/seeds/001-users.ts)");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let seedFiles: string[];
|
|
38
|
+
try {
|
|
39
|
+
seedFiles = readdirSync(seedDir)
|
|
40
|
+
.filter((f) => f.endsWith(".ts"))
|
|
41
|
+
.sort()
|
|
42
|
+
.map((f) => join(seedDir, f));
|
|
43
|
+
} catch {
|
|
44
|
+
console.log(" Could not read src/seeds/ directory.");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (seedFiles.length === 0) {
|
|
49
|
+
console.log(" No seed files found in src/seeds/");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log(` Found ${seedFiles.length} seed file(s)\n`);
|
|
54
|
+
|
|
55
|
+
let failed = false;
|
|
56
|
+
for (const file of seedFiles) {
|
|
57
|
+
const relative = file.replace(cwd + "/", "");
|
|
58
|
+
console.log(` Seeding: ${relative}`);
|
|
59
|
+
try {
|
|
60
|
+
execSync(`npx tsx "${file}"`, { cwd, stdio: "inherit" });
|
|
61
|
+
} catch {
|
|
62
|
+
failed = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (failed) {
|
|
67
|
+
console.error("\n Some seeds failed.");
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log("\n All seeds completed.");
|
|
72
|
+
}
|
|
@@ -36,8 +36,9 @@ export async function serveProject(options: ServeOptions): Promise<void> {
|
|
|
36
36
|
const watcher = watchForChanges(watchDirs, async () => {
|
|
37
37
|
try {
|
|
38
38
|
const { discoverRoutes } = await import("@tina4/core");
|
|
39
|
-
|
|
39
|
+
// Clear routes BEFORE re-discovery to avoid stale duplicates
|
|
40
40
|
server.router.clear();
|
|
41
|
+
const routes = await discoverRoutes(routesDir);
|
|
41
42
|
for (const route of routes) {
|
|
42
43
|
server.router.addRoute(route);
|
|
43
44
|
}
|