Rework folder structure (#17229)
<img width="700" height="771" alt="image" src="https://github.com/user-attachments/assets/509b95b5-9c4f-474d-a47f-f950dee189ea" />
This commit is contained in:
+3
-3
@@ -1,7 +1,7 @@
|
||||
import { existsSync } from 'fs';
|
||||
import { AppSyncCommand } from '@/cli/commands/app-sync.command';
|
||||
import { AppUninstallCommand } from '@/cli/commands/app-uninstall.command';
|
||||
import { getTestedApplicationPath } from '@/cli/__tests__/e2e/utils/get-tested-application-path.util';
|
||||
import { AppSyncCommand } from '@/cli/commands/app/app-sync';
|
||||
import { AppUninstallCommand } from '@/cli/commands/app/app-uninstall';
|
||||
import { existsSync } from 'fs';
|
||||
import { inspect } from 'util';
|
||||
|
||||
inspect.defaultOptions.depth = 10;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
import { inspect } from 'util';
|
||||
import { registerCommands } from '@/cli/commands/app.command';
|
||||
import { ConfigService } from '@/cli/services/config.service';
|
||||
import chalk from 'chalk';
|
||||
import { Command, CommanderError } from 'commander';
|
||||
import { AppCommand } from '@/cli/commands/app.command';
|
||||
import { AuthCommand } from '@/cli/commands/auth.command';
|
||||
import { ConfigService } from '@/cli/services/config.service';
|
||||
import { inspect } from 'util';
|
||||
import packageJson from '../../package.json';
|
||||
|
||||
inspect.defaultOptions.depth = 10;
|
||||
@@ -33,8 +32,7 @@ program.hook('preAction', (thisCommand) => {
|
||||
);
|
||||
});
|
||||
|
||||
program.addCommand(new AuthCommand().getCommand());
|
||||
program.addCommand(new AppCommand().getCommand());
|
||||
registerCommands(program);
|
||||
|
||||
program.exitOverride();
|
||||
|
||||
|
||||
@@ -1,164 +1,186 @@
|
||||
import { formatPath } from '@/cli/utils/format-path';
|
||||
import chalk from 'chalk';
|
||||
import { Command } from 'commander';
|
||||
import type { Command } from 'commander';
|
||||
import {
|
||||
AppAddCommand,
|
||||
isSyncableEntity,
|
||||
SyncableEntity,
|
||||
} from './app-add.command';
|
||||
import { AppUninstallCommand } from '@/cli/commands/app-uninstall.command';
|
||||
import { AppDevCommand } from '@/cli/commands/app-dev.command';
|
||||
import { AppSyncCommand } from '@/cli/commands/app-sync.command';
|
||||
import { formatPath } from '@/cli/utils/format-path';
|
||||
import { AppGenerateCommand } from '@/cli/commands/app-generate.command';
|
||||
import { AppLogsCommand } from '@/cli/commands/app-logs.command';
|
||||
import { AppBuildCommand } from '@/cli/commands/app-build.command';
|
||||
} from './app/app-add';
|
||||
import { AppBuildCommand } from './app/app-build';
|
||||
import { AppGenerateCommand } from './app/app-generate';
|
||||
import { AppLogsCommand } from './app/app-logs';
|
||||
import { AppSyncCommand } from './app/app-sync';
|
||||
import { AppUninstallCommand } from './app/app-uninstall';
|
||||
import { AppWatchCommand } from './app/app-watch';
|
||||
import { AuthLoginCommand } from './auth/auth-login';
|
||||
import { AuthLogoutCommand } from './auth/auth-logout';
|
||||
import { AuthStatusCommand } from './auth/auth-status';
|
||||
|
||||
export class AppCommand {
|
||||
private devCommand = new AppDevCommand();
|
||||
private syncCommand = new AppSyncCommand();
|
||||
private uninstallCommand = new AppUninstallCommand();
|
||||
private addCommand = new AppAddCommand();
|
||||
private generateCommand = new AppGenerateCommand();
|
||||
private logsCommand = new AppLogsCommand();
|
||||
private buildCommand = new AppBuildCommand();
|
||||
export const registerCommands = (program: Command): void => {
|
||||
// Auth commands
|
||||
const loginCommand = new AuthLoginCommand();
|
||||
const logoutCommand = new AuthLogoutCommand();
|
||||
const statusCommand = new AuthStatusCommand();
|
||||
|
||||
getCommand(): Command {
|
||||
const appCommand = new Command('app');
|
||||
appCommand.description('Application development commands');
|
||||
program
|
||||
.command('auth:login')
|
||||
.description('Authenticate with Twenty')
|
||||
.option('--api-key <key>', 'API key for authentication')
|
||||
.option('--api-url <url>', 'Twenty API URL')
|
||||
.action(async (options) => {
|
||||
await loginCommand.execute(options);
|
||||
});
|
||||
|
||||
appCommand
|
||||
.command('dev [appPath]')
|
||||
.description('Watch and sync local application changes')
|
||||
.option('-d, --debounce <ms>', 'Debounce delay in milliseconds', '1000')
|
||||
.action(async (appPath, options) => {
|
||||
await this.devCommand.execute({
|
||||
program
|
||||
.command('auth:logout')
|
||||
.description('Remove authentication credentials')
|
||||
.action(async () => {
|
||||
await logoutCommand.execute();
|
||||
});
|
||||
|
||||
program
|
||||
.command('auth:status')
|
||||
.description('Check authentication status')
|
||||
.action(async () => {
|
||||
await statusCommand.execute();
|
||||
});
|
||||
|
||||
// App commands
|
||||
const watchCommand = new AppWatchCommand();
|
||||
const syncCommand = new AppSyncCommand();
|
||||
const uninstallCommand = new AppUninstallCommand();
|
||||
const addCommand = new AppAddCommand();
|
||||
const generateCommand = new AppGenerateCommand();
|
||||
const logsCommand = new AppLogsCommand();
|
||||
const buildCommand = new AppBuildCommand();
|
||||
|
||||
program
|
||||
.command('app:dev [appPath]')
|
||||
.description('Watch and sync local application changes')
|
||||
.option('-d, --debounce <ms>', 'Debounce delay in milliseconds', '1000')
|
||||
.action(async (appPath, options) => {
|
||||
await watchCommand.execute({
|
||||
...options,
|
||||
appPath: formatPath(appPath),
|
||||
});
|
||||
});
|
||||
|
||||
program
|
||||
.command('app:build [appPath]')
|
||||
.description('Build application for deployment')
|
||||
.option('-w, --watch', 'Watch for changes and rebuild')
|
||||
.option('-t, --tarball', 'Create a tarball after build')
|
||||
.action(async (appPath, options) => {
|
||||
try {
|
||||
const result = await buildCommand.execute({
|
||||
...options,
|
||||
appPath: formatPath(appPath),
|
||||
});
|
||||
});
|
||||
|
||||
appCommand
|
||||
.command('build [appPath]')
|
||||
.description('Build application for deployment')
|
||||
.option('-w, --watch', 'Watch for changes and rebuild')
|
||||
.option('-t, --tarball', 'Create a tarball after build')
|
||||
.action(async (appPath, options) => {
|
||||
try {
|
||||
const result = await this.buildCommand.execute({
|
||||
...options,
|
||||
appPath: formatPath(appPath),
|
||||
});
|
||||
if (!result.success) {
|
||||
process.exit(1);
|
||||
}
|
||||
} catch {
|
||||
if (!result.success) {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
appCommand
|
||||
.command('sync [appPath]')
|
||||
.description('Sync application to Twenty')
|
||||
.action(async (appPath?: string) => {
|
||||
try {
|
||||
const result = await this.syncCommand.execute(formatPath(appPath));
|
||||
if (!result.success) {
|
||||
process.exit(1);
|
||||
}
|
||||
} catch {
|
||||
program
|
||||
.command('app:sync [appPath]')
|
||||
.description('Sync application to Twenty')
|
||||
.action(async (appPath?: string) => {
|
||||
try {
|
||||
const result = await syncCommand.execute(formatPath(appPath));
|
||||
if (!result.success) {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
appCommand
|
||||
.command('uninstall [appPath]')
|
||||
.description('Uninstall application from Twenty')
|
||||
.action(async (appPath?: string) => {
|
||||
try {
|
||||
const result = await this.uninstallCommand.execute({
|
||||
appPath: formatPath(appPath),
|
||||
askForConfirmation: true,
|
||||
});
|
||||
if (!result.success) {
|
||||
process.exit(1);
|
||||
}
|
||||
} catch {
|
||||
program
|
||||
.command('app:uninstall [appPath]')
|
||||
.description('Uninstall application from Twenty')
|
||||
.action(async (appPath?: string) => {
|
||||
try {
|
||||
const result = await uninstallCommand.execute({
|
||||
appPath: formatPath(appPath),
|
||||
askForConfirmation: true,
|
||||
});
|
||||
if (!result.success) {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
// Keeping to avoid breaking changes
|
||||
appCommand
|
||||
.command('delete [appPath]', { hidden: true })
|
||||
.description('Delete application from Twenty')
|
||||
.action(async (appPath?: string) => {
|
||||
try {
|
||||
const result = await this.uninstallCommand.execute({
|
||||
appPath: formatPath(appPath),
|
||||
askForConfirmation: true,
|
||||
});
|
||||
if (!result.success) {
|
||||
process.exit(1);
|
||||
}
|
||||
} catch {
|
||||
// Keeping to avoid breaking changes
|
||||
program
|
||||
.command('app:delete [appPath]', { hidden: true })
|
||||
.description('Delete application from Twenty')
|
||||
.action(async (appPath?: string) => {
|
||||
try {
|
||||
const result = await uninstallCommand.execute({
|
||||
appPath: formatPath(appPath),
|
||||
askForConfirmation: true,
|
||||
});
|
||||
if (!result.success) {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
appCommand
|
||||
.command('add [entityType]')
|
||||
.option('--path <path>', 'Path in which the entity should be created.')
|
||||
.description(
|
||||
`Add a new entity to your application (${Object.values(SyncableEntity).join('|')})`,
|
||||
)
|
||||
.action(async (entityType?: string, options?: { path?: string }) => {
|
||||
if (entityType && !isSyncableEntity(entityType)) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`Invalid entity type "${entityType}". Must be one of: ${Object.values(SyncableEntity).join('|')}`,
|
||||
),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
await this.addCommand.execute(
|
||||
entityType as SyncableEntity,
|
||||
options?.path,
|
||||
program
|
||||
.command('app:add [entityType]')
|
||||
.option('--path <path>', 'Path in which the entity should be created.')
|
||||
.description(
|
||||
`Add a new entity to your application (${Object.values(SyncableEntity).join('|')})`,
|
||||
)
|
||||
.action(async (entityType?: string, options?: { path?: string }) => {
|
||||
if (entityType && !isSyncableEntity(entityType)) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`Invalid entity type "${entityType}". Must be one of: ${Object.values(SyncableEntity).join('|')}`,
|
||||
),
|
||||
);
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
await addCommand.execute(entityType as SyncableEntity, options?.path);
|
||||
});
|
||||
|
||||
appCommand
|
||||
.command('generate [appPath]')
|
||||
.description('Generate Twenty client')
|
||||
.action(async (appPath?: string) => {
|
||||
await this.generateCommand.execute(formatPath(appPath));
|
||||
});
|
||||
program
|
||||
.command('app:generate [appPath]')
|
||||
.description('Generate Twenty client')
|
||||
.action(async (appPath?: string) => {
|
||||
await generateCommand.execute(formatPath(appPath));
|
||||
});
|
||||
|
||||
appCommand
|
||||
.command('logs [appPath]')
|
||||
.option(
|
||||
'-u, --functionUniversalIdentifier <functionUniversalIdentifier>',
|
||||
'Only show logs for the function with this universal ID',
|
||||
)
|
||||
.option(
|
||||
'-n, --functionName <functionName>',
|
||||
'Only show logs for the function with this name',
|
||||
)
|
||||
.description('Watch application function logs')
|
||||
.action(
|
||||
async (
|
||||
appPath?: string,
|
||||
options?: {
|
||||
functionUniversalIdentifier?: string;
|
||||
functionName?: string;
|
||||
},
|
||||
) => {
|
||||
await this.logsCommand.execute({
|
||||
...options,
|
||||
appPath: formatPath(appPath),
|
||||
});
|
||||
program
|
||||
.command('app:logs [appPath]')
|
||||
.option(
|
||||
'-u, --functionUniversalIdentifier <functionUniversalIdentifier>',
|
||||
'Only show logs for the function with this universal ID',
|
||||
)
|
||||
.option(
|
||||
'-n, --functionName <functionName>',
|
||||
'Only show logs for the function with this name',
|
||||
)
|
||||
.description('Watch application function logs')
|
||||
.action(
|
||||
async (
|
||||
appPath?: string,
|
||||
options?: {
|
||||
functionUniversalIdentifier?: string;
|
||||
functionName?: string;
|
||||
},
|
||||
);
|
||||
|
||||
return appCommand;
|
||||
}
|
||||
}
|
||||
) => {
|
||||
await logsCommand.execute({
|
||||
...options,
|
||||
appPath: formatPath(appPath),
|
||||
});
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
-11
@@ -9,17 +9,6 @@ export type BuildCommandOptions = {
|
||||
tarball?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* AppBuildCommand handles the `twenty app build` CLI command.
|
||||
*
|
||||
* This command transpiles TypeScript applications into distributable
|
||||
* JavaScript bundles using Vite.
|
||||
*
|
||||
* Usage:
|
||||
* - `npx twenty app build [appPath]` - One-time build
|
||||
* - `npx twenty app build --watch [appPath]` - Watch mode with incremental rebuilds
|
||||
* - `npx twenty app build --tarball [appPath]` - Build + create .tar.gz
|
||||
*/
|
||||
export class AppBuildCommand {
|
||||
private buildService = new BuildService();
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// Placeholder for app publish command
|
||||
// TODO: Implement application publishing functionality
|
||||
|
||||
export class AppPublishCommand {
|
||||
async execute(): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Placeholder for app test command
|
||||
// TODO: Implement application testing functionality
|
||||
|
||||
export class AppTestCommand {
|
||||
async execute(): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { loadManifest } from '@/cli/utils/load-manifest';
|
||||
import { displayWarnings } from '@/cli/utils/display-warnings';
|
||||
import { displayErrors } from '@/cli/utils/display-errors';
|
||||
|
||||
export class AppDevCommand {
|
||||
export class AppWatchCommand {
|
||||
private apiService = new ApiService();
|
||||
|
||||
async execute(options: {
|
||||
@@ -0,0 +1,9 @@
|
||||
export { AppWatchCommand } from './app-watch';
|
||||
export { AppBuildCommand, type BuildCommandOptions } from './app-build';
|
||||
export { AppSyncCommand } from './app-sync';
|
||||
export { AppUninstallCommand } from './app-uninstall';
|
||||
export { AppLogsCommand } from './app-logs';
|
||||
export { AppTestCommand } from './app-test';
|
||||
export { AppPublishCommand } from './app-publish';
|
||||
export { AppAddCommand, SyncableEntity, isSyncableEntity } from './app-add';
|
||||
export { AppGenerateCommand } from './app-generate';
|
||||
@@ -1,162 +0,0 @@
|
||||
import chalk from 'chalk';
|
||||
import { Command } from 'commander';
|
||||
import inquirer from 'inquirer';
|
||||
import { ApiService } from '@/cli/services/api.service';
|
||||
import { ConfigService } from '@/cli/services/config.service';
|
||||
|
||||
export class AuthCommand {
|
||||
private configService = new ConfigService();
|
||||
private apiService = new ApiService();
|
||||
|
||||
getCommand(): Command {
|
||||
const authCommand = new Command('auth');
|
||||
authCommand.description('Authentication commands');
|
||||
|
||||
authCommand
|
||||
.command('login')
|
||||
.description('Authenticate with Twenty')
|
||||
.option('--api-key <key>', 'API key for authentication')
|
||||
.option('--api-url <url>', 'Twenty API URL')
|
||||
.action(async (options) => {
|
||||
await this.login(options);
|
||||
});
|
||||
|
||||
authCommand
|
||||
.command('logout')
|
||||
.description('Remove authentication credentials')
|
||||
.action(async () => {
|
||||
await this.logout();
|
||||
});
|
||||
|
||||
authCommand
|
||||
.command('status')
|
||||
.description('Check authentication status')
|
||||
.action(async () => {
|
||||
await this.status();
|
||||
});
|
||||
|
||||
return authCommand;
|
||||
}
|
||||
|
||||
private async login(options: {
|
||||
apiKey?: string;
|
||||
apiUrl?: string;
|
||||
}): Promise<void> {
|
||||
try {
|
||||
let { apiKey, apiUrl } = options;
|
||||
|
||||
// Get current config
|
||||
const config = await this.configService.getConfig();
|
||||
|
||||
// Prompt for missing values
|
||||
if (!apiUrl) {
|
||||
const urlAnswer = await inquirer.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'apiUrl',
|
||||
message: 'Twenty API URL:',
|
||||
default: config.apiUrl,
|
||||
validate: (input) => {
|
||||
try {
|
||||
new URL(input);
|
||||
return true;
|
||||
} catch {
|
||||
return 'Please enter a valid URL';
|
||||
}
|
||||
},
|
||||
},
|
||||
]);
|
||||
apiUrl = urlAnswer.apiUrl;
|
||||
}
|
||||
|
||||
if (!apiKey) {
|
||||
const keyAnswer = await inquirer.prompt([
|
||||
{
|
||||
type: 'password',
|
||||
name: 'apiKey',
|
||||
message: 'API Key:',
|
||||
mask: '*',
|
||||
validate: (input) => input.length > 0 || 'API key is required',
|
||||
},
|
||||
]);
|
||||
apiKey = keyAnswer.apiKey;
|
||||
}
|
||||
|
||||
// Update config
|
||||
await this.configService.setConfig({
|
||||
apiUrl,
|
||||
apiKey,
|
||||
});
|
||||
|
||||
// Validate authentication
|
||||
const isValid = await this.apiService.validateAuth();
|
||||
|
||||
if (isValid) {
|
||||
const activeWorkspace = ConfigService.getActiveWorkspace();
|
||||
console.log(
|
||||
chalk.green(
|
||||
`✓ Successfully authenticated with Twenty (workspace: ${activeWorkspace})`,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
chalk.red('✗ Authentication failed. Please check your credentials.'),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
chalk.red('Login failed:'),
|
||||
error instanceof Error ? error.message : error,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private async logout(): Promise<void> {
|
||||
try {
|
||||
await this.configService.clearConfig();
|
||||
const activeWorkspace = ConfigService.getActiveWorkspace();
|
||||
console.log(
|
||||
chalk.green(
|
||||
`✓ Successfully logged out (workspace: ${activeWorkspace})`,
|
||||
),
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
chalk.red('Logout failed:'),
|
||||
error instanceof Error ? error.message : error,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private async status(): Promise<void> {
|
||||
try {
|
||||
const activeWorkspace = ConfigService.getActiveWorkspace();
|
||||
const config = await this.configService.getConfig();
|
||||
|
||||
console.log(chalk.blue('Authentication Status:'));
|
||||
console.log(`Workspace: ${activeWorkspace}`);
|
||||
console.log(`API URL: ${config.apiUrl}`);
|
||||
console.log(
|
||||
`API Key: ${config.apiKey ? '***' + config.apiKey.slice(-4) : 'Not set'}`,
|
||||
);
|
||||
|
||||
if (config.apiKey) {
|
||||
const isValid = await this.apiService.validateAuth();
|
||||
console.log(
|
||||
`Status: ${isValid ? chalk.green('✓ Valid') : chalk.red('✗ Invalid')}`,
|
||||
);
|
||||
} else {
|
||||
console.log(`Status: ${chalk.yellow('⚠ Not authenticated')}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
chalk.red('Status check failed:'),
|
||||
error instanceof Error ? error.message : error,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import chalk from 'chalk';
|
||||
import inquirer from 'inquirer';
|
||||
import { ApiService } from '@/cli/services/api.service';
|
||||
import { ConfigService } from '@/cli/services/config.service';
|
||||
|
||||
export class AuthLoginCommand {
|
||||
private configService = new ConfigService();
|
||||
private apiService = new ApiService();
|
||||
|
||||
async execute(options: {
|
||||
apiKey?: string;
|
||||
apiUrl?: string;
|
||||
}): Promise<void> {
|
||||
try {
|
||||
let { apiKey, apiUrl } = options;
|
||||
|
||||
// Get current config
|
||||
const config = await this.configService.getConfig();
|
||||
|
||||
// Prompt for missing values
|
||||
if (!apiUrl) {
|
||||
const urlAnswer = await inquirer.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'apiUrl',
|
||||
message: 'Twenty API URL:',
|
||||
default: config.apiUrl,
|
||||
validate: (input) => {
|
||||
try {
|
||||
new URL(input);
|
||||
return true;
|
||||
} catch {
|
||||
return 'Please enter a valid URL';
|
||||
}
|
||||
},
|
||||
},
|
||||
]);
|
||||
apiUrl = urlAnswer.apiUrl;
|
||||
}
|
||||
|
||||
if (!apiKey) {
|
||||
const keyAnswer = await inquirer.prompt([
|
||||
{
|
||||
type: 'password',
|
||||
name: 'apiKey',
|
||||
message: 'API Key:',
|
||||
mask: '*',
|
||||
validate: (input) => input.length > 0 || 'API key is required',
|
||||
},
|
||||
]);
|
||||
apiKey = keyAnswer.apiKey;
|
||||
}
|
||||
|
||||
// Update config
|
||||
await this.configService.setConfig({
|
||||
apiUrl,
|
||||
apiKey,
|
||||
});
|
||||
|
||||
// Validate authentication
|
||||
const isValid = await this.apiService.validateAuth();
|
||||
|
||||
if (isValid) {
|
||||
const activeWorkspace = ConfigService.getActiveWorkspace();
|
||||
console.log(
|
||||
chalk.green(
|
||||
`✓ Successfully authenticated with Twenty (workspace: ${activeWorkspace})`,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
chalk.red('✗ Authentication failed. Please check your credentials.'),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
chalk.red('Login failed:'),
|
||||
error instanceof Error ? error.message : error,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import chalk from 'chalk';
|
||||
import { ConfigService } from '@/cli/services/config.service';
|
||||
|
||||
export class AuthLogoutCommand {
|
||||
private configService = new ConfigService();
|
||||
|
||||
async execute(): Promise<void> {
|
||||
try {
|
||||
await this.configService.clearConfig();
|
||||
const activeWorkspace = ConfigService.getActiveWorkspace();
|
||||
console.log(
|
||||
chalk.green(
|
||||
`✓ Successfully logged out (workspace: ${activeWorkspace})`,
|
||||
),
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
chalk.red('Logout failed:'),
|
||||
error instanceof Error ? error.message : error,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import chalk from 'chalk';
|
||||
import { ApiService } from '@/cli/services/api.service';
|
||||
import { ConfigService } from '@/cli/services/config.service';
|
||||
|
||||
export class AuthStatusCommand {
|
||||
private configService = new ConfigService();
|
||||
private apiService = new ApiService();
|
||||
|
||||
async execute(): Promise<void> {
|
||||
try {
|
||||
const activeWorkspace = ConfigService.getActiveWorkspace();
|
||||
const config = await this.configService.getConfig();
|
||||
|
||||
console.log(chalk.blue('Authentication Status:'));
|
||||
console.log(`Workspace: ${activeWorkspace}`);
|
||||
console.log(`API URL: ${config.apiUrl}`);
|
||||
console.log(
|
||||
`API Key: ${config.apiKey ? '***' + config.apiKey.slice(-4) : 'Not set'}`,
|
||||
);
|
||||
|
||||
if (config.apiKey) {
|
||||
const isValid = await this.apiService.validateAuth();
|
||||
console.log(
|
||||
`Status: ${isValid ? chalk.green('✓ Valid') : chalk.red('✗ Invalid')}`,
|
||||
);
|
||||
} else {
|
||||
console.log(`Status: ${chalk.yellow('⚠ Not authenticated')}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
chalk.red('Status check failed:'),
|
||||
error instanceof Error ? error.message : error,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Placeholder for auth switch command
|
||||
// TODO: Implement workspace switching functionality
|
||||
|
||||
export class AuthSwitchCommand {
|
||||
async execute(): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export { AuthLoginCommand } from './auth-login';
|
||||
export { AuthLogoutCommand } from './auth-logout';
|
||||
export { AuthStatusCommand } from './auth-status';
|
||||
export { AuthSwitchCommand } from './auth-switch';
|
||||
@@ -0,0 +1,8 @@
|
||||
// Placeholder for entity add command
|
||||
// TODO: Implement entity add functionality
|
||||
|
||||
export class EntityAddCommand {
|
||||
async execute(): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { EntityAddCommand } from './entity-add';
|
||||
@@ -0,0 +1,3 @@
|
||||
export { InstanceSetupCommand } from './instance-setup';
|
||||
export { InstanceUpgradeCommand } from './instance-upgrade';
|
||||
export { InstanceRunCommand } from './instance-run';
|
||||
@@ -0,0 +1,8 @@
|
||||
// Placeholder for instance run command
|
||||
// TODO: Implement instance run functionality
|
||||
|
||||
export class InstanceRunCommand {
|
||||
async execute(): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Placeholder for instance setup command
|
||||
// TODO: Implement instance setup functionality
|
||||
|
||||
export class InstanceSetupCommand {
|
||||
async execute(): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Placeholder for instance upgrade command
|
||||
// TODO: Implement instance upgrade functionality
|
||||
|
||||
export class InstanceUpgradeCommand {
|
||||
async execute(): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { SdkGenerateCommand } from './sdk-generate';
|
||||
@@ -0,0 +1,8 @@
|
||||
// Placeholder for sdk generate command
|
||||
// TODO: Implement SDK generation functionality
|
||||
|
||||
export class SdkGenerateCommand {
|
||||
async execute(): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user