mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-10 08:05:14 +02:00
feat(cli): formalize dev-friendly result output
This commit is contained in:
parent
dbb40d53b1
commit
41ccf9f12a
3 changed files with 52 additions and 3 deletions
|
|
@ -20,6 +20,12 @@ describe('resolveOutputMode', () => {
|
|||
expect(resolveOutputMode({ explicit: 'pretty', json: true, io: ioWith(true), env: {} })).toBe('json');
|
||||
});
|
||||
|
||||
it('prefers explicit JSON over every other output setting', () => {
|
||||
expect(resolveOutputMode({ json: true, explicit: 'pretty', io: ioWith(true), env: { KTX_OUTPUT: 'plain' } })).toBe(
|
||||
'json',
|
||||
);
|
||||
});
|
||||
|
||||
it('throws on unknown explicit value', () => {
|
||||
expect(() => resolveOutputMode({ explicit: 'fancy', io: ioWith(true), env: {} })).toThrow(/Invalid --output/);
|
||||
});
|
||||
|
|
@ -34,6 +40,12 @@ describe('resolveOutputMode', () => {
|
|||
expect(() => resolveOutputMode({ io: ioWith(true), env: { KTX_OUTPUT: 'fancy' } })).toThrow(/Invalid KTX_OUTPUT/);
|
||||
});
|
||||
|
||||
it('rejects invalid KTX_OUTPUT values', () => {
|
||||
expect(() => resolveOutputMode({ io: ioWith(false), env: { KTX_OUTPUT: 'verbose' } })).toThrow(
|
||||
'Invalid KTX_OUTPUT value: verbose. Expected one of pretty, plain, json.',
|
||||
);
|
||||
});
|
||||
|
||||
it('returns plain when CI is set to a truthy value', () => {
|
||||
expect(resolveOutputMode({ io: ioWith(true), env: { CI: 'true' } })).toBe('plain');
|
||||
expect(resolveOutputMode({ io: ioWith(true), env: { CI: '1' } })).toBe('plain');
|
||||
|
|
|
|||
|
|
@ -42,6 +42,16 @@ export function printList<Row extends object>(args: PrintListArgs<Row>): void {
|
|||
}
|
||||
}
|
||||
|
||||
export interface KtxJsonResultEnvelope<T> {
|
||||
kind: string;
|
||||
data: T;
|
||||
meta?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export function writeJsonResult<T>(io: KtxCliIo, envelope: KtxJsonResultEnvelope<T>): void {
|
||||
io.stdout.write(`${JSON.stringify(envelope, null, 2)}\n`);
|
||||
}
|
||||
|
||||
function isEmpty(value: unknown): boolean {
|
||||
return value === undefined || value === null || value === '';
|
||||
}
|
||||
|
|
@ -61,12 +71,11 @@ function printListPlain<Row extends object>(args: PrintListArgs<Row>): void {
|
|||
}
|
||||
|
||||
function printListJson<Row extends object>(args: PrintListArgs<Row>): void {
|
||||
const envelope = {
|
||||
writeJsonResult(args.io, {
|
||||
kind: 'list',
|
||||
data: { items: args.rows },
|
||||
meta: { command: args.command },
|
||||
};
|
||||
args.io.stdout.write(`${JSON.stringify(envelope, null, 2)}\n`);
|
||||
});
|
||||
}
|
||||
|
||||
function pluralize(count: number, singular: string): string {
|
||||
|
|
|
|||
|
|
@ -400,6 +400,7 @@ joins: []
|
|||
expect(code).toBe(0);
|
||||
|
||||
const parsed = JSON.parse(listIo.stdout());
|
||||
expect(listIo.stderr()).toBe('');
|
||||
expect(parsed.kind).toBe('list');
|
||||
expect(parsed.meta).toEqual({ command: 'sl list' });
|
||||
expect(parsed.data.items).toHaveLength(1);
|
||||
|
|
@ -412,6 +413,33 @@ joins: []
|
|||
});
|
||||
});
|
||||
|
||||
it('prints sl list JSON as a single result envelope', async () => {
|
||||
const projectDir = join(tempDir, 'project');
|
||||
await initKtxProject({ projectDir, projectName: 'warehouse' });
|
||||
|
||||
const writeIo = makeIo();
|
||||
await runKtxSl(
|
||||
{ command: 'write', projectDir, connectionId: 'warehouse', sourceName: 'orders', yaml: ORDERS_YAML },
|
||||
writeIo.io,
|
||||
);
|
||||
|
||||
const listIo = makeIo();
|
||||
await expect(
|
||||
runKtxSl({ command: 'list', projectDir, connectionId: 'warehouse', json: true }, listIo.io),
|
||||
).resolves.toBe(0);
|
||||
|
||||
expect(listIo.stderr()).toBe('');
|
||||
expect(JSON.parse(listIo.stdout())).toMatchObject({
|
||||
kind: 'list',
|
||||
data: {
|
||||
items: expect.any(Array),
|
||||
},
|
||||
meta: {
|
||||
command: 'sl list',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('emits sl list with grouping and Clack-style framing when output=pretty', async () => {
|
||||
const projectDir = join(tempDir, 'project');
|
||||
await initKtxProject({ projectDir, projectName: 'warehouse' });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue