An experimental TypeSpec syntax for Lexicon

handoff

+55 -10
+10 -3
packages/cli/src/cli.ts
··· 10 10 .command( 11 11 "init", 12 12 "Initialize a new typelex project", 13 - () => {}, 14 - async () => { 15 - await initCommand(); 13 + (yargs) => { 14 + return yargs.option("setup", { 15 + describe: "Internal: run setup after installation", 16 + type: "boolean", 17 + hidden: true, 18 + default: false, 19 + }); 20 + }, 21 + async (argv) => { 22 + await initCommand(argv.setup); 16 23 } 17 24 ) 18 25 .command(
+45 -7
packages/cli/src/commands/init.ts
··· 39 39 } 40 40 41 41 /** 42 - * Initialize a new typelex project 42 + * Initialize command - installs packages and hands off to local version 43 + * This is what gets called by npx 43 44 */ 44 - export async function initCommand(): Promise<void> { 45 + export async function initCommand(isSetup: boolean = false): Promise<void> { 45 46 const cwd = process.cwd(); 46 - const typelexDir = resolve(cwd, "typelex"); 47 - const mainTspPath = resolve(typelexDir, "main.tsp"); 48 - const externalsTspPath = resolve(typelexDir, "externals.tsp"); 47 + 48 + // If this is the second pass (after handoff), run setup 49 + if (isSetup) { 50 + return initSetup(); 51 + } 49 52 50 53 console.log(pc.bold("Initializing typelex project...\n")); 51 54 console.log("Installing dependencies..."); ··· 71 74 dir = resolve(dir, ".."); 72 75 } 73 76 74 - // Install dependencies and only proceed if successful 77 + // Install dependencies 75 78 await new Promise<void>((resolvePromise, reject) => { 76 79 const args = packageManager === "npm" 77 80 ? ["install", "--save-dev", "@typelex/cli", "@typelex/emitter"] ··· 98 101 }); 99 102 }); 100 103 101 - // Prompt for namespace after successful installation 104 + // Hand off to locally installed version 105 + console.log("Continuing with local installation...\n"); 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", 112 + }); 113 + 114 + setup.on("close", (code) => { 115 + if (code === 0) { 116 + resolvePromise(); 117 + } else { 118 + process.exit(code ?? 1); 119 + } 120 + }); 121 + 122 + setup.on("error", (err) => { 123 + console.error(pc.red("✗ Failed to run setup:"), err); 124 + reject(err); 125 + }); 126 + }); 127 + } 128 + 129 + /** 130 + * Setup function - called after packages are installed 131 + * This runs from the locally installed version 132 + */ 133 + export async function initSetup(): Promise<void> { 134 + const cwd = process.cwd(); 135 + const typelexDir = resolve(cwd, "typelex"); 136 + const mainTspPath = resolve(typelexDir, "main.tsp"); 137 + const externalsTspPath = resolve(typelexDir, "externals.tsp"); 138 + 139 + // Prompt for namespace 102 140 let namespace = await promptNamespace(); 103 141 104 142 // Validate namespace format