@basictech/cli
Version:
Basic CLI for creating & managing your projects
133 lines • 4.19 kB
JavaScript
import { exec } from 'child_process';
import { promisify } from 'util';
import * as os from 'os';
import * as path from 'path';
import { CONSTANTS, COMMANDS } from './constants.js';
const execAsync = promisify(exec);
export function getConfigPath() {
const home = os.homedir();
return path.join(home, CONSTANTS.CLI_DIR, CONSTANTS.TOKEN_FILE);
}
export function getConfigDir() {
const home = os.homedir();
return path.join(home, CONSTANTS.CLI_DIR);
}
export async function openBrowser(url) {
const platform = process.platform;
const commands = {
darwin: 'open',
win32: 'start',
linux: 'xdg-open'
};
const command = commands[platform];
if (!command) {
throw new Error(`Unsupported platform: ${platform}`);
}
try {
if (platform === 'win32') {
// Windows requires special handling for URLs
await execAsync(`${command} "" "${url}"`);
}
else {
await execAsync(`${command} "${url}"`);
}
}
catch (error) {
throw new Error(`Failed to open browser: ${error}`);
}
}
export async function copyToClipboard(text) {
const platform = process.platform;
try {
if (platform === 'darwin') {
// macOS
await execAsync(`echo "${text}" | pbcopy`);
}
else if (platform === 'win32') {
// Windows
await execAsync(`echo ${text} | clip`);
}
else {
// Linux - try xclip first, then xsel
try {
await execAsync(`echo "${text}" | xclip -selection clipboard`);
}
catch {
await execAsync(`echo "${text}" | xsel --clipboard --input`);
}
}
}
catch (error) {
throw new Error(`Failed to copy to clipboard: ${error}`);
}
}
export function isOnline() {
return fetch(CONSTANTS.API_BASE, { method: 'HEAD' })
.then(() => true)
.catch(() => false);
}
export function generateSlugFromName(name) {
return name
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/[^a-zA-Z-]/g, '');
}
export function generateRandomTeamName() {
// Generate a random number between 1000 and 9999 using crypto
const array = new Uint16Array(1);
crypto.getRandomValues(array);
const randomNum = (array[0] % 9000) + 1000;
return `team-${randomNum}`;
}
export function similarity(s1, s2) {
const d = levenshteinDistance(s1, s2);
const maxLen = Math.max(s1.length, s2.length);
if (maxLen === 0)
return 1.0;
return 1.0 - d / maxLen;
}
function levenshteinDistance(s1, s2) {
if (s1.length === 0)
return s2.length;
if (s2.length === 0)
return s1.length;
const matrix = [];
for (let i = 0; i <= s1.length; i++) {
matrix[i] = [];
matrix[i][0] = i;
}
for (let j = 0; j <= s2.length; j++) {
matrix[0][j] = j;
}
for (let i = 1; i <= s1.length; i++) {
for (let j = 1; j <= s2.length; j++) {
const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;
matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + cost);
}
}
return matrix[s1.length][s2.length];
}
export function findSimilarCommands(input) {
const commands = COMMANDS.filter(cmd => cmd !== input);
const suggestions = [];
for (const command of commands) {
const sim = similarity(input, command);
if (sim >= CONSTANTS.SIMILARITY_THRESHOLD) {
suggestions.push({ command, similarity: sim });
}
}
return suggestions
.sort((a, b) => b.similarity - a.similarity)
.slice(0, 3)
.map(s => s.command);
}
export function generateSlug(name) {
return name
.toLowerCase()
.trim()
.replace(/[^a-z0-9\s-]/g, '') // Remove special characters except spaces and hyphens
.replace(/\s+/g, '-') // Replace spaces with hyphens
.replace(/-+/g, '-') // Replace multiple hyphens with single hyphen
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
}
//# sourceMappingURL=platform.js.map