Files
inkreach-teable-cli/dist/commands/extras.js
T
yeuimu 3810c33d69 refactor: rename CLI command 'inkreach' -> 'inkreach-teable'
Rename the command (and its config namespace) to match the project name:

- bin:          inkreach        -> inkreach-teable
- program name: inkreach        -> inkreach-teable
- config dir:   ~/.inkreach/    -> ~/.inkreach-teable/
- env vars:     INKREACH_*      -> INKREACH_TEABLE_*
- all docs (SKILL.md, guides, api-reference, AGENTS.md, design doc, install.sh)

Unchanged (intentional):
- npm package name: @inkreach/teable-cli
- package directory: packages/inkreach-cli/
- skill name: inkreach-teable-ops
- organization/authors: 'inkreach' (npm scope @inkreach)

Existing config auto-migrated (~/.inkreach -> ~/.inkreach-teable). Verified
end-to-end: auth status, workflow list (636), build clean.
2026-08-05 10:14:26 +08:00

289 lines
11 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sqlCommand = exports.fireCommand = exports.runsCommand = exports.secretCommand = void 0;
/**
* `inkreach-teable secret` — manage workflow automation secrets.
* `inkreach-teable runs` — execution history.
* `inkreach-teable fire` — manual trigger testing (button-click / webhook).
* `inkreach-teable sql` — read-only SQL queries.
*/
const commander_1 = require("commander");
const ctx_1 = require("../lib/ctx");
const output_1 = require("../lib/output");
// ===================== secret =====================
function secretCommand() {
const cmd = new commander_1.Command('secret');
cmd.description('Manage automation script secrets');
cmd
.command('list <workflowId>')
.description('List secrets for a workflow. Values are never returned.')
.option('--base-id <id>', 'Base id (overrides default)')
.action((0, ctx_1.run)(async (ctx, args, o) => {
const workflowId = args[0];
const opts = o;
const baseId = (0, ctx_1.requireBaseId)(ctx, opts.baseId);
const list = (await ctx.client.listSecrets(baseId, workflowId));
if (ctx.json)
(0, output_1.printJson)(list);
else {
if (!list.length) {
process.stdout.write('No secrets found.\n');
return;
}
(0, output_1.printTable)([
{ key: 'id', header: 'ID' },
{ key: 'name', header: 'NAME' },
{ key: 'description', header: 'DESCRIPTION' },
], list.map((s) => ({
id: s.id,
name: (0, output_1.truncate)(s.name, 30),
description: (0, output_1.truncate)(s.description, 50),
})));
}
}));
cmd
.command('set <workflowId>')
.description('Create a new secret')
.requiredOption('--name <name>', 'Secret name')
.requiredOption('--value <value>', 'Secret value')
.option('--description <desc>', 'Secret description')
.option('--base-id <id>', 'Base id (overrides default)')
.action((0, ctx_1.run)(async (ctx, args, o) => {
const workflowId = args[0];
const opts = o;
const baseId = (0, ctx_1.requireBaseId)(ctx, opts.baseId);
const created = await ctx.client.createSecret(baseId, workflowId, {
name: opts.name,
value: opts.value,
description: opts.description,
});
const s = created;
if (ctx.json)
(0, output_1.printJson)(created);
else {
(0, output_1.printKv)([
['id', s.id],
['name', s.name],
['', ''],
['note', 'Secret value is never returned. Update it if needed.'],
]);
}
}));
cmd
.command('update <workflowId> <secretId>')
.description('Update a secret')
.option('--name <name>', 'New name')
.option('--value <value>', 'New value')
.option('--description <desc>', 'New description')
.option('--base-id <id>', 'Base id (overrides default)')
.action((0, ctx_1.run)(async (ctx, args, o) => {
const [workflowId, secretId] = args;
const opts = o;
const baseId = (0, ctx_1.requireBaseId)(ctx, opts.baseId);
await ctx.client.updateSecret(baseId, workflowId, secretId, {
name: opts.name,
value: opts.value,
description: opts.description,
});
if (ctx.json)
(0, output_1.printJson)({ ok: true, id: secretId });
else
process.stdout.write(`✓ Secret ${secretId} updated\n`);
}));
cmd
.command('delete <workflowId> <secretId>')
.description('Delete a secret')
.option('--base-id <id>', 'Base id (overrides default)')
.action((0, ctx_1.run)(async (ctx, args, o) => {
const [workflowId, secretId] = args;
const opts = o;
const baseId = (0, ctx_1.requireBaseId)(ctx, opts.baseId);
await ctx.client.deleteSecret(baseId, workflowId, secretId);
if (ctx.json)
(0, output_1.printJson)({ ok: true, id: secretId });
else
process.stdout.write(`✓ Secret ${secretId} deleted\n`);
}));
return cmd;
}
exports.secretCommand = secretCommand;
// ===================== runs =====================
function runsCommand() {
const cmd = new commander_1.Command('runs');
cmd.description('Execution history for automations');
cmd
.command('list <workflowId>')
.description('List execution history')
.option('--status <status>', 'Filter by status: failed, succeeded, or running')
.option('--base-id <id>', 'Base id (overrides default)')
.action((0, ctx_1.run)(async (ctx, args, o) => {
const workflowId = args[0];
const opts = o;
const baseId = (0, ctx_1.requireBaseId)(ctx, opts.baseId);
let list = (await ctx.client.listExecutions(baseId, workflowId));
if (opts.status) {
list = list.filter((e) => e.status === opts.status);
}
if (ctx.json)
(0, output_1.printJson)(list);
else {
if (!list.length) {
process.stdout.write('No executions found.\n');
return;
}
(0, output_1.printTable)([
{ key: 'id', header: 'ID' },
{ key: 'status', header: 'STATUS' },
{ key: 'triggerType', header: 'TRIGGER' },
{ key: 'startedAt', header: 'STARTED' },
{ key: 'finishedAt', header: 'FINISHED' },
], list.map((e) => ({
id: e.id,
status: e.status,
triggerType: e.triggerType || '',
startedAt: (0, output_1.truncate)(e.startedAt, 25),
finishedAt: (0, output_1.truncate)(e.finishedAt, 25),
})));
}
}));
cmd
.command('get <workflowId> <executionId>')
.description('Get execution detail with node results')
.option('--base-id <id>', 'Base id (overrides default)')
.action((0, ctx_1.run)(async (ctx, args, o) => {
const [workflowId, executionId] = args;
const opts = o;
const baseId = (0, ctx_1.requireBaseId)(ctx, opts.baseId);
const exec = await ctx.client.getExecution(baseId, workflowId, executionId);
const ex = exec;
if (ctx.json)
(0, output_1.printJson)(exec);
else {
(0, output_1.printKv)([
['id', ex.id],
['status', ex.status],
['trigger', ex.triggerType || ''],
['started', ex.startedAt || ''],
['finished', ex.finishedAt || ''],
]);
if (ex.nodeResults?.length) {
process.stdout.write('\nNODE RESULTS:\n');
(0, output_1.printTable)([
{ key: 'nodeId', header: 'NODE' },
{ key: 'status', header: 'STATUS' },
{ key: 'error', header: 'ERROR' },
], ex.nodeResults.map((r) => ({
nodeId: r.nodeId,
status: r.status,
error: (0, output_1.truncate)(r.error, 50),
})));
}
}
}));
cmd
.command('rerun <workflowId> <executionId>')
.description('Rerun a failed execution')
.option('--base-id <id>', 'Base id (overrides default)')
.action((0, ctx_1.run)(async (ctx, args, o) => {
const [workflowId, executionId] = args;
const opts = o;
const baseId = (0, ctx_1.requireBaseId)(ctx, opts.baseId);
const res = (await ctx.client.rerunExecution(baseId, workflowId, executionId));
if (ctx.json)
(0, output_1.printJson)(res);
else {
const pairs = [
['executionId', executionId],
['status', 'rerun requested'],
];
if (res.id)
pairs.push(['newExecutionId', res.id]);
(0, output_1.printKv)(pairs);
}
}));
return cmd;
}
exports.runsCommand = runsCommand;
// ===================== fire =====================
function fireCommand() {
const cmd = new commander_1.Command('fire');
cmd.description('Manually fire triggers for testing');
cmd
.command('button-click <tableId> <recordId> <fieldId>')
.description('Simulate a button field click')
.action((0, ctx_1.run)(async (ctx, args) => {
const [tableId, recordId, fieldId] = args;
const res = await ctx.client.fireButtonClick(tableId, recordId, fieldId);
if (ctx.json)
(0, output_1.printJson)(res);
else {
(0, output_1.printKv)([
['runId', res.runId],
['tableId', res.tableId],
['fieldId', res.fieldId],
]);
}
}));
cmd
.command('webhook <baseId> <workflowId>')
.description('Simulate a webhook call')
.option('--body <json>', 'JSON body to send')
.option('--method <method>', 'HTTP method (informational only)', 'POST')
.action((0, ctx_1.run)(async (ctx, args, o) => {
const [baseId, workflowId] = args;
const opts = o;
const body = opts.body ? JSON.parse(opts.body) : undefined;
const res = await ctx.client.fireWebhook(baseId, workflowId, body);
if (ctx.json)
(0, output_1.printJson)(res);
else {
process.stdout.write(`✓ Webhook fired for workflow ${workflowId}\n`);
if (typeof res === 'object' && res !== null) {
(0, output_1.printJson)(res);
}
}
}));
return cmd;
}
exports.fireCommand = fireCommand;
// ===================== sql =====================
function sqlCommand() {
const cmd = new commander_1.Command('sql');
cmd.description('Execute a read-only SQL query (SELECT only)');
cmd.option('--base-id <id>', 'Base id (overrides default)');
cmd.argument('<sql>', 'SQL SELECT statement');
cmd.action((0, ctx_1.run)(async (ctx, args, o) => {
const sql = args[0];
const opts = o;
const baseId = (0, ctx_1.requireBaseId)(ctx, opts.baseId);
const rows = (await ctx.client.sql(baseId, sql));
if (ctx.json) {
(0, output_1.printJson)(rows);
}
else {
if (!rows.length) {
process.stdout.write('No rows returned.\n');
return;
}
const first = rows[0];
if (typeof first === 'object' && first !== null && !Array.isArray(first)) {
const keys = Object.keys(first);
(0, output_1.printTable)(keys.map((k) => ({ key: k, header: k })), rows.map((r) => {
const obj = r;
const row = {};
for (const k of keys) {
row[k] = (0, output_1.truncate)(obj[k], 40);
}
return row;
}));
process.stdout.write(`\n${rows.length} row(s).\n`);
}
else {
rows.forEach((r) => process.stdout.write(JSON.stringify(r) + '\n'));
}
}
}));
return cmd;
}
exports.sqlCommand = sqlCommand;