Add triggers to cli sync (#14828)
This commit is contained in:
@@ -4,13 +4,14 @@ import inquirer from 'inquirer';
|
||||
import path from 'path';
|
||||
import { v4 } from 'uuid';
|
||||
import { resolveAppPath } from '../utils/app-path-resolver';
|
||||
import { writeJsoncFile } from '../utils/jsonc-parser';
|
||||
import { parseJsoncFile, writeJsoncFile } from '../utils/jsonc-parser';
|
||||
import { getSchemaUrls } from '../utils/schema-validator';
|
||||
|
||||
enum SyncableEntity {
|
||||
AGENT = 'agent',
|
||||
OBJECT = 'object',
|
||||
SERVERLESS_FUNCTION = 'serverlessFunction',
|
||||
TRIGGER = 'trigger',
|
||||
}
|
||||
|
||||
const getFolderName = (entity: SyncableEntity) => {
|
||||
@@ -40,6 +41,11 @@ export class AppAddCommand {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (entity === SyncableEntity.TRIGGER) {
|
||||
await this.addTriggerToServerlessFunction(appPath);
|
||||
return;
|
||||
}
|
||||
|
||||
const entityName = await this.getEntityName(entity);
|
||||
|
||||
const entityData = await this.getEntityToCreateData(entity, entityName);
|
||||
@@ -97,6 +103,7 @@ export class AppAddCommand {
|
||||
SyncableEntity.AGENT,
|
||||
SyncableEntity.OBJECT,
|
||||
SyncableEntity.SERVERLESS_FUNCTION,
|
||||
SyncableEntity.TRIGGER,
|
||||
],
|
||||
},
|
||||
]);
|
||||
@@ -184,4 +191,123 @@ export class AppAddCommand {
|
||||
|
||||
return entityToCreateData;
|
||||
}
|
||||
|
||||
private async addTriggerToServerlessFunction(appPath: string) {
|
||||
const serverlessFunctionsDir = path.join(appPath, 'serverlessFunctions');
|
||||
|
||||
if (!(await fs.pathExists(serverlessFunctionsDir))) {
|
||||
console.error(chalk.red('No serverless functions found in this app'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const serverlessFunctions = await fs.readdir(serverlessFunctionsDir);
|
||||
|
||||
if (serverlessFunctions.length === 0) {
|
||||
console.error(chalk.red('No serverless functions found in this app'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const { serverlessFunctionName } = await inquirer.prompt([
|
||||
{
|
||||
type: 'list',
|
||||
name: 'serverlessFunctionName',
|
||||
message: 'Select a serverless function to add a trigger to:',
|
||||
choices: serverlessFunctions,
|
||||
},
|
||||
]);
|
||||
|
||||
const { triggerType } = await inquirer.prompt([
|
||||
{
|
||||
type: 'list',
|
||||
name: 'triggerType',
|
||||
message: 'Select the type of trigger:',
|
||||
choices: ['databaseEvent', 'cron'],
|
||||
},
|
||||
]);
|
||||
|
||||
let triggerData: any;
|
||||
|
||||
if (triggerType === 'databaseEvent') {
|
||||
triggerData = await this.createDatabaseEventTrigger();
|
||||
} else if (triggerType === 'cron') {
|
||||
triggerData = await this.createCronTrigger();
|
||||
}
|
||||
|
||||
const manifestPath = path.join(
|
||||
serverlessFunctionsDir,
|
||||
serverlessFunctionName,
|
||||
'serverlessFunction.manifest.jsonc',
|
||||
);
|
||||
|
||||
const manifest = await parseJsoncFile(manifestPath);
|
||||
|
||||
if (!manifest.triggers) {
|
||||
manifest.triggers = [];
|
||||
}
|
||||
|
||||
manifest.triggers.push(triggerData);
|
||||
|
||||
await writeJsoncFile(manifestPath, manifest);
|
||||
|
||||
console.log(
|
||||
chalk.green(`✅ Trigger added successfully to ${serverlessFunctionName}`),
|
||||
);
|
||||
}
|
||||
|
||||
private async createDatabaseEventTrigger() {
|
||||
const uuid = v4();
|
||||
|
||||
const { eventName } = await inquirer.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'eventName',
|
||||
message: 'Enter the database event name (e.g., company.created):',
|
||||
validate: (input) => {
|
||||
if (input.length === 0) {
|
||||
return 'Event name is required';
|
||||
}
|
||||
if (!/^[a-zA-Z]+\.(created|updated|deleted)$/.test(input)) {
|
||||
return 'Event name must be in format: objectName.(created|updated|deleted)';
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
return {
|
||||
universalIdentifier: uuid,
|
||||
type: 'databaseEvent',
|
||||
eventName,
|
||||
};
|
||||
}
|
||||
|
||||
private async createCronTrigger() {
|
||||
const uuid = v4();
|
||||
|
||||
const { schedule } = await inquirer.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'schedule',
|
||||
message: 'Enter the cron schedule (e.g., 0 9 * * * for daily at 9 AM):',
|
||||
validate: (input) => {
|
||||
if (input.length === 0) {
|
||||
return 'Schedule is required';
|
||||
}
|
||||
|
||||
const parts = input.trim().split(/\s+/);
|
||||
|
||||
if (parts.length < 5 || parts.length > 6) {
|
||||
return 'Cron schedule must have 5 or 6 fields (e.g., 0 9 * * *)';
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
return {
|
||||
universalIdentifier: uuid,
|
||||
type: 'cron',
|
||||
schedule,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user