UNPKG

@xec-sh/cli

Version:

Xec: The Universal Shell for TypeScript

243 lines 7.68 kB
export function deepMerge(target, source, options) { if (source === null || source === undefined) { return target; } if (target === null || target === undefined) { return source; } if (typeof source !== 'object' || typeof target !== 'object') { return source; } if (Array.isArray(source)) { if (Array.isArray(target) && source[0] === '$merge') { return [...target, ...source.slice(1)]; } return source; } const result = { ...target }; for (const key of Object.keys(source)) { const sourceValue = source[key]; if (options?.skipUndefined && sourceValue === undefined) { continue; } if (sourceValue === '$unset') { delete result[key]; continue; } if (Array.isArray(sourceValue)) { if (Array.isArray(result[key]) && sourceValue[0] === '$merge') { result[key] = [...result[key], ...sourceValue.slice(1)]; } else { result[key] = sourceValue; } } else if (sourceValue && typeof sourceValue === 'object' && result[key] && typeof result[key] === 'object' && !Array.isArray(result[key])) { result[key] = deepMerge(result[key], sourceValue, options); } else { result[key] = sourceValue; } } return result; } export function parseDuration(duration) { if (typeof duration === 'number') { return duration; } const match = duration.match(/^(\d+)(ms|s|m|h)?$/); if (!match) { throw new Error(`Invalid duration format: ${duration}`); } const value = parseInt(match[1] || '0', 10); const unit = match[2] || 'ms'; switch (unit) { case 'ms': return value; case 's': return value * 1000; case 'm': return value * 60 * 1000; case 'h': return value * 60 * 60 * 1000; default: throw new Error(`Unknown duration unit: ${unit}`); } } export function formatDuration(ms) { if (ms < 1000) { return `${ms}ms`; } const seconds = Math.floor(ms / 1000); if (seconds < 60) { return `${seconds}s`; } const minutes = Math.floor(seconds / 60); if (minutes < 60) { return `${minutes}m`; } const hours = Math.floor(minutes / 60); return `${hours}h`; } export function parseMemorySize(size) { if (typeof size === 'number') { return size; } const match = size.match(/^(\d+)([A-Z]*)?$/i); if (!match) { throw new Error(`Invalid memory size format: ${size}`); } const value = parseInt(match[1] || '0', 10); const unit = (match[2] || 'B').toUpperCase(); switch (unit) { case 'B': return value; case 'K': case 'KB': return value * 1024; case 'M': case 'MB': return value * 1024 * 1024; case 'G': case 'GB': return value * 1024 * 1024 * 1024; default: throw new Error(`Unknown memory size unit: ${unit}`); } } export function isValidTargetReference(ref) { if (ref.includes(':')) { const parts = ref.split(':', 2); const type = parts[0] || ''; const name = parts[1] || ''; return ['docker', 'pod', 'ssh'].includes(type) && !!name && name.length > 0; } if (ref.includes('.')) { const firstDotIndex = ref.indexOf('.'); const type = ref.substring(0, firstDotIndex); const name = ref.substring(firstDotIndex + 1); if (['hosts', 'containers', 'pods', 'local'].includes(type)) { return !!name && name.length > 0; } const commonTLDs = ['com', 'org', 'net', 'io', 'dev', 'app', 'co', 'me', 'info', 'biz']; const lastDotIndex = ref.lastIndexOf('.'); const possibleTLD = ref.substring(lastDotIndex + 1); if (commonTLDs.includes(possibleTLD.toLowerCase())) { return true; } const dotCount = (ref.match(/\./g) || []).length; if (dotCount === 1 && type.match(/^[a-z]+$/) && name.match(/^[a-z][a-z0-9-]*$/)) { return false; } } if (ref === 'local') { return true; } return ref.length > 0; } export function parseTargetReference(ref) { if (ref === 'local') { return { type: 'local', isWildcard: false }; } if (ref.includes(':')) { const parts = ref.split(':', 2); const prefix = parts[0] || ''; const name = parts[1] || ''; const typeMap = { 'ssh': 'hosts', 'docker': 'containers', 'pod': 'pods', 'k8s': 'pods' }; return { type: typeMap[prefix] || 'auto', name, isWildcard: !!name && (name.includes('*') || name.includes('?')) }; } if (ref.includes('.')) { const firstDotIndex = ref.indexOf('.'); const type = ref.substring(0, firstDotIndex); const name = ref.substring(firstDotIndex + 1); if (['hosts', 'containers', 'pods'].includes(type)) { return { type: type, name, isWildcard: !!name && (name.includes('*') || name.includes('?')) }; } } return { type: 'auto', name: ref, isWildcard: ref.includes('*') || ref.includes('?') }; } export function matchPattern(pattern, str) { const regexPattern = pattern .split('*').map(part => part.split('?').map(escapeRegex).join('.')) .join('.*'); const regex = new RegExp(`^${regexPattern}$`); return regex.test(str); } function escapeRegex(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } export function expandBraces(pattern) { const match = pattern.match(/^(.*)\{([^}]+)\}(.*)$/); if (!match) { return [pattern]; } const [, prefix, items, suffix] = match; const expanded = []; if (!items) { return [pattern]; } for (const item of items.split(',')) { const trimmed = item.trim(); const rangeMatch = trimmed.match(/^(\d+)\.\.(\d+)$/); if (rangeMatch) { const start = parseInt(rangeMatch[1] || '0', 10); const end = parseInt(rangeMatch[2] || '0', 10); for (let i = start; i <= end; i++) { expanded.push(`${prefix || ''}${i}${suffix || ''}`); } } else { expanded.push(`${prefix || ''}${trimmed}${suffix || ''}`); } } return expanded.flatMap(item => expandBraces(item)); } export function flattenObject(obj, prefix = '') { const flattened = {}; for (const [key, value] of Object.entries(obj)) { const fullKey = prefix ? `${prefix}.${key}` : key; if (value && typeof value === 'object' && !Array.isArray(value)) { Object.assign(flattened, flattenObject(value, fullKey)); } else { flattened[fullKey] = value; } } return flattened; } export function isCI() { return !!(process.env['CI'] || process.env['GITHUB_ACTIONS'] || process.env['GITLAB_CI'] || process.env['CIRCLECI'] || process.env['JENKINS_URL'] || process.env['TEAMCITY_VERSION']); } export function getDefaultShell() { if (process.platform === 'win32') { return process.env['COMSPEC'] || 'cmd.exe'; } return process.env['SHELL'] || '/bin/sh'; } //# sourceMappingURL=utils.js.map