UNPKG

@typecad/typecad

Version:

🤖programmatically 💥create 🛰️hardware

168 lines (148 loc) 5.42 kB
import { watch } from 'fs'; import { exec } from 'child_process'; import chalk from 'chalk'; import { fileURLToPath } from 'url'; import { dirname, basename } from 'path'; import * as ts from 'typescript'; import { promisify } from 'util'; import { readFile, writeFile } from 'fs/promises'; import JavaScriptObfuscator from 'javascript-obfuscator'; const execAsync = promisify(exec); const filesToWatch = [ 'index.ts', 'component.ts', 'pcb.ts', 'pcb_registry.ts', 'pcb_kicad_window.ts', 'pcb_track_builder.ts', 'pcb_interfaces.ts', 'schematic.ts', 'buses.ts', 'config.ts', 'erc.ts', 'kicad.ts', 'pin.ts', 'reference_counter.ts', 'component_registry.ts' ]; // Debounce timers for each file const debounceTimers = new Map(); const DEBOUNCE_DELAY = 500; console.log(chalk.blue('🔍 Watching files for changes...')); console.log(chalk.gray('Watching:')); filesToWatch.forEach(file => console.log(chalk.gray(` - ${file}`))); async function compileFile(file) { // console.log('Debug: ts object:', typeof ts !== 'undefined' ? 'defined' : 'undefined'); // if (ts) { // console.log('Debug: ts.version:', ts.version); // console.log('Debug: ts.default:', typeof ts.default !== 'undefined' ? 'defined' : 'undefined'); // if (ts.default) { // console.log('Debug: ts.default.ScriptTarget:', ts.default.ScriptTarget); // console.log('Debug: ts.default.ModuleKind:', ts.default.ModuleKind); // console.log('Debug: ts.default.ModuleResolutionKind:', ts.default.ModuleResolutionKind); // console.log('Debug: ts.default.ScriptTarget.ES2021:', ts.default.ScriptTarget?.ES2021); // console.log('Debug: ts.default.ModuleKind.ES2020:', ts.default.ModuleKind?.ES2020); // console.log('Debug: ts.default.ModuleResolutionKind.NodeJs:', ts.default.ModuleResolutionKind?.NodeJs); // } else { // // Log original paths if ts.default is not present // console.log('Debug: ts.ScriptTarget (direct):', ts.ScriptTarget); // console.log('Debug: ts.ModuleKind (direct):', ts.ModuleKind); // console.log('Debug: ts.ModuleResolutionKind (direct):', ts.ModuleResolutionKind); // } // } const tsApi = ts.default; const program = tsApi.createProgram([file], { target: tsApi.ScriptTarget.ES2021, module: tsApi.ModuleKind.ES2020, moduleResolution: tsApi.ModuleResolutionKind.NodeJs, // Changed from Node to NodeJs esModuleInterop: true, outDir: 'dist', declaration: true }); const emitResult = program.emit(); const diagnostics = tsApi.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); if (diagnostics.length > 0) { throw new Error(tsApi.formatDiagnosticsWithColorAndContext(diagnostics, { getCurrentDirectory: () => process.cwd(), getCanonicalFileName: fileName => fileName, getNewLine: () => tsApi.sys.newLine })); } } async function obfuscateFile(file) { const fileName = basename(file, '.ts'); const inputPath = `dist/${fileName}.js`; const outputPath = `dist/${fileName}.js`; const code = await readFile(inputPath, 'utf8'); const obfuscatedCode = JavaScriptObfuscator.obfuscate(code, { compact: true, controlFlowFlattening: true, controlFlowFlatteningThreshold: 0.5, deadCodeInjection: false, debugProtection: false, disableConsoleOutput: false, identifierNamesGenerator: "hexadecimal", numbersToExpressions: true, renameGlobals: false, selfDefending: false, simplify: true, splitStrings: true, splitStringsChunkLength: 10, stringArray: true, stringArrayCallsTransform: true, stringArrayCallsTransformThreshold: 0.5, stringArrayEncoding: ["base64"], stringArrayIndexShift: true, stringArrayRotate: true, stringArrayShuffle: true, stringArrayWrappersCount: 1, stringArrayWrappersChainedCalls: true, stringArrayWrappersParametersMaxCount: 2, stringArrayWrappersType: "function", stringArrayThreshold: 0.5, transformObjectKeys: true, unicodeEscapeSequence: false }); await writeFile(outputPath, obfuscatedCode.getObfuscatedCode()); } async function rebuild(file) { console.log(chalk.yellow(`\n🔄 Changes detected in ${file}`)); console.log(chalk.gray('Building and obfuscating...')); const startTime = Date.now(); try { await compileFile(file); await obfuscateFile(file); const endTime = Date.now(); const duration = endTime - startTime; console.log(chalk.green(`✅ Build completed in ${duration}ms`)); console.log(chalk.gray('Watching for changes...')); } catch (error) { console.error(chalk.red('❌ Build failed:')); console.error(error.message); } } function debouncedRebuild(file) { if (debounceTimers.has(file)) { clearTimeout(debounceTimers.get(file)); } const timer = setTimeout(() => { rebuild(file); debounceTimers.delete(file); }, DEBOUNCE_DELAY); debounceTimers.set(file, timer); } // Initial build console.log(chalk.blue('🏗️ Running initial build...')); Promise.all(filesToWatch.map(compileFile)) .then(() => console.log(chalk.green('✅ Initial build completed'))) .catch(error => { console.error(chalk.red('❌ Initial build failed:')); console.error(error.message); }); filesToWatch.forEach(file => { watch(file, (eventType) => { if (eventType === 'change') { debouncedRebuild(file); } }); });