@swell/cli
Version:
Swell's command line interface/utility
95 lines (91 loc) • 3.53 kB
JavaScript
import { InspectResourceCommand, inspectResourceBaseArgs, inspectResourceBaseFlags, } from '../../inspect-resource-command.js';
function deriveTrigger(r) {
if (r.cron?.schedule) {
return `cron (${r.cron.schedule})`;
}
if (r.model?.events?.length) {
const n = r.model.events.length;
return `model (${n} event${n === 1 ? '' : 's'})`;
}
if (r.route) {
const { methods } = r.route;
if (!methods?.length)
return 'route';
return methods.length <= 2
? `route (${methods.join(',')})`
: `route (${methods.length} methods)`;
}
return undefined;
}
export default class Functions extends InspectResourceCommand {
static summary = 'Functions with scheduling and trigger state.';
static description = `Lists functions across all apps, grouped by app. Pass --app=<slug> or --app=. (current swell.json) to scope.
List output: paste-back key + status (disabled, trigger, next cron run, last failure).
Pass an identifier to view a single record as JSON.
Identifier forms:
app.<app>.<name> — full paste-back key (list column 1)
<name> — requires --app= scope
<24-char id> — any scope
`;
static args = { ...inspectResourceBaseArgs };
static flags = { ...inspectResourceBaseFlags };
static examples = [
'swell inspect functions',
'swell inspect functions --app=my-app',
'swell inspect functions app.my-app.payment-sync',
'swell inspect functions payment-sync --app=my-app',
'swell inspect functions --live',
];
resourceLabel = 'Functions';
resourceLabelSingular = 'function';
adminPath = '/data/:functions';
commandName = 'functions';
async run() {
const { args, flags } = await this.parse(Functions);
await this.runInspect({ args, flags });
}
metaFor(r) {
const parts = [];
if (!r.enabled) {
parts.push('disabled');
}
const trigger = deriveTrigger(r);
if (trigger) {
parts.push(trigger);
}
if (r.date_cron_scheduled) {
parts.push(`next ${r.date_cron_scheduled}`);
}
if (r.date_final_attempt) {
parts.push(`last fail ${r.date_final_attempt}`);
}
return parts.length > 0 ? parts.join(' · ') : undefined;
}
filterListResults(results) {
return results.filter((record) => record.kind !== 'workflow');
}
emitDetail(record, flags) {
if (record.kind === 'workflow') {
const workflowName = record.name || record.id;
const workflowRef = record.id || record.name;
throw new Error(`Function '${workflowName}' is a workflow. Use "swell inspect workflows ${workflowRef}" instead.`);
}
super.emitDetail(record, flags);
}
/**
* Model-triggered functions emit `/events:webhooks` rows on each invocation.
* Route and cron functions do not — pointing the agent at an empty query
* would teach them their function isn't running. The logs hint always
* applies as long as we have a function name.
*/
hints(record) {
const lines = [];
if (record.model?.events?.length && record.id) {
lines.push(`swell api get '/events:webhooks?where[function_id]=${record.id}&limit=10'`);
}
if (record.name) {
lines.push(`swell logs --type function -s '${record.name}'`);
}
return lines;
}
}