+92
-62
tools/lexicon-cli/src/commands/generate.ts
+92
-62
tools/lexicon-cli/src/commands/generate.ts
···
1
-
import { execa } from 'execa';
2
-
import { existsSync } from 'fs';
3
-
import { join } from 'path';
4
-
import pc from 'picocolors';
5
-
import { findWorkspaceRoot } from '../utils/workspace.js';
6
7
interface GenerateOptions {
8
tsOnly?: boolean;
···
12
13
export async function generate(options: GenerateOptions = {}) {
14
const workspaceRoot = findWorkspaceRoot();
15
-
16
-
console.log(pc.blue('🔧 Generating lexicon types...'));
17
-
18
try {
19
if (!options.rustOnly) {
20
await generateTypeScript(workspaceRoot, options.force);
21
}
22
-
23
if (!options.tsOnly) {
24
await generateRust(workspaceRoot, options.force);
25
}
26
-
27
-
console.log(pc.green('✅ Lexicon generation complete!'));
28
} catch (error) {
29
-
console.error(pc.red('❌ Generation failed:'), error instanceof Error ? error.message : String(error));
30
process.exit(1);
31
}
32
}
33
34
async function generateTypeScript(workspaceRoot: string, force?: boolean) {
35
-
const lexiconsPath = join(workspaceRoot, 'lexicons');
36
-
37
if (!existsSync(lexiconsPath)) {
38
-
throw new Error('Lexicons directory not found at workspace root');
39
}
40
-
41
// Check if packages/lexicons exists for TypeScript generation
42
-
const packagesLexiconsPath = join(workspaceRoot, 'packages/lexicons');
43
if (!existsSync(packagesLexiconsPath)) {
44
-
console.log(pc.yellow(' ⚠️ TypeScript lexicons package not found, skipping TypeScript generation'));
45
return;
46
}
47
-
48
-
console.log(pc.cyan(' 📦 Generating TypeScript types...'));
49
-
50
try {
51
-
await execa('pnpm', ['lex:gen-server'], {
52
cwd: packagesLexiconsPath,
53
-
stdio: 'inherit'
54
});
55
-
console.log(pc.green(' ✓ TypeScript types generated'));
56
} catch (error) {
57
-
throw new Error(`TypeScript generation failed: ${error instanceof Error ? error.message : String(error)}`);
58
}
59
}
60
61
async function generateRust(workspaceRoot: string, force?: boolean) {
62
-
const typesPath = join(workspaceRoot, 'services/types');
63
-
const lexiconsPath = join(workspaceRoot, 'lexicons');
64
-
65
if (!existsSync(typesPath)) {
66
-
throw new Error('Rust types service not found');
67
}
68
-
69
if (!existsSync(lexiconsPath)) {
70
-
throw new Error('Lexicons directory not found at workspace root');
71
}
72
-
73
-
console.log(pc.cyan(' 🦀 Generating Rust types...'));
74
-
75
try {
76
// Check if esquema-cli is available
77
try {
78
-
await execa('esquema-cli', ['--version'], { stdio: 'pipe' });
79
} catch {
80
-
console.log(pc.yellow(' ⚠️ esquema-cli not found. Installing...'));
81
try {
82
-
await execa('cargo', [
83
-
'install',
84
-
'esquema-cli',
85
-
'--git',
86
-
'https://github.com/fatfingers23/esquema.git'
87
-
], {
88
-
stdio: 'inherit'
89
-
});
90
-
console.log(pc.green(' ✓ esquema-cli installed successfully'));
91
} catch (installError) {
92
-
throw new Error('Failed to install esquema-cli. Please install manually: cargo install esquema-cli --git https://github.com/fatfingers23/esquema.git');
93
}
94
}
95
-
96
-
await execa('esquema-cli', [
97
-
'generate',
98
-
'local',
99
-
'--lexdir',
100
-
lexiconsPath,
101
-
'--outdir',
102
-
join(typesPath, 'src')
103
-
], {
104
-
cwd: typesPath,
105
-
stdio: 'inherit'
106
-
});
107
-
108
-
console.log(pc.green(' ✓ Rust types generated'));
109
} catch (error) {
110
-
throw new Error(`Rust generation failed: ${error instanceof Error ? error.message : String(error)}`);
111
}
112
-
}
···
1
+
import { existsSync } from "fs";
2
+
import { join } from "path";
3
+
import { execa } from "execa";
4
+
import pc from "picocolors";
5
+
6
+
import { findWorkspaceRoot } from "../utils/workspace.js";
7
8
interface GenerateOptions {
9
tsOnly?: boolean;
···
13
14
export async function generate(options: GenerateOptions = {}) {
15
const workspaceRoot = findWorkspaceRoot();
16
+
17
+
console.log(pc.blue("🔧 Generating lexicon types..."));
18
+
19
try {
20
if (!options.rustOnly) {
21
await generateTypeScript(workspaceRoot, options.force);
22
}
23
+
24
if (!options.tsOnly) {
25
await generateRust(workspaceRoot, options.force);
26
}
27
+
28
+
console.log(pc.green("✅ Lexicon generation complete!"));
29
} catch (error) {
30
+
console.error(
31
+
pc.red("❌ Generation failed:"),
32
+
error instanceof Error ? error.message : String(error),
33
+
);
34
process.exit(1);
35
}
36
}
37
38
async function generateTypeScript(workspaceRoot: string, force?: boolean) {
39
+
const lexiconsPath = join(workspaceRoot, "lexicons");
40
+
41
if (!existsSync(lexiconsPath)) {
42
+
throw new Error("Lexicons directory not found at workspace root");
43
}
44
+
45
// Check if packages/lexicons exists for TypeScript generation
46
+
const packagesLexiconsPath = join(workspaceRoot, "packages/lexicons");
47
if (!existsSync(packagesLexiconsPath)) {
48
+
console.log(
49
+
pc.yellow(
50
+
" ⚠️ TypeScript lexicons package not found, skipping TypeScript generation",
51
+
),
52
+
);
53
return;
54
}
55
+
56
+
console.log(pc.cyan(" 📦 Generating TypeScript types..."));
57
+
58
try {
59
+
await execa("pnpm", ["lex:gen-server"], {
60
cwd: packagesLexiconsPath,
61
+
stdio: "inherit",
62
});
63
+
console.log(pc.green(" ✓ TypeScript types generated"));
64
} catch (error) {
65
+
throw new Error(
66
+
`TypeScript generation failed: ${error instanceof Error ? error.message : String(error)}`,
67
+
);
68
}
69
}
70
71
async function generateRust(workspaceRoot: string, force?: boolean) {
72
+
const typesPath = join(workspaceRoot, "services/types");
73
+
const lexiconsPath = join(workspaceRoot, "lexicons");
74
+
75
if (!existsSync(typesPath)) {
76
+
throw new Error("Rust types service not found");
77
}
78
+
79
if (!existsSync(lexiconsPath)) {
80
+
throw new Error("Lexicons directory not found at workspace root");
81
}
82
+
83
+
console.log(pc.cyan(" 🦀 Generating Rust types..."));
84
+
85
try {
86
// Check if esquema-cli is available
87
try {
88
+
await execa("esquema-cli", ["--version"], { stdio: "pipe" });
89
} catch {
90
+
console.log(pc.yellow(" ⚠️ esquema-cli not found. Installing..."));
91
try {
92
+
await execa(
93
+
"cargo",
94
+
[
95
+
"install",
96
+
"esquema-cli",
97
+
"--git",
98
+
"https://github.com/fatfingers23/esquema.git",
99
+
],
100
+
{
101
+
stdio: "inherit",
102
+
},
103
+
);
104
+
console.log(pc.green(" ✓ esquema-cli installed successfully"));
105
} catch (installError) {
106
+
throw new Error(
107
+
"Failed to install esquema-cli. Please install manually: cargo install esquema-cli --git https://github.com/fatfingers23/esquema.git",
108
+
);
109
}
110
}
111
+
112
+
// create typespath/src if it doesn't exist
113
+
if (!existsSync(join(typesPath, "src"))) {
114
+
console.log(pc.yellow(" Creating src directory for Rust types..."));
115
+
await execa("mkdir", ["-p", join(typesPath, "src")], {
116
+
stdio: "inherit",
117
+
});
118
+
}
119
+
120
+
await execa(
121
+
"esquema-cli",
122
+
[
123
+
"generate",
124
+
"local",
125
+
"--lexdir",
126
+
lexiconsPath,
127
+
"--outdir",
128
+
join(typesPath, "src"),
129
+
],
130
+
{
131
+
cwd: typesPath,
132
+
stdio: "inherit",
133
+
},
134
+
);
135
+
136
+
console.log(pc.green(" ✓ Rust types generated"));
137
} catch (error) {
138
+
throw new Error(
139
+
`Rust generation failed: ${error instanceof Error ? error.message : String(error)}`,
140
+
);
141
}
142
+
}