fix(npx): remove dependency on ora and test command, runs smooth

This commit is contained in:
Waleed Latif
2025-03-04 11:53:10 -08:00
parent 23e3c37750
commit d0f0f479a2
7 changed files with 325 additions and 79 deletions

View File

@@ -1,52 +1,20 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.start = start;
const child_process_1 = require("child_process");
const chalk_1 = __importDefault(require("chalk"));
const config_1 = require("../utils/config");
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const os_1 = __importDefault(require("os"));
const tar_1 = require("tar");
const https_1 = __importDefault(require("https"));
const fs_2 = require("fs");
const child_process_1 = require("child_process");
const child_process_2 = require("child_process");
const fs_1 = __importDefault(require("fs"));
const fs_2 = require("fs");
const https_1 = __importDefault(require("https"));
const os_1 = __importDefault(require("os"));
const path_1 = __importDefault(require("path"));
const tar_1 = require("tar");
const config_1 = require("../utils/config");
const spinner_1 = require("../utils/spinner");
// Constants for standalone app
const SIM_HOME_DIR = path_1.default.join(os_1.default.homedir(), '.sim-studio');
const SIM_STANDALONE_DIR = path_1.default.join(SIM_HOME_DIR, 'standalone');
@@ -63,11 +31,8 @@ async function start(options) {
config_1.config.set('lastRun', new Date().toISOString());
const port = options.port || '3000';
const debug = options.debug || false;
// Dynamically import ora
const oraModule = await Promise.resolve().then(() => __importStar(require('ora')));
const ora = oraModule.default;
// Show starting message
const spinner = ora(`Starting Sim Studio on port ${port}...`).start();
const spinner = (0, spinner_1.createSpinner)(`Starting Sim Studio on port ${port}...`).start();
try {
// Set environment variables for using local storage
const env = {
@@ -88,7 +53,7 @@ async function start(options) {
simProcess = (0, child_process_1.spawn)('npm', ['run', 'dev'], {
env,
stdio: 'inherit',
shell: true
shell: true,
});
}
else {
@@ -132,7 +97,8 @@ async function start(options) {
// Start the standalone app
spinner.text = 'Starting Sim Studio standalone...';
// Make sure the standalone directory exists
if (!fs_1.default.existsSync(SIM_STANDALONE_DIR) || !fs_1.default.existsSync(path_1.default.join(SIM_STANDALONE_DIR, 'server.js'))) {
if (!fs_1.default.existsSync(SIM_STANDALONE_DIR) ||
!fs_1.default.existsSync(path_1.default.join(SIM_STANDALONE_DIR, 'server.js'))) {
spinner.fail('Standalone app files are missing. Re-run to download again.');
// Force a fresh download next time
if (fs_1.default.existsSync(SIM_VERSION_FILE)) {
@@ -149,7 +115,7 @@ async function start(options) {
cwd: SIM_STANDALONE_DIR,
env: standaloneEnv,
stdio: 'inherit',
shell: true
shell: true,
});
}
// Successful start
@@ -215,7 +181,8 @@ async function downloadStandaloneApp(spinner) {
const file = (0, fs_2.createWriteStream)(tarballPath);
spinner.text = 'Downloading Sim Studio...';
// Download the tarball
https_1.default.get(DOWNLOAD_URL, (response) => {
https_1.default
.get(DOWNLOAD_URL, (response) => {
if (response.statusCode !== 200) {
spinner.fail(`Failed to download: ${response.statusCode}`);
return reject(new Error(`Download failed with status code: ${response.statusCode}`));
@@ -233,8 +200,9 @@ async function downloadStandaloneApp(spinner) {
// Extract the tarball
(0, tar_1.extract)({
file: tarballPath,
cwd: SIM_STANDALONE_DIR
}).then(() => {
cwd: SIM_STANDALONE_DIR,
})
.then(() => {
// Clean up
fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
// Install dependencies if needed
@@ -243,24 +211,26 @@ async function downloadStandaloneApp(spinner) {
try {
(0, child_process_2.execSync)('npm install --production', {
cwd: SIM_STANDALONE_DIR,
stdio: 'ignore'
stdio: 'ignore',
});
}
catch (error) {
spinner.warn('Error installing dependencies, but trying to continue...');
}
}
// Save version info
fs_1.default.writeFileSync(SIM_VERSION_FILE, JSON.stringify({ version: STANDALONE_VERSION, installedAt: new Date().toISOString() }));
// Write version file
fs_1.default.writeFileSync(SIM_VERSION_FILE, JSON.stringify({ version: STANDALONE_VERSION, date: new Date().toISOString() }));
spinner.succeed('Sim Studio downloaded successfully');
resolve();
}).catch((err) => {
spinner.fail('Extraction failed');
})
.catch((err) => {
spinner.fail('Failed to extract Sim Studio');
reject(err);
});
});
}).on('error', (err) => {
fs_1.default.unlink(tarballPath, () => { });
spinner.fail('Download failed');
})
.on('error', (err) => {
spinner.fail('Network error');
reject(err);
});
});

View File

@@ -7,11 +7,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
const chalk_1 = __importDefault(require("chalk"));
const commander_1 = require("commander");
const update_notifier_1 = __importDefault(require("update-notifier"));
const start_1 = require("./commands/start");
const help_1 = require("./commands/help");
const start_1 = require("./commands/start");
const version_1 = require("./commands/version");
const logo_1 = require("./utils/logo");
const config_1 = require("./utils/config");
const logo_1 = require("./utils/logo");
// Package info for version checking
const pkg = require('../package.json');
// Check for updates

View File

@@ -0,0 +1,52 @@
/**
* A simple spinner implementation that doesn't rely on external packages
*/
export declare class SimpleSpinner {
private interval;
private frames;
private frameIndex;
private isSpinning;
private lastOutput;
private _text;
constructor(text?: string);
/**
* Start the spinner
*/
start(text?: string): SimpleSpinner;
/**
* Stop the spinner
*/
stop(): SimpleSpinner;
/**
* Update the spinner text
*/
set text(value: string);
/**
* Get the spinner text
*/
get text(): string;
/**
* Show a success message
*/
succeed(text?: string): SimpleSpinner;
/**
* Show a failure message
*/
fail(text?: string): SimpleSpinner;
/**
* Show a warning message
*/
warn(text?: string): SimpleSpinner;
/**
* Show an info message
*/
info(text?: string): SimpleSpinner;
/**
* Stop the spinner and show a symbol with text
*/
private stopWithSymbol;
}
/**
* Create a new spinner
*/
export declare function createSpinner(text?: string): SimpleSpinner;

110
packages/@sim/cli/dist/utils/spinner.js vendored Normal file
View File

@@ -0,0 +1,110 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleSpinner = void 0;
exports.createSpinner = createSpinner;
const chalk_1 = __importDefault(require("chalk"));
/**
* A simple spinner implementation that doesn't rely on external packages
*/
class SimpleSpinner {
constructor(text = '') {
this.interval = null;
this.frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
this.frameIndex = 0;
this.isSpinning = false;
this.lastOutput = '';
this._text = '';
this._text = text;
}
/**
* Start the spinner
*/
start(text) {
if (text) {
this._text = text;
}
if (!this.isSpinning) {
this.isSpinning = true;
this.frameIndex = 0;
// Clear any previous output
if (this.lastOutput) {
process.stdout.write('\r' + ' '.repeat(this.lastOutput.length) + '\r');
}
this.interval = setInterval(() => {
const frame = this.frames[this.frameIndex];
const output = `${chalk_1.default.cyan(frame)} ${this._text}`;
process.stdout.write('\r' + output);
this.lastOutput = output;
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
}, 80);
}
return this;
}
/**
* Stop the spinner
*/
stop() {
if (this.isSpinning && this.interval) {
clearInterval(this.interval);
this.interval = null;
this.isSpinning = false;
// Clear the spinner line
process.stdout.write('\r' + ' '.repeat(this.lastOutput.length) + '\r');
}
return this;
}
/**
* Update the spinner text
*/
set text(value) {
this._text = value;
}
/**
* Get the spinner text
*/
get text() {
return this._text;
}
/**
* Show a success message
*/
succeed(text) {
return this.stopWithSymbol(chalk_1.default.green('✓'), text || this._text);
}
/**
* Show a failure message
*/
fail(text) {
return this.stopWithSymbol(chalk_1.default.red('✗'), text || this._text);
}
/**
* Show a warning message
*/
warn(text) {
return this.stopWithSymbol(chalk_1.default.yellow('⚠'), text || this._text);
}
/**
* Show an info message
*/
info(text) {
return this.stopWithSymbol(chalk_1.default.blue(''), text || this._text);
}
/**
* Stop the spinner and show a symbol with text
*/
stopWithSymbol(symbol, text) {
this.stop();
console.log(`${symbol} ${text}`);
return this;
}
}
exports.SimpleSpinner = SimpleSpinner;
/**
* Create a new spinner
*/
function createSpinner(text) {
return new SimpleSpinner(text);
}

View File

@@ -35,7 +35,6 @@
"conf": "^10.2.0",
"dotenv": "^16.4.7",
"inquirer": "^8.2.6",
"ora": "^8.2.0",
"tar": "^6.2.1",
"update-notifier": "^5.1.0"
},

View File

@@ -4,11 +4,11 @@ import { execSync } from 'child_process'
import fs from 'fs'
import { createWriteStream } from 'fs'
import https from 'https'
import type { Ora } from 'ora'
import os from 'os'
import path from 'path'
import { extract } from 'tar'
import { config } from '../utils/config'
import { SimpleSpinner, createSpinner } from '../utils/spinner'
interface StartOptions {
port: string
@@ -35,12 +35,8 @@ export async function start(options: StartOptions) {
const port = options.port || '3000'
const debug = options.debug || false
// Dynamically import ora
const oraModule = await import('ora')
const ora = oraModule.default
// Show starting message
const spinner = ora(`Starting Sim Studio on port ${port}...`).start()
const spinner = createSpinner(`Starting Sim Studio on port ${port}...`).start()
try {
// Set environment variables for using local storage
@@ -203,7 +199,7 @@ function checkIfInProjectDirectory(): boolean {
/**
* Downloads and extracts the standalone app
*/
async function downloadStandaloneApp(spinner: Ora): Promise<void> {
async function downloadStandaloneApp(spinner: SimpleSpinner): Promise<void> {
return new Promise((resolve, reject) => {
// Create temp directory
const tmpDir = path.join(os.tmpdir(), `sim-download-${Date.now()}`)
@@ -260,26 +256,23 @@ async function downloadStandaloneApp(spinner: Ora): Promise<void> {
}
}
// Save version info
// Write version file
fs.writeFileSync(
SIM_VERSION_FILE,
JSON.stringify({
version: STANDALONE_VERSION,
installedAt: new Date().toISOString(),
})
JSON.stringify({ version: STANDALONE_VERSION, date: new Date().toISOString() })
)
spinner.succeed('Sim Studio downloaded successfully')
resolve()
})
.catch((err: Error) => {
spinner.fail('Extraction failed')
.catch((err) => {
spinner.fail('Failed to extract Sim Studio')
reject(err)
})
})
})
.on('error', (err: Error) => {
fs.unlink(tarballPath, () => {})
spinner.fail('Download failed')
.on('error', (err) => {
spinner.fail('Network error')
reject(err)
})
})

View File

@@ -0,0 +1,122 @@
import chalk from 'chalk'
/**
* A simple spinner implementation that doesn't rely on external packages
*/
export class SimpleSpinner {
private interval: NodeJS.Timeout | null = null
private frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
private frameIndex = 0
private isSpinning = false
private lastOutput = ''
private _text: string = ''
constructor(text: string = '') {
this._text = text
}
/**
* Start the spinner
*/
start(text?: string): SimpleSpinner {
if (text) {
this._text = text
}
if (!this.isSpinning) {
this.isSpinning = true
this.frameIndex = 0
// Clear any previous output
if (this.lastOutput) {
process.stdout.write('\r' + ' '.repeat(this.lastOutput.length) + '\r')
}
this.interval = setInterval(() => {
const frame = this.frames[this.frameIndex]
const output = `${chalk.cyan(frame)} ${this._text}`
process.stdout.write('\r' + output)
this.lastOutput = output
this.frameIndex = (this.frameIndex + 1) % this.frames.length
}, 80)
}
return this
}
/**
* Stop the spinner
*/
stop(): SimpleSpinner {
if (this.isSpinning && this.interval) {
clearInterval(this.interval)
this.interval = null
this.isSpinning = false
// Clear the spinner line
process.stdout.write('\r' + ' '.repeat(this.lastOutput.length) + '\r')
}
return this
}
/**
* Update the spinner text
*/
set text(value: string) {
this._text = value
}
/**
* Get the spinner text
*/
get text(): string {
return this._text
}
/**
* Show a success message
*/
succeed(text?: string): SimpleSpinner {
return this.stopWithSymbol(chalk.green('✓'), text || this._text)
}
/**
* Show a failure message
*/
fail(text?: string): SimpleSpinner {
return this.stopWithSymbol(chalk.red('✗'), text || this._text)
}
/**
* Show a warning message
*/
warn(text?: string): SimpleSpinner {
return this.stopWithSymbol(chalk.yellow('⚠'), text || this._text)
}
/**
* Show an info message
*/
info(text?: string): SimpleSpinner {
return this.stopWithSymbol(chalk.blue(''), text || this._text)
}
/**
* Stop the spinner and show a symbol with text
*/
private stopWithSymbol(symbol: string, text: string): SimpleSpinner {
this.stop()
console.log(`${symbol} ${text}`)
return this
}
}
/**
* Create a new spinner
*/
export function createSpinner(text?: string): SimpleSpinner {
return new SimpleSpinner(text)
}