UNPKG

@xec-sh/cli

Version:

Xec: The Universal Shell for TypeScript

172 lines (171 loc) 5.63 kB
import chalk from 'chalk'; import { glob } from 'glob'; import * as path from 'path'; import { $ } from '@xec-sh/core'; import { minimatch } from 'minimatch'; import { tasks } from './task-api.js'; import { config } from './config-api.js'; import { targets } from './target-api.js'; import { createTargetEngine } from '../utils/direct-execution.js'; export class ScriptContext { static async create(scriptPath, args = [], target) { const $target = target ? await createTargetEngine(target) : $; const $targetInfo = target ? { type: target.type, name: target.name, host: target.type === 'ssh' ? target.config.host : undefined, container: target.type === 'docker' ? target.config.container : undefined, pod: target.type === 'k8s' ? target.config.pod : undefined, namespace: target.type === 'k8s' ? target.config.namespace : undefined, config: target.config } : undefined; await config.reload(); const vars = config.get('vars') || {}; const params = this.parseParams(args); const scriptInfo = { path: scriptPath, args, target }; return { $target: $target, $targetInfo, $: $, __filename: path.resolve(scriptPath), __dirname: path.dirname(path.resolve(scriptPath)), __script: scriptInfo, config, vars, params, tasks, targets, chalk, glob: (pattern) => glob(pattern), minimatch: (filePath, pattern) => minimatch(filePath, pattern) }; } static inject(context) { const globalAny = global; for (const [key, value] of Object.entries(context)) { globalAny[key] = value; } } static cleanup(context) { const globalAny = global; for (const key of Object.keys(context)) { delete globalAny[key]; } } static parseParams(args) { const params = {}; for (let i = 0; i < args.length; i++) { const arg = args[i]; if (!arg) continue; if (arg.startsWith('--') && arg.includes('=')) { const [key, value] = arg.slice(2).split('=', 2); if (key && value !== undefined) { params[key] = this.parseValue(value); } } else if (arg.startsWith('--') && i + 1 < args.length) { const key = arg.slice(2); const value = args[i + 1]; if (value && !value.startsWith('-')) { params[key] = this.parseValue(value); i++; } else { params[key] = true; } } else if (arg.startsWith('-') && arg.length === 2 && i + 1 < args.length) { const key = arg.slice(1); const value = args[i + 1]; if (value && !value.startsWith('-')) { params[key] = this.parseValue(value); i++; } else { params[key] = true; } } else if (arg.startsWith('-')) { const key = arg.startsWith('--') ? arg.slice(2) : arg.slice(1); params[key] = true; } } return params; } static parseValue(value) { if (value === 'true') return true; if (value === 'false') return false; if (/^-?\d+$/.test(value)) { return parseInt(value, 10); } if (/^-?\d+\.\d+$/.test(value)) { return parseFloat(value); } if (value.startsWith('{') || value.startsWith('[')) { try { return JSON.parse(value); } catch { } } return value; } static async createREPL(target) { const context = await this.create('repl', [], target); const replContext = { ...context, help: () => { console.log(` Available globals: $target - Execute commands on the target $ - Execute commands locally config - Configuration API tasks - Task API targets - Target API chalk - Terminal colors glob - File globbing minimatch - Pattern matching Examples: await $target\`ls -la\` await tasks.run('build') const hosts = await targets.list('ssh') `); }, clear: () => { process.stdout.write('\x1B[2J\x1B[0f'); } }; return replContext; } } export async function executeScript(scriptPath, args = [], target) { const context = await ScriptContext.create(scriptPath, args, target); try { ScriptContext.inject(context); const scriptModule = await import(path.resolve(scriptPath)); if (typeof scriptModule.default === 'function') { await scriptModule.default(...args); } else if (typeof scriptModule.main === 'function') { await scriptModule.main(...args); } else if (typeof scriptModule === 'function') { await scriptModule(...args); } } finally { ScriptContext.cleanup(context); } } //# sourceMappingURL=script-context.js.map