Fix bin/publish: use correct .env path for rspade_system Fix bin/publish script: prevent grep exit code 1 from terminating script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
218 lines
5.9 KiB
JavaScript
Executable File
218 lines
5.9 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* JQHTML Official CLI Compiler
|
|
*
|
|
* Compiles .jqhtml templates to JavaScript with multiple output formats
|
|
* Uses unified compiler module for single source of truth
|
|
*/
|
|
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import { compileTemplate } from '../dist/index.js';
|
|
import { readFileSync } from 'fs';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
// Get package version
|
|
const packagePath = path.join(path.dirname(__dirname), 'package.json');
|
|
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
const VERSION = packageJson.version;
|
|
|
|
// Parse command line arguments
|
|
function parseArgs(argv) {
|
|
const args = {
|
|
input: null,
|
|
output: null,
|
|
format: 'iife',
|
|
sourcemap: false,
|
|
statusJson: false,
|
|
help: false,
|
|
version: false
|
|
};
|
|
|
|
for (let i = 2; i < argv.length; i++) {
|
|
const arg = argv[i];
|
|
|
|
if (arg === '--help' || arg === '-h') {
|
|
args.help = true;
|
|
} else if (arg === '--version' || arg === '-v') {
|
|
args.version = true;
|
|
} else if (arg === '--output' || arg === '-o') {
|
|
args.output = argv[++i];
|
|
if (!args.output) {
|
|
throw new Error('--output requires a file path');
|
|
}
|
|
} else if (arg === '--format') {
|
|
args.format = argv[++i];
|
|
if (!['iife', 'esm', 'cjs', 'umd'].includes(args.format)) {
|
|
throw new Error(`Invalid format: ${args.format}. Must be one of: iife, esm, cjs, umd`);
|
|
}
|
|
} else if (arg === '--sourcemap') {
|
|
args.sourcemap = true;
|
|
} else if (arg === '--status-json') {
|
|
args.statusJson = true;
|
|
} else if (!arg.startsWith('-')) {
|
|
args.input = arg;
|
|
}
|
|
}
|
|
|
|
return args;
|
|
}
|
|
|
|
// Show help message
|
|
function showHelp() {
|
|
console.log(`
|
|
JQHTML CLI Compiler v${VERSION}
|
|
|
|
Usage: jqhtml-compile <input.jqhtml> [options]
|
|
|
|
Options:
|
|
--output, -o <file> Write output to file instead of stdout
|
|
--format <format> Output format: iife|esm|cjs|umd (default: iife)
|
|
--sourcemap Include inline sourcemap
|
|
--status-json Output errors as JSON for programmatic parsing
|
|
--version, -v Show version number
|
|
--help, -h Show this help message
|
|
|
|
Examples:
|
|
jqhtml compile component.jqhtml
|
|
jqhtml compile component.jqhtml --output component.js
|
|
jqhtml compile component.jqhtml --format esm --sourcemap
|
|
jqhtml compile component.jqhtml -o dist/component.js --format umd
|
|
|
|
Output formats:
|
|
iife - Self-executing function that registers with window.jqhtml
|
|
esm - ES module export
|
|
cjs - CommonJS module.exports
|
|
umd - Universal module (works as AMD, CommonJS, or global)
|
|
`);
|
|
}
|
|
|
|
|
|
// Main compilation function
|
|
async function compile(inputFile, options) {
|
|
try {
|
|
// Read input file
|
|
const inputPath = path.resolve(inputFile);
|
|
if (!fs.existsSync(inputPath)) {
|
|
throw new Error(`Input file not found: ${inputPath}`);
|
|
}
|
|
|
|
const source = fs.readFileSync(inputPath, 'utf-8');
|
|
const filename = path.basename(inputPath);
|
|
|
|
// Use unified compiler
|
|
const compiled = compileTemplate(source, filename, {
|
|
format: options.format,
|
|
sourcemap: options.sourcemap,
|
|
version: VERSION
|
|
});
|
|
|
|
const formattedCode = compiled.code;
|
|
|
|
if (options.statusJson) {
|
|
// Output as JSON for programmatic consumption
|
|
const result = {
|
|
status: 'success',
|
|
result: formattedCode
|
|
};
|
|
if (options.output) {
|
|
result.outputFile = options.output;
|
|
}
|
|
console.log(JSON.stringify(result));
|
|
} else if (options.output) {
|
|
// Write to output file
|
|
const outputPath = path.resolve(options.output);
|
|
const outputDir = path.dirname(outputPath);
|
|
|
|
// Create output directory if it doesn't exist
|
|
if (!fs.existsSync(outputDir)) {
|
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
}
|
|
|
|
fs.writeFileSync(outputPath, formattedCode, 'utf-8');
|
|
console.log(`✓ Compiled ${inputFile} → ${options.output}`);
|
|
} else {
|
|
// Output the compiled code to stdout without trailing newline
|
|
process.stdout.write(formattedCode);
|
|
}
|
|
|
|
return 0; // Success
|
|
} catch (error) {
|
|
if (options.statusJson) {
|
|
// Output error as JSON
|
|
const errorObj = {
|
|
status: 'error',
|
|
error: {
|
|
type: error.constructor.name,
|
|
message: error.message,
|
|
file: error.filename || null,
|
|
line: error.line || null,
|
|
column: error.column || null,
|
|
context: error.context || null,
|
|
suggestion: error.suggestion || null
|
|
}
|
|
};
|
|
console.log(JSON.stringify(errorObj));
|
|
} else {
|
|
// Output error to stderr
|
|
console.error(`Error: ${error.message}`);
|
|
if (error.line) {
|
|
console.error(` at line ${error.line}, column ${error.column || 0}`);
|
|
}
|
|
if (error.context) {
|
|
console.error(` context: ${error.context}`);
|
|
}
|
|
if (error.suggestion) {
|
|
console.error(` suggestion: ${error.suggestion}`);
|
|
}
|
|
}
|
|
return 1; // Error
|
|
}
|
|
}
|
|
|
|
// Main entry point
|
|
async function main() {
|
|
try {
|
|
const args = parseArgs(process.argv);
|
|
|
|
if (args.help) {
|
|
showHelp();
|
|
process.exit(0);
|
|
}
|
|
|
|
if (args.version) {
|
|
console.log(`v${VERSION}`);
|
|
process.exit(0);
|
|
}
|
|
|
|
if (!args.input) {
|
|
if (args.statusJson) {
|
|
console.log(JSON.stringify({
|
|
status: 'error',
|
|
error: {
|
|
type: 'ArgumentError',
|
|
message: 'No input file specified'
|
|
}
|
|
}));
|
|
} else {
|
|
console.error('Error: No input file specified');
|
|
console.error('Usage: jqhtml compile <input.jqhtml> [options]');
|
|
console.error('Use --help for more information');
|
|
}
|
|
process.exit(1);
|
|
}
|
|
|
|
const exitCode = await compile(args.input, args);
|
|
process.exit(exitCode);
|
|
} catch (error) {
|
|
console.error('Fatal error:', error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Run the CLI
|
|
main(); |