Skip to main content
Glama
typescript-compilation-pipeline.test.ts6.15 kB
/** * TypeScript to JavaScript Compilation Pipeline Test * * CRITICAL TEST: Ensures that TypeScript source can be properly compiled to JavaScript * and that the compilation process maintains protocol consistency. * * PURPOSE: Establish sustainable development workflow where TypeScript changes * can be compiled to JavaScript without breaking the Interactive Terminal Epic. */ import { execSync } from 'child_process'; import { existsSync, readFileSync, writeFileSync } from 'fs'; import { join } from 'path'; import * as ts from 'typescript'; describe('TypeScript Compilation Pipeline', () => { const projectRoot = process.cwd(); const staticDir = join(projectRoot, 'static'); const tsFilePath = join(staticDir, 'terminal-input-handler.ts'); const jsFilePath = join(staticDir, 'terminal-input-handler.js'); const backupJsPath = join(staticDir, 'terminal-input-handler.js.backup'); beforeAll(() => { // Backup existing JS file if (existsSync(jsFilePath)) { const jsContent = readFileSync(jsFilePath, 'utf8'); writeFileSync(backupJsPath, jsContent); } }); afterAll(() => { // Restore backup if (existsSync(backupJsPath)) { const backupContent = readFileSync(backupJsPath, 'utf8'); writeFileSync(jsFilePath, backupContent); } }); test('TypeScript file exists and has valid syntax', () => { expect(existsSync(tsFilePath)).toBe(true); const tsContent = readFileSync(tsFilePath, 'utf8'); expect(tsContent.length).toBeGreaterThan(100); // Basic TypeScript syntax validation expect(tsContent).toContain('export class TerminalInputHandler'); expect(tsContent).toContain('interface'); expect(tsContent).toContain('private'); expect(tsContent).toContain('public'); }); test('TypeScript can be compiled to JavaScript', () => { const tsContent = readFileSync(tsFilePath, 'utf8'); // TypeScript compiler options for browser-compatible output const compilerOptions: ts.CompilerOptions = { target: ts.ScriptTarget.ES2017, module: ts.ModuleKind.None, // No module system for browser lib: ['ES2017', 'DOM'], strict: false, // Relaxed for browser compatibility esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, removeComments: false, // Keep comments for debugging sourceMap: false, // No source maps needed for static file }; // Compile TypeScript to JavaScript const result = ts.transpileModule(tsContent, { compilerOptions }); expect(result.outputText).toBeDefined(); expect(result.outputText.length).toBeGreaterThan(100); expect(result.diagnostics).toEqual([]); // No compilation errors // Verify compiled output has essential elements expect(result.outputText).toContain('TerminalInputHandler'); expect(result.outputText).toContain('submitCommand'); expect(result.outputText).toContain('command:'); expect(result.outputText).toContain('commandId:'); }); test('Compiled JavaScript maintains protocol compatibility', () => { const tsContent = readFileSync(tsFilePath, 'utf8'); const compilerOptions: ts.CompilerOptions = { target: ts.ScriptTarget.ES2017, module: ts.ModuleKind.None, lib: ['ES2017', 'DOM'], strict: false, removeComments: false, }; const result = ts.transpileModule(tsContent, { compilerOptions }); const compiledJS = result.outputText; // Verify protocol elements are preserved in compilation expect(compiledJS).toContain('terminal_input'); expect(compiledJS).toContain('sessionName'); expect(compiledJS).toContain('command'); // NOT 'data' expect(compiledJS).toContain('commandId'); expect(compiledJS).toContain('cmd_'); expect(compiledJS).toContain('Date.now()'); // Verify WebSocket send structure is correct const submitCommandMatch = compiledJS.match(/webSocket\.send\(JSON\.stringify\(([\s\S]*?)\)\);/); if (submitCommandMatch) { const messageStructure = submitCommandMatch[1]; expect(messageStructure).toContain('command:'); expect(messageStructure).toContain('commandId:'); } }); test('Package.json should have TypeScript build scripts', () => { const packageJsonPath = join(projectRoot, 'package.json'); expect(existsSync(packageJsonPath)).toBe(true); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); // This test documents what scripts should exist for sustainable development const shouldHaveBuildScript = packageJson.scripts?.['build:client'] || packageJson.scripts?.['build:static'] || packageJson.scripts?.['compile:ts']; // Initially this will fail, documenting what needs to be added if (!shouldHaveBuildScript) { expect(true).toBe(false); // Force failure to document requirement } }); test('NPM script compilation should work', () => { // Skip if npm scripts don't exist yet const packageJsonPath = join(projectRoot, 'package.json'); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); const buildScript = packageJson.scripts?.['build:client'] || packageJson.scripts?.['build:static'] || packageJson.scripts?.['compile:ts']; if (!buildScript) { // Document what the script should do expect(buildScript).toBeDefined(); return; } // If script exists, test it works try { execSync('npm run build:client || npm run build:static || npm run compile:ts', { cwd: projectRoot, stdio: 'pipe' }); } catch (error) { expect(true).toBe(false); // Compilation should not fail } // Verify compilation produced valid output expect(existsSync(jsFilePath)).toBe(true); const compiledContent = readFileSync(jsFilePath, 'utf8'); expect(compiledContent).toContain('TerminalInputHandler'); expect(compiledContent).toContain('command:'); expect(compiledContent).toContain('commandId:'); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/LightspeedDMS/ssh-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server