Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@insforge/cli",
"version": "0.1.49",
"version": "0.1.50",
"description": "InsForge CLI - Command line tool for InsForge platform",
"type": "module",
"bin": {
Expand Down
35 changes: 18 additions & 17 deletions src/commands/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { promisify } from 'node:util';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import * as clack from '@clack/prompts';
import * as prompts from '../lib/prompts.js';
import {
listOrganizations,
createProject,
Expand Down Expand Up @@ -181,15 +182,15 @@ export function registerCreateCommand(program: Command): void {
if (json) {
throw new CLIError('Multiple organizations found. Specify --org-id.');
}
const selected = await clack.select({
const selected = await prompts.select<string>({
message: 'Select an organization:',
options: orgs.map((o) => ({
value: o.id,
label: o.name,
})),
});
if (clack.isCancel(selected)) process.exit(0);
orgId = selected as string;
if (prompts.isCancel(selected)) process.exit(0);
orgId = selected;
}
}

Expand All @@ -203,13 +204,13 @@ export function registerCreateCommand(program: Command): void {
if (!projectName) {
if (json) throw new CLIError('--name is required in JSON mode.');
const defaultName = getDefaultProjectName();
const name = await clack.text({
const name = await prompts.text({
message: 'Project name:',
...(defaultName ? { initialValue: defaultName } : {}),
validate: (v) => (v.length >= 2 ? undefined : 'Name must be at least 2 characters'),
});
if (clack.isCancel(name)) process.exit(0);
projectName = name as string;
if (prompts.isCancel(name)) process.exit(0);
projectName = name;
}

// Sanitize project name to prevent path traversal
Expand All @@ -228,23 +229,23 @@ export function registerCreateCommand(program: Command): void {
if (json) {
template = 'empty';
} else {
const approach = await clack.select({
const approach = await prompts.select<string>({
message: 'How would you like to start?',
options: [
{ value: 'blank', label: 'Blank project', hint: 'Start from scratch with .env.local ready' },
{ value: 'template', label: 'Start from a template', hint: 'Pre-built starter apps' },
],
});
if (clack.isCancel(approach)) process.exit(0);
if (prompts.isCancel(approach)) process.exit(0);

captureEvent(orgId, 'create_approach_selected', {
approach: approach as string,
approach,
});

if (approach === 'blank') {
template = 'empty';
} else {
const selected = await clack.select({
const selected = await prompts.select<string>({
message: 'Choose a starter template:',
options: [
{ value: 'react', label: 'Web app template with React' },
Expand All @@ -255,8 +256,8 @@ export function registerCreateCommand(program: Command): void {
{ value: 'todo', label: 'Todo app with Next.js' },
],
});
if (clack.isCancel(selected)) process.exit(0);
template = selected as string;
if (prompts.isCancel(selected)) process.exit(0);
template = selected;
}
}
}
Expand All @@ -275,7 +276,7 @@ export function registerCreateCommand(program: Command): void {
if (hasTemplate) {
dirName = projectName;
if (!json) {
const inputDir = await clack.text({
const inputDir = await prompts.text({
message: 'Directory name:',
initialValue: projectName,
validate: (v) => {
Expand All @@ -285,8 +286,8 @@ export function registerCreateCommand(program: Command): void {
return undefined;
},
});
if (clack.isCancel(inputDir)) process.exit(0);
dirName = path.basename(inputDir as string).replace(/[^a-zA-Z0-9._-]/g, '-');
if (prompts.isCancel(inputDir)) process.exit(0);
dirName = path.basename(inputDir).replace(/[^a-zA-Z0-9._-]/g, '-');
}

// Validate normalized dirName
Expand Down Expand Up @@ -396,11 +397,11 @@ export function registerCreateCommand(program: Command): void {
// 9. Offer to deploy (template projects, interactive mode only)
let liveUrl: string | null = null;
if (templateDownloaded && !json) {
const shouldDeploy = await clack.confirm({
const shouldDeploy = await prompts.confirm({
message: 'Would you like to deploy now?',
});

if (!clack.isCancel(shouldDeploy) && shouldDeploy) {
if (!prompts.isCancel(shouldDeploy) && shouldDeploy) {
try {
// Read env vars from .env.local or .env to pass to deployment
const envVars = await readEnvFile(process.cwd());
Expand Down
6 changes: 3 additions & 3 deletions src/commands/deployments/cancel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Command } from 'commander';
import * as clack from '@clack/prompts';
import * as prompts from '../../lib/prompts.js';
import { ossFetch } from '../../lib/api/oss.js';
import { requireAuth } from '../../lib/credentials.js';
import { getProjectConfig } from '../../lib/config.js';
Expand All @@ -17,10 +17,10 @@ export function registerDeploymentsCancelCommand(deploymentsCmd: Command): void
if (!getProjectConfig()) throw new ProjectNotLinkedError();

if (!yes && !json) {
const confirmed = await clack.confirm({
const confirmed = await prompts.confirm({
message: `Cancel deployment ${id}?`,
});
if (clack.isCancel(confirmed) || !confirmed) process.exit(0);
if (prompts.isCancel(confirmed) || !confirmed) process.exit(0);
}

const res = await ossFetch(`/api/deployments/${id}/cancel`, { method: 'POST' });
Expand Down
5 changes: 3 additions & 2 deletions src/commands/diagnose/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Command } from 'commander';
import * as os from 'node:os';
import * as clack from '@clack/prompts';
import * as prompts from '../../lib/prompts.js';
import { requireAuth } from '../../lib/credentials.js';
import { handleError, getRootOpts, CLIError, ProjectNotLinkedError } from '../../lib/errors.js';
import { getProjectConfig, FAKE_PROJECT_ID } from '../../lib/config.js';
Expand Down Expand Up @@ -255,7 +256,7 @@ export function registerDiagnoseCommands(diagnoseCmd: Command): void {

// Optional rating prompt (interactive only)
if (!json && sessionId) {
const ratingChoice = await clack.select({
const ratingChoice = await prompts.select<string>({
message: 'Was this analysis helpful?',
options: [
{ value: 'skip', label: 'Skip', hint: 'no rating' },
Expand All @@ -265,7 +266,7 @@ export function registerDiagnoseCommands(diagnoseCmd: Command): void {
],
});

if (!clack.isCancel(ratingChoice) && ratingChoice !== 'skip') {
if (!prompts.isCancel(ratingChoice) && ratingChoice !== 'skip') {
try {
await rateDiagnosticSession(
sessionId,
Expand Down
5 changes: 3 additions & 2 deletions src/commands/functions/delete.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Command } from 'commander';
import * as clack from '@clack/prompts';
import * as prompts from '../../lib/prompts.js';
import { ossFetch } from '../../lib/api/oss.js';
import { requireAuth } from '../../lib/credentials.js';
import { handleError, getRootOpts } from '../../lib/errors.js';
Expand All @@ -17,10 +18,10 @@ export function registerFunctionsDeleteCommand(functionsCmd: Command): void {
await requireAuth();

if (!yes && !json) {
const confirmed = await clack.confirm({
const confirmed = await prompts.confirm({
message: `Delete function "${slug}"? This cannot be undone.`,
});
if (clack.isCancel(confirmed) || !confirmed) {
if (prompts.isCancel(confirmed) || !confirmed) {
clack.log.info('Cancelled.');
return;
}
Expand Down
9 changes: 5 additions & 4 deletions src/commands/login.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Command } from 'commander';
import * as clack from '@clack/prompts';
import * as prompts from '../lib/prompts.js';
import { saveCredentials } from '../lib/config.js';
import { login as platformLogin } from '../lib/api/platform.js';
import { performOAuthLogin } from '../lib/auth.js';
Expand Down Expand Up @@ -37,23 +38,23 @@ async function loginWithEmail(json: boolean, apiUrl?: string): Promise<void> {

const email = json
? process.env.INSFORGE_EMAIL
: await clack.text({
: await prompts.text({
message: 'Email:',
validate: (v) => (v.includes('@') ? undefined : 'Please enter a valid email'),
});

if (clack.isCancel(email)) {
if (prompts.isCancel(email)) {
clack.cancel('Login cancelled.');
throw new Error('cancelled');
}

const password = json
? process.env.INSFORGE_PASSWORD
: await clack.password({
: await prompts.password({
message: 'Password:',
});

if (clack.isCancel(password)) {
if (prompts.isCancel(password)) {
clack.cancel('Login cancelled.');
throw new Error('cancelled');
}
Expand Down
19 changes: 10 additions & 9 deletions src/commands/projects/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import * as clack from '@clack/prompts';
import pc from 'picocolors';
import * as prompts from '../../lib/prompts.js';
import {
listOrganizations,
listProjects,
Expand Down Expand Up @@ -108,15 +109,15 @@ export function registerProjectLinkCommand(program: Command): void {
if (json) {
throw new CLIError('Multiple organizations found. Specify --org-id.');
}
const selected = await clack.select({
const selected = await prompts.select<string>({
message: 'Select an organization:',
options: orgs.map((o) => ({
value: o.id,
label: o.name,
})),
});
if (clack.isCancel(selected)) process.exit(0);
orgId = selected as string;
if (prompts.isCancel(selected)) process.exit(0);
orgId = selected;
}
}

Expand All @@ -134,15 +135,15 @@ export function registerProjectLinkCommand(program: Command): void {
if (json) {
throw new CLIError('Specify --project-id in JSON mode.');
}
const selected = await clack.select({
const selected = await prompts.select<string>({
message: 'Select a project to link:',
options: projects.map((p) => ({
value: p.id,
label: `${p.name} (${p.region}, ${p.status})`,
})),
});
if (clack.isCancel(selected)) process.exit(0);
projectId = selected as string;
if (prompts.isCancel(selected)) process.exit(0);
projectId = selected;
}

// Fetch project details and API key
Expand Down Expand Up @@ -204,7 +205,7 @@ export function registerProjectLinkCommand(program: Command): void {
// Ask for directory name
let dirName = project.name;
if (!json) {
const inputDir = await clack.text({
const inputDir = await prompts.text({
message: 'Directory name:',
initialValue: project.name,
validate: (v) => {
Expand All @@ -214,8 +215,8 @@ export function registerProjectLinkCommand(program: Command): void {
return undefined;
},
});
if (clack.isCancel(inputDir)) process.exit(0);
dirName = path.basename(inputDir as string).replace(/[^a-zA-Z0-9._-]/g, '-');
if (prompts.isCancel(inputDir)) process.exit(0);
dirName = path.basename(inputDir).replace(/[^a-zA-Z0-9._-]/g, '-');
}

if (!dirName || dirName === '.' || dirName === '..') {
Expand Down
8 changes: 4 additions & 4 deletions src/commands/projects/list.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Command } from 'commander';
import * as clack from '@clack/prompts';
import * as prompts from '../../lib/prompts.js';
import { listOrganizations, listProjects } from '../../lib/api/platform.js';
import { getGlobalConfig } from '../../lib/config.js';
import { requireAuth } from '../../lib/credentials.js';
Expand Down Expand Up @@ -27,17 +27,17 @@ export function registerProjectsCommands(projectsCmd: Command): void {
if (orgs.length === 1) {
orgId = orgs[0].id;
} else if (!json) {
const selected = await clack.select({
const selected = await prompts.select<string>({
message: 'Select an organization:',
options: orgs.map((o) => ({
value: o.id,
label: o.name,
})),
});
if (clack.isCancel(selected)) {
if (prompts.isCancel(selected)) {
process.exit(0);
}
orgId = selected as string;
orgId = selected;
} else {
throw new CLIError('Multiple organizations found. Specify --org-id.');
}
Expand Down
6 changes: 3 additions & 3 deletions src/commands/schedules/delete.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Command } from 'commander';
import * as clack from '@clack/prompts';
import * as prompts from '../../lib/prompts.js';
import { ossFetch } from '../../lib/api/oss.js';
import { requireAuth } from '../../lib/credentials.js';
import { handleError, getRootOpts } from '../../lib/errors.js';
Expand All @@ -15,10 +15,10 @@ export function registerSchedulesDeleteCommand(schedulesCmd: Command): void {
await requireAuth();

if (!yes && !json) {
const confirm = await clack.confirm({
const confirm = await prompts.confirm({
message: `Delete schedule "${id}"? This cannot be undone.`,
});
if (!confirm || clack.isCancel(confirm)) {
if (prompts.isCancel(confirm) || !confirm) {
process.exit(0);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/commands/secrets/delete.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Command } from 'commander';
import * as clack from '@clack/prompts';
import * as prompts from '../../lib/prompts.js';
import { ossFetch } from '../../lib/api/oss.js';
import { requireAuth } from '../../lib/credentials.js';
import { handleError, getRootOpts } from '../../lib/errors.js';
Expand All @@ -16,10 +16,10 @@ export function registerSecretsDeleteCommand(secretsCmd: Command): void {
await requireAuth();

if (!yes && !json) {
const confirm = await clack.confirm({
const confirm = await prompts.confirm({
message: `Delete secret "${key}"? This cannot be undone.`,
});
if (!confirm || clack.isCancel(confirm)) {
if (prompts.isCancel(confirm) || !confirm) {
process.exit(0);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/commands/storage/delete-bucket.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Command } from 'commander';
import * as clack from '@clack/prompts';
import * as prompts from '../../lib/prompts.js';
import { ossFetch } from '../../lib/api/oss.js';
import { requireAuth } from '../../lib/credentials.js';
import { handleError, getRootOpts } from '../../lib/errors.js';
Expand All @@ -15,10 +15,10 @@ export function registerStorageDeleteBucketCommand(storageCmd: Command): void {
await requireAuth();

if (!yes && !json) {
const confirm = await clack.confirm({
const confirm = await prompts.confirm({
message: `Delete bucket "${name}" and all its objects? This cannot be undone.`,
});
if (!confirm || clack.isCancel(confirm)) {
if (prompts.isCancel(confirm) || !confirm) {
process.exit(0);
}
}
Expand Down
Loading
Loading