Improve readme (#14858)
This commit is contained in:
@@ -3,11 +3,11 @@ import * as fs from 'fs-extra';
|
||||
import inquirer from 'inquirer';
|
||||
import path from 'path';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { resolveAppPath } from '../utils/app-path-resolver';
|
||||
import { parseJsoncFile, writeJsoncFile } from '../utils/jsonc-parser';
|
||||
import { getSchemaUrls } from '../utils/schema-validator';
|
||||
import { CURRENT_EXECUTION_DIRECTORY } from '../constants/current-execution-directory';
|
||||
|
||||
enum SyncableEntity {
|
||||
export enum SyncableEntity {
|
||||
AGENT = 'agent',
|
||||
OBJECT = 'object',
|
||||
SERVERLESS_FUNCTION = 'serverlessFunction',
|
||||
@@ -27,12 +27,16 @@ const getFolderName = (entity: SyncableEntity) => {
|
||||
}
|
||||
};
|
||||
|
||||
export class AppAddCommand {
|
||||
async execute(options: { path?: string }): Promise<void> {
|
||||
try {
|
||||
const appPath = await resolveAppPath(options.path);
|
||||
export const isSyncableEntity = (value: string): value is SyncableEntity => {
|
||||
return Object.values(SyncableEntity).includes(value as SyncableEntity);
|
||||
};
|
||||
|
||||
const entity = await this.getEntity();
|
||||
export class AppAddCommand {
|
||||
async execute(entityType?: SyncableEntity): Promise<void> {
|
||||
try {
|
||||
const appPath = CURRENT_EXECUTION_DIRECTORY;
|
||||
|
||||
const entity = entityType ?? (await this.getEntity());
|
||||
|
||||
const appExists = await fs.pathExists(appPath);
|
||||
|
||||
@@ -99,12 +103,7 @@ export class AppAddCommand {
|
||||
name: 'entity',
|
||||
message: `What entity do you want to create?`,
|
||||
default: '',
|
||||
choices: [
|
||||
SyncableEntity.AGENT,
|
||||
SyncableEntity.OBJECT,
|
||||
SyncableEntity.SERVERLESS_FUNCTION,
|
||||
SyncableEntity.TRIGGER,
|
||||
],
|
||||
choices: [SyncableEntity.SERVERLESS_FUNCTION, SyncableEntity.TRIGGER],
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -261,7 +260,8 @@ export class AppAddCommand {
|
||||
{
|
||||
type: 'input',
|
||||
name: 'eventName',
|
||||
message: 'Enter the database event name (e.g., company.created):',
|
||||
message:
|
||||
'Enter the database event name (e.g. company.created, *.updated, person.*):',
|
||||
validate: (input) => {
|
||||
if (input.length === 0) {
|
||||
return 'Event name is required';
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import chalk from 'chalk';
|
||||
import * as chokidar from 'chokidar';
|
||||
import { ApiService } from '../services/api.service';
|
||||
import { resolveAppPath } from '../utils/app-path-resolver';
|
||||
import { syncApp } from '../utils/app-sync';
|
||||
import { CURRENT_EXECUTION_DIRECTORY } from '../constants/current-execution-directory';
|
||||
|
||||
export class AppDevCommand {
|
||||
private apiService = new ApiService();
|
||||
|
||||
async execute(options: { path?: string; debounce: string }): Promise<void> {
|
||||
async execute(options: { debounce: string }): Promise<void> {
|
||||
try {
|
||||
const appPath = await resolveAppPath(options.path);
|
||||
const appPath = CURRENT_EXECUTION_DIRECTORY;
|
||||
|
||||
const debounceMs = parseInt(options.debounce, 10);
|
||||
|
||||
this.logStartupInfo(appPath, debounceMs);
|
||||
|
||||
@@ -6,10 +6,10 @@ import { copyBaseApplicationProject } from '../utils/app-template';
|
||||
import kebabCase from 'lodash.kebabcase';
|
||||
|
||||
export class AppInitCommand {
|
||||
async execute(options: { path?: string }): Promise<void> {
|
||||
async execute(directory?: string): Promise<void> {
|
||||
try {
|
||||
const { appName, appDirectory, appDescription } =
|
||||
await this.getAppInfos(options);
|
||||
await this.getAppInfos(directory);
|
||||
|
||||
await this.validateDirectory(appDirectory);
|
||||
|
||||
@@ -33,7 +33,7 @@ export class AppInitCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private async getAppInfos(options: { path?: string }): Promise<{
|
||||
private async getAppInfos(directory?: string): Promise<{
|
||||
appName: string;
|
||||
appDirectory: string;
|
||||
appDescription: string;
|
||||
@@ -60,9 +60,9 @@ export class AppInitCommand {
|
||||
|
||||
const appDescription = description.trim();
|
||||
|
||||
const appDirectory = options.path
|
||||
? path.resolve(options.path, kebabCase(appName))
|
||||
: path.join(process.cwd(), kebabCase(appName)!);
|
||||
const appDirectory = directory
|
||||
? path.join(process.cwd(), kebabCase(directory))
|
||||
: path.join(process.cwd(), kebabCase(appName));
|
||||
|
||||
return { appName, appDirectory, appDescription };
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import chalk from 'chalk';
|
||||
import { ApiService } from '../services/api.service';
|
||||
import { resolveAppPath } from '../utils/app-path-resolver';
|
||||
import { syncApp } from '../utils/app-sync';
|
||||
import { CURRENT_EXECUTION_DIRECTORY } from '../constants/current-execution-directory';
|
||||
|
||||
export class AppSyncCommand {
|
||||
private apiService = new ApiService();
|
||||
|
||||
async execute(options: { path?: string }): Promise<void> {
|
||||
async execute(): Promise<void> {
|
||||
try {
|
||||
const appPath = await resolveAppPath(options.path);
|
||||
const appPath = CURRENT_EXECUTION_DIRECTORY;
|
||||
|
||||
console.log(chalk.blue('🚀 Syncing Twenty Application'));
|
||||
console.log(chalk.gray(`📁 App Path: ${appPath}`));
|
||||
|
||||
@@ -2,7 +2,12 @@ import { Command } from 'commander';
|
||||
import { AppSyncCommand } from './app-sync.command';
|
||||
import { AppDevCommand } from './app-dev.command';
|
||||
import { AppInitCommand } from './app-init.command';
|
||||
import { AppAddCommand } from './app-add.command';
|
||||
import {
|
||||
AppAddCommand,
|
||||
isSyncableEntity,
|
||||
SyncableEntity,
|
||||
} from './app-add.command';
|
||||
import chalk from 'chalk';
|
||||
|
||||
export class AppCommand {
|
||||
private devCommand = new AppDevCommand();
|
||||
@@ -17,10 +22,6 @@ export class AppCommand {
|
||||
appCommand
|
||||
.command('dev')
|
||||
.description('Watch and sync local application changes')
|
||||
.option(
|
||||
'-p, --path <path>',
|
||||
'Application directory path (auto-detected if not specified)',
|
||||
)
|
||||
.option('-d, --debounce <ms>', 'Debounce delay in milliseconds', '1000')
|
||||
.action(async (options) => {
|
||||
await this.devCommand.execute(options);
|
||||
@@ -29,31 +30,40 @@ export class AppCommand {
|
||||
appCommand
|
||||
.command('sync')
|
||||
.description('Sync application to Twenty')
|
||||
.option(
|
||||
'-p, --path <path>',
|
||||
'Application directory path (auto-detected if not specified)',
|
||||
)
|
||||
.action(async (options) => {
|
||||
await this.syncCommand.execute(options);
|
||||
.action(async () => {
|
||||
await this.syncCommand.execute();
|
||||
});
|
||||
|
||||
appCommand
|
||||
.command('init')
|
||||
.command('init [directory]')
|
||||
.description('Initialize a new Twenty application')
|
||||
.option('-p, --path <path>', 'Directory to create the application in')
|
||||
.action(async (options) => {
|
||||
await this.initCommand.execute(options);
|
||||
.action(async (directory?: string) => {
|
||||
if (directory && !/^[a-z0-9-]+$/.test(directory)) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`Invalid directory "${directory}". Must contain only lowercase letters, numbers, and hyphens`,
|
||||
),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
await this.initCommand.execute(directory);
|
||||
});
|
||||
|
||||
appCommand
|
||||
.command('add')
|
||||
.description('Add a new entity to your application')
|
||||
.option(
|
||||
'-p, --path <path>',
|
||||
'Application directory path (auto-detected if not specified)',
|
||||
.command('add [entityType]')
|
||||
.description(
|
||||
`Add a new entity to your application (${Object.values(SyncableEntity).join('|')})`,
|
||||
)
|
||||
.action(async (options) => {
|
||||
await this.addCommand.execute(options);
|
||||
.action(async (entityType?: 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);
|
||||
});
|
||||
|
||||
return appCommand;
|
||||
|
||||
Reference in New Issue
Block a user