作为命令
很容易在成功坑内创建命令
安装
npm install @ehmpathy/as-command
使用量
默认输出
创建一个简单的命令,用自动记录和输出持续处理数据:
import { asCommand } from '@ehmpathy/as-command';
import { COMMANDS_OUTPUT_DIRECTORY } from './constants';
const command = asCommand(
{
name: 'processData',
stage: process.env.STAGE || 'dev',
dir: COMMANDS_OUTPUT_DIRECTORY,
log,
},
async (input: { userId: string; date: string }, context) => {
context.log.info('starting data processing', { userId: input.userId });
// your business logic here
const result = {
processed: true,
recordCount: 42,
timestamp: new Date().toISOString(),
};
context.log.info('processing complete', { result });
return result;
},
);
// run directly
if (require.main === module) {
void command({
userId: 'user-123',
date: '2024-01-15',
});
}
输出结构 :
__tmp__/dev/processData/
└── 20240115.143022.a1b2c3d4.../
├── log.json # all logs from the run
└── out.json # command output
定制产出
创建组织输出的复杂目录结构 :
const command = asCommand(
{
name: 'analyzeData',
stage: 'prod',
dir: COMMANDS_OUTPUT_DIRECTORY,
log,
},
async (input: { datasetId: string }, context) => {
// write to nested directories - they're created automatically
await context.out.write({
name: 'reports/analytics/user-metrics.json',
data: JSON.stringify({ activeUsers: 1500 }),
});
await context.out.write({
name: 'reports/analytics/revenue-breakdown.csv',
data: 'Category,Amount\nSubscriptions,50000\nAds,25000',
});
await context.out.write({
name: 'exports/raw-data.json',
data: JSON.stringify({ records: [] }),
});
return { analyzed: true };
},
);
输出结构 :
__tmp__/prod/analyzeData/
└── 20240115.143022.i9j0k1l2.../
├── log.json
├── out.json
├── reports/
│ └── analytics/
│ ├── user-metrics.json
│ └── revenue-breakdown.csv
└── exports/
└── raw-data.json
概念
命令上下文
每个命令都收到一个 context 对象,使用下列方法:
context.log
记录不同级别的信息。 所有日志都写入控制台和 log.json数字 :
context.log.debug('debug message', { data: 'debug info' });
context.log.info('info message', { userId: 123 });
context.log.warn('warning message', { issue: 'potential problem' });
context.log.error('error message', { error: errorObject });
context.out.write()
将自定义文件写入命令的输出目录 :
const result = await context.out.write({
name: 'report.csv', // supports nested paths: 'reports/analytics/data.csv'
data: csvString, // string or Buffer
});
// result.path contains the full path to the written file
console.log(result.path);
输出目录结构
每个命令运行根据时间戳和输入散列创建一个独特的目录:
{dir}/__tmp__/{stage}/{command-name}/
└── {timestamp}.{input-hash}/
├── log.json # all logs from the run
├── out.json # command return value
└── ... # any files created with context.out.write()
示例:
/var/app/__tmp__/prod/process-orders/
├── 20240115.091530.a1b2c3d4e5f6.../
│ ├── log.json
│ ├── out.json
│ └── orders-summary.csv
└── 20240115.102045.a1b2c3d4e5f6.../ # same input, different time
├── log.json
├── out.json
└── orders-summary.csv
输入散列
命令使用 SHA-256 自动散列输入。这可以:
- 分解检测: 相同的输入产生相同的散列
- 审计线索: 当同一操作多次运行时跟踪
- 调试: 快速找到前一个输入相同的运行
// these two runs will have the same hash in their directory names:
await command({ userId: '123', action: 'process' });
await command({ userId: '123', action: 'process' });
// this run will have a different hash:
await command({ userId: '456', action: 'process' });