@labnex/cli
Version:
CLI for Labnex, an AI-Powered Testing Automation Platform
185 lines • 8.85 kB
JavaScript
"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.runWelcomeWizard = runWelcomeWizard;
const inquirer_1 = __importDefault(require("inquirer"));
const chalk_1 = __importDefault(require("chalk"));
// Note: 'open' is ESM-only; we'll load it dynamically when needed to avoid CommonJS require issues
const client_1 = require("./api/client");
const projectConfig_1 = require("./utils/projectConfig");
const axios_1 = __importDefault(require("axios"));
async function runWelcomeWizard() {
console.log(chalk_1.default.bold.cyan('\n┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓'));
console.log(chalk_1.default.bold.cyan('┃ Welcome to the Labnex CLI! ┃'));
console.log(chalk_1.default.bold.cyan('┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛'));
console.log(chalk_1.default.gray('Let\'s get you set up in just a few steps.\n'));
// Step 1: API Key
let apiKey = '';
while (!apiKey) {
const { method } = await inquirer_1.default.prompt([
{
type: 'list',
name: 'method',
message: 'How would you like to authenticate?',
choices: [
{ name: 'Paste existing API key', value: 'paste' },
{ name: 'Open dashboard to create key', value: 'open' },
],
},
]);
if (method === 'open') {
const { default: open } = await Promise.resolve().then(() => __importStar(require('open')));
await open('https://app.labnex.ai/settings/api-keys');
console.log(chalk_1.default.cyan('Browser opened. Once you\'ve created a key, come back and paste it below.'));
}
const { key } = await inquirer_1.default.prompt([
{
type: 'password',
mask: '*',
name: 'key',
message: 'Paste your Labnex API key:',
validate: (val) => val.trim() !== '' || 'API key cannot be empty',
},
]);
apiKey = key.trim();
// Validate key by hitting /auth/me directly
try {
const base = process.env.LABNEX_API_URL || 'https://labnex-backend.onrender.com/api';
await axios_1.default.get(base + '/auth/me', { headers: { Authorization: `Bearer ${apiKey}` }, timeout: 10000 });
}
catch {
console.log(chalk_1.default.red('Invalid or unauthorized API key, please try again.'));
apiKey = '';
}
}
// Update token in config
const baseCfg = { token: apiKey };
// Step 2: Select or create project
let projectId = '';
try {
// Temporarily inject token into global apiClient for subsequent calls during wizard
process.env.LABNEX_API_TOKEN_TEMP = apiKey;
// Monkey patch loadConfig to return the token during wizard
const cfgUtils = require('./utils/config');
const originalLoadConfig = cfgUtils.loadConfig;
cfgUtils.loadConfig = async () => ({ apiUrl: process.env.LABNEX_API_URL || 'https://labnex-backend.onrender.com/api', token: apiKey });
const projectsResp = await client_1.apiClient.getProjects();
if (projectsResp.success && projectsResp.data.length > 0) {
const choices = projectsResp.data.map((p) => ({
name: `${p.name} (${p.projectCode})`,
value: p._id,
}));
choices.push({ name: chalk_1.default.yellow('<Create new project>'), value: '__create__' });
const { chosen } = await inquirer_1.default.prompt([
{
type: 'list',
name: 'chosen',
message: 'Select a project to work with:',
choices,
},
]);
if (chosen === '__create__') {
const { name } = await inquirer_1.default.prompt({ type: 'input', name: 'name', message: 'Project name:' });
const { code } = await inquirer_1.default.prompt({ type: 'input', name: 'code', message: 'Project code (optional):' });
const createResp = await client_1.apiClient.createProject({ name, projectCode: code || undefined });
if (createResp.success) {
projectId = createResp.data._id;
console.log(chalk_1.default.green(`Project created: ${createResp.data.projectCode}`));
}
}
else {
projectId = chosen;
}
}
else {
console.log(chalk_1.default.yellow('No projects found. Let\'s create one.'));
const { name } = await inquirer_1.default.prompt({ type: 'input', name: 'name', message: 'Project name:' });
const { code } = await inquirer_1.default.prompt({ type: 'input', name: 'code', message: 'Project code (optional):' });
const createResp = await client_1.apiClient.createProject({ name, projectCode: code || undefined });
if (createResp.success) {
projectId = createResp.data._id;
console.log(chalk_1.default.green(`Project created: ${createResp.data.projectCode}`));
}
}
// Restore original loadConfig after project selection
cfgUtils.loadConfig = originalLoadConfig;
}
catch (err) {
console.log(chalk_1.default.red('Error fetching/creating project:'), err.message);
}
// Step 3: Default baseUrl
const { baseUrl } = await inquirer_1.default.prompt([
{
type: 'input',
name: 'baseUrl',
message: 'Enter a default base URL for this project (e.g., https://example.com):',
validate: (val) => /^https?:\/\//i.test(val) || 'Please enter a valid http(s) URL',
},
]);
const { rememberBase } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'rememberBase',
message: 'Save this base URL in labnex.config.json inside this directory?',
default: true,
},
]);
if (rememberBase) {
(0, projectConfig_1.saveProjectConfig)({ baseUrl });
console.log(chalk_1.default.green('Saved base URL to labnex.config.json'));
}
// Step 4: Offer example test
const { runExample } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'runExample',
message: 'Would you like to run an example test now?',
default: false,
},
]);
// Persist global config now
const { updateConfig } = require('./utils/config');
await updateConfig(baseCfg);
console.log(chalk_1.default.green('\nSetup complete! You\'re ready to use Labnex CLI.'));
console.log(chalk_1.default.cyan('Tip: Run `labnex run --help` to see available options.'));
if (runExample) {
const { runCommand } = await Promise.resolve().then(() => __importStar(require('./commands/run')));
await runCommand.parseAsync(['node', 'labnex', 'run', '--project', projectId, '--base-url', baseUrl]);
}
}
//# sourceMappingURL=welcomeWizard.js.map