@xec-sh/cli
Version:
Xec: The Universal Shell for TypeScript
172 lines (171 loc) • 5.63 kB
JavaScript
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