tangled
alpha
login
or
join now
maxine.puppykitty.racing
/
typelex
forked from
danabra.mov/typelex
0
fork
atom
An experimental TypeSpec syntax for Lexicon
0
fork
atom
overview
issues
pulls
pipelines
fixes
danabra.mov
5 months ago
936dfa97
846457ba
+61
-15
2 changed files
expand all
collapse all
unified
split
packages
cli
package.json
src
commands
init.ts
+1
-1
packages/cli/package.json
···
1
{
2
"name": "@typelex/cli",
3
-
"version": "0.2.10",
4
"main": "dist/index.js",
5
"type": "module",
6
"bin": {
···
1
{
2
"name": "@typelex/cli",
3
+
"version": "0.2.12",
4
"main": "dist/index.js",
5
"type": "module",
6
"bin": {
+60
-14
packages/cli/src/commands/init.ts
···
4
import { createInterface } from "readline";
5
import pc from "picocolors";
6
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
7
function createMainTemplate(namespace: string): string {
8
return `import "@typelex/emitter";
9
import "./externals.tsp";
···
50
return initSetup();
51
}
52
53
-
console.log(pc.bold("Initializing typelex project...\n"));
54
-
console.log("Installing dependencies...");
55
56
// Detect package manager: walk up from cwd
57
let packageManager = "npm";
···
87
88
install.on("close", (code) => {
89
if (code === 0) {
90
-
console.log("\n✓ Installed @typelex/cli and @typelex/emitter\n");
91
resolvePromise();
92
} else {
93
console.error(pc.red("✗ Failed to install dependencies"));
···
102
});
103
104
// Hand off to locally installed version
105
-
console.log("Continuing with local installation...\n");
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
106
107
return new Promise((resolvePromise, reject) => {
108
-
const localCli = resolve(cwd, "node_modules/.bin/typelex");
109
const setup = spawn(localCli, ["init", "--setup"], {
110
cwd,
111
stdio: "inherit",
···
176
}
177
}
178
0
0
0
0
0
0
0
0
0
179
// Create typelex directory
180
await mkdir(typelexDir, { recursive: true });
181
···
185
await access(mainTspPath);
186
const content = await readFile(mainTspPath, "utf-8");
187
if (content.trim().length > 0) {
188
-
console.log(`✓ ${pc.cyan("typelex/main.tsp")} already exists, skipping`);
189
shouldCreateMain = false;
190
}
191
} catch {
···
194
195
if (shouldCreateMain) {
196
await writeFile(mainTspPath, createMainTemplate(namespacePrefix), "utf-8");
197
-
console.log(`✓ Created ${pc.cyan("typelex/main.tsp")}`);
198
}
199
200
// Always create/overwrite externals.tsp
201
await writeFile(externalsTspPath, EXTERNALS_TSP_TEMPLATE, "utf-8");
202
-
console.log(`✓ Created ${pc.cyan("typelex/externals.tsp")}`);
203
204
// Add build script to package.json
205
const packageJsonPath = resolve(cwd, "package.json");
···
212
const outFlag = lexiconsDir ? ` --out ${lexiconsDir}` : "";
213
packageJson.scripts["build:typelex"] = `typelex compile ${namespace}${outFlag}`;
214
await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n", "utf-8");
215
-
console.log(`✓ Added ${pc.cyan("build:typelex")} script to ${pc.cyan("package.json")}`);
216
if (hasLocalLexicons) {
217
console.log(pc.dim(` Using existing lexicons directory: ${pc.cyan("./lexicons")}`));
218
} else if (lexiconsDir) {
219
console.log(pc.dim(` Using existing lexicons directory: ${pc.cyan(lexiconsDir)}`));
220
}
221
} else {
222
-
console.log(`✓ ${pc.cyan("build:typelex")} script already exists in ${pc.cyan("package.json")}`);
223
}
224
} catch (err) {
225
console.warn(pc.yellow(`⚠ Could not update ${pc.cyan("package.json")}:`), (err as Error).message);
226
}
227
228
-
console.log(pc.bold("\n✓ Typelex initialized successfully!"));
229
-
console.log(pc.bold("\nNext steps:"));
230
-
console.log(` 1. Edit ${pc.cyan("typelex/main.tsp")} to define your lexicons`);
231
-
console.log(` 2. Run: ${pc.cyan("npm run build:typelex")}`);
0
232
}
···
4
import { createInterface } from "readline";
5
import pc from "picocolors";
6
7
+
// Gradient colors matching website (approximated with ANSI 256 colors)
8
+
// Darker variant for better readability on white terminals
9
+
function gradientText(text: string): string {
10
+
// Approximating: #4a9eff -> #7a8ef7 -> #ff85c1 -> #9b7ef7
11
+
// Using darker ANSI 256 color codes for a blue->purple->pink gradient
12
+
const colors = [
13
+
'\x1b[38;5;33m', // darker blue
14
+
'\x1b[38;5;69m', // blue-purple
15
+
'\x1b[38;5;99m', // purple
16
+
'\x1b[38;5;133m', // purple-pink
17
+
'\x1b[38;5;170m', // pink
18
+
'\x1b[38;5;170m', // pink
19
+
'\x1b[38;5;133m', // purple-pink
20
+
];
21
+
const reset = '\x1b[0m';
22
+
23
+
return text.split('').map((char, i) => {
24
+
const colorIndex = Math.floor((i / text.length) * colors.length);
25
+
return colors[colorIndex] + char;
26
+
}).join('') + reset;
27
+
}
28
+
29
function createMainTemplate(namespace: string): string {
30
return `import "@typelex/emitter";
31
import "./externals.tsp";
···
72
return initSetup();
73
}
74
75
+
console.log(`Adding ${gradientText("typelex")}...\n`);
0
76
77
// Detect package manager: walk up from cwd
78
let packageManager = "npm";
···
108
109
install.on("close", (code) => {
110
if (code === 0) {
111
+
console.log(`\n${pc.green("✓")} Installed ${pc.dim("@typelex/cli")} and ${pc.dim("@typelex/emitter")}\n`);
112
resolvePromise();
113
} else {
114
console.error(pc.red("✗ Failed to install dependencies"));
···
123
});
124
125
// Hand off to locally installed version
126
+
// Find where node_modules actually is (could be at workspace root with pnpm)
127
+
let nodeModulesDir = resolve(cwd, "node_modules");
128
+
let searchDir = cwd;
129
+
130
+
// Search upward for node_modules with typelex installed
131
+
while (searchDir !== resolve(searchDir, "..")) {
132
+
try {
133
+
const candidatePath = resolve(searchDir, "node_modules/.bin/typelex");
134
+
await access(candidatePath);
135
+
nodeModulesDir = resolve(searchDir, "node_modules");
136
+
break;
137
+
} catch {
138
+
// Not found, try parent
139
+
}
140
+
searchDir = resolve(searchDir, "..");
141
+
}
142
143
return new Promise((resolvePromise, reject) => {
144
+
const localCli = resolve(nodeModulesDir, ".bin/typelex");
145
const setup = spawn(localCli, ["init", "--setup"], {
146
cwd,
147
stdio: "inherit",
···
212
}
213
}
214
215
+
// Determine the actual lexicons path for display
216
+
const displayLexiconsPath = hasLocalLexicons
217
+
? "./lexicons"
218
+
: lexiconsDir || "./lexicons";
219
+
220
+
// Inform about external lexicons
221
+
console.log(`\nLexicons other than ${pc.cyan(namespace)} will be considered external.`);
222
+
console.log(`Put them into the ${pc.cyan(displayLexiconsPath)} folder as JSON.\n`);
223
+
224
// Create typelex directory
225
await mkdir(typelexDir, { recursive: true });
226
···
230
await access(mainTspPath);
231
const content = await readFile(mainTspPath, "utf-8");
232
if (content.trim().length > 0) {
233
+
console.log(`${pc.green("✓")} ${pc.cyan("typelex/main.tsp")} already exists, skipping`);
234
shouldCreateMain = false;
235
}
236
} catch {
···
239
240
if (shouldCreateMain) {
241
await writeFile(mainTspPath, createMainTemplate(namespacePrefix), "utf-8");
242
+
console.log(`${pc.green("✓")} Created ${pc.cyan("typelex/main.tsp")}`);
243
}
244
245
// Always create/overwrite externals.tsp
246
await writeFile(externalsTspPath, EXTERNALS_TSP_TEMPLATE, "utf-8");
247
+
console.log(`${pc.green("✓")} Created ${pc.cyan("typelex/externals.tsp")}`);
248
249
// Add build script to package.json
250
const packageJsonPath = resolve(cwd, "package.json");
···
257
const outFlag = lexiconsDir ? ` --out ${lexiconsDir}` : "";
258
packageJson.scripts["build:typelex"] = `typelex compile ${namespace}${outFlag}`;
259
await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n", "utf-8");
260
+
console.log(`${pc.green("✓")} Added ${pc.cyan("build:typelex")} script to ${pc.cyan("package.json")}`);
261
if (hasLocalLexicons) {
262
console.log(pc.dim(` Using existing lexicons directory: ${pc.cyan("./lexicons")}`));
263
} else if (lexiconsDir) {
264
console.log(pc.dim(` Using existing lexicons directory: ${pc.cyan(lexiconsDir)}`));
265
}
266
} else {
267
+
console.log(`${pc.green("✓")} ${pc.cyan("build:typelex")} script already exists in ${pc.cyan("package.json")}`);
268
}
269
} catch (err) {
270
console.warn(pc.yellow(`⚠ Could not update ${pc.cyan("package.json")}:`), (err as Error).message);
271
}
272
273
+
console.log(`\n${pc.green("✓")} ${pc.bold("All set!")}`);
274
+
console.log(`\n${pc.bold("Next steps:")}`);
275
+
console.log(` ${pc.dim("1.")} Edit ${pc.cyan("typelex/main.tsp")} to define your lexicons`);
276
+
console.log(` ${pc.dim("2.")} Keep putting external lexicons into ${pc.cyan(displayLexiconsPath)}`);
277
+
console.log(` ${pc.dim("3.")} Run ${pc.cyan("npm run build:typelex")} to compile to JSON`);
278
}