Skip to content

Commit dfa2dbd

Browse files
committed
refactor(cli): use implicit stdin for cip query input
1 parent 6cf28f9 commit dfa2dbd

File tree

7 files changed

+22
-94
lines changed

7 files changed

+22
-94
lines changed

docs/cli/cip.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,13 @@ Provide SQL from exactly one source:
6363

6464
1. Positional argument (`b2c cip query "SELECT ..."`)
6565
2. `--file <path>`
66-
3. `--stdin`
66+
3. Piped stdin (for example `cat query.sql | b2c cip query ...`)
6767

6868
### Query-Specific Flags
6969

70-
| Flag | Description |
71-
| -------------- | ------------------------- |
72-
| `--file`, `-f` | Read SQL query from file |
73-
| `--stdin` | Read SQL query from stdin |
70+
| Flag | Description |
71+
| -------------- | ------------------------ |
72+
| `--file`, `-f` | Read SQL query from file |
7473

7574
### Placeholders
7675

@@ -101,7 +100,7 @@ b2c cip query \
101100
b2c cip query --file ./query.sql --tenant-id zzxy_prd --client-id <client-id> --client-secret <client-secret>
102101

103102
# Read SQL from stdin
104-
cat ./query.sql | b2c cip query --stdin --tenant-id zzxy_prd --client-id <client-id> --client-secret <client-secret>
103+
cat ./query.sql | b2c cip query --tenant-id zzxy_prd --client-id <client-id> --client-secret <client-secret>
105104
```
106105

107106
## b2c cip report
@@ -126,7 +125,7 @@ Use `--sql` to pipe into `cip query`:
126125

127126
```bash
128127
b2c cip report sales-analytics --site-id Sites-RefArch-Site --sql \
129-
| b2c cip query --stdin --tenant-id zzxy_prd --client-id <client-id> --client-secret <client-secret>
128+
| b2c cip query --tenant-id zzxy_prd --client-id <client-id> --client-secret <client-secret>
130129
```
131130

132131
### Report Commands

docs/guide/analytics-reports-cip-ccac.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ Pipe generated SQL into raw query execution:
103103

104104
```bash
105105
b2c cip report sales-analytics --tenant-id abcd_prd --site-id Sites-RefArch-Site --sql \
106-
| b2c cip query --tenant-id abcd_prd --stdin
106+
| b2c cip query --tenant-id abcd_prd
107107

108108
# force staging analytics host
109109
b2c cip report sales-analytics --tenant-id abcd_prd --site-id Sites-RefArch-Site --staging --sql

packages/b2c-cli/bin/dev.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,4 @@ if (userWantsTelemetryEnabled) {
2727

2828
import {execute} from '@oclif/core';
2929

30-
function shouldBufferCipQueryStdin(argv) {
31-
return argv.includes('cip') && argv.includes('query') && argv.includes('--stdin');
32-
}
33-
34-
if (shouldBufferCipQueryStdin(process.argv) && !process.stdin.isTTY) {
35-
let bufferedInput = '';
36-
for await (const chunk of process.stdin) {
37-
bufferedInput += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
38-
}
39-
40-
process.env.SFCC_CIP_QUERY_STDIN = bufferedInput;
41-
}
42-
4330
await execute({development: true, dir: import.meta.url});

packages/b2c-cli/bin/run.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,4 @@ try {
1414

1515
import {execute} from '@oclif/core';
1616

17-
function shouldBufferCipQueryStdin(argv) {
18-
return argv.includes('cip') && argv.includes('query') && argv.includes('--stdin');
19-
}
20-
21-
if (shouldBufferCipQueryStdin(process.argv) && !process.stdin.isTTY) {
22-
let bufferedInput = '';
23-
for await (const chunk of process.stdin) {
24-
bufferedInput += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
25-
}
26-
27-
process.env.SFCC_CIP_QUERY_STDIN = bufferedInput;
28-
}
29-
3017
await execute({dir: import.meta.url});

packages/b2c-cli/src/commands/cip/query.ts

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,10 @@ export default class CipQuery extends CipCommand<typeof CipQuery> {
3636
description: 'Read SQL query from file',
3737
helpGroup: 'QUERY',
3838
}),
39-
stdin: Flags.boolean({
40-
description: 'Read SQL query from stdin',
41-
default: false,
42-
helpGroup: 'QUERY',
43-
}),
4439
};
4540

4641
async run(): Promise<CipQueryCommandResult> {
47-
const sql = await this.resolveSql();
42+
const sql = this.resolveSql();
4843

4944
this.requireCipCredentials();
5045
const client = this.getCipClient();
@@ -69,21 +64,6 @@ export default class CipQuery extends CipCommand<typeof CipQuery> {
6964
return output;
7065
}
7166

72-
private async readSqlFromStdin(): Promise<string> {
73-
const preBufferedInput = process.env.SFCC_CIP_QUERY_STDIN;
74-
if (preBufferedInput !== undefined) {
75-
return preBufferedInput;
76-
}
77-
78-
let data = '';
79-
80-
for await (const chunk of process.stdin) {
81-
data += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
82-
}
83-
84-
return data;
85-
}
86-
8767
private renderRows(columns: string[], rows: Array<Record<string, unknown>>, format: CipOutputFormat): void {
8868
if (format === 'csv') {
8969
process.stdout.write(`${toCsv(columns, rows)}\n`);
@@ -93,29 +73,21 @@ export default class CipQuery extends CipCommand<typeof CipQuery> {
9373
renderTable(columns, rows);
9474
}
9575

96-
private async resolveSql(): Promise<string> {
76+
private resolveSql(): string {
9777
const positionalSql = this.args.sql;
9878
const hasPositional = Boolean(positionalSql);
9979
const hasFile = Boolean(this.flags.file);
100-
const hasStdin = this.flags.stdin === true;
101-
102-
if (hasStdin && hasFile) {
103-
this.error('Use either --stdin or --file, not both.');
104-
}
80+
const sourceCount = [hasPositional, hasFile].filter(Boolean).length;
10581

106-
if (!hasStdin && hasFile && hasPositional) {
107-
this.error('Use either a positional SQL argument or --file, not both.');
82+
if (sourceCount === 0) {
83+
this.error('No SQL provided. Pass SQL as an argument, pipe SQL through stdin, or use --file.');
10884
}
10985

110-
if (!hasStdin && !hasFile && !hasPositional) {
111-
this.error('No SQL provided. Pass SQL as an argument, or use --file / --stdin.');
86+
if (sourceCount > 1) {
87+
this.error('Provide SQL from exactly one source: positional argument/stdin, or --file.');
11288
}
11389

114-
const rawSql = hasStdin
115-
? await this.readSqlFromStdin()
116-
: hasFile
117-
? fs.readFileSync(this.flags.file as string, 'utf8')
118-
: positionalSql;
90+
const rawSql = hasFile ? fs.readFileSync(this.flags.file as string, 'utf8') : positionalSql;
11991

12092
if (!rawSql || rawSql.trim().length === 0) {
12193
this.error('SQL input is empty.');

packages/b2c-cli/test/commands/cip/query.test.ts

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,15 @@ describe('cip query', () => {
2020
expect(error).to.be.undefined;
2121
});
2222

23-
it('requires one SQL source flag', async () => {
23+
it('requires one SQL source', async () => {
2424
const {error} = await runCommand('cip query --tenant-id zzxy_prd --client-id test --client-secret secret');
2525
expect(error).to.not.be.undefined;
2626
expect(error?.message).to.include('No SQL provided');
2727
});
2828

29-
it('rejects conflicting file and stdin sources', async () => {
30-
const {error} = await runCommand('cip query --stdin --file ./query.sql');
29+
it('rejects positional SQL when --file is also set', async () => {
30+
const {error} = await runCommand('cip query "SELECT 1" --file ./query.sql');
3131
expect(error).to.not.be.undefined;
32-
expect(error?.message).to.include('either --stdin or --file');
33-
});
34-
35-
it('prioritizes --stdin over positional SQL source', async () => {
36-
const {error} = await runCommand('cip query "SELECT 1" --stdin');
37-
expect(error).to.not.be.undefined;
38-
expect(error?.message).to.include('SQL input is empty');
39-
});
40-
41-
it('uses pre-buffered stdin fallback when stream is unavailable', async () => {
42-
process.env.SFCC_CIP_QUERY_STDIN = 'SELECT 1';
43-
44-
const {error} = await runCommand(
45-
'cip query --stdin --tenant-id zzxy_prd --client-id test --client-secret test --cip-host 127.0.0.1:9',
46-
);
47-
48-
expect(error).to.not.be.undefined;
49-
expect(error?.message).to.not.include('SQL input is empty');
32+
expect(error?.message).to.include('exactly one source');
5033
});
5134
});

skills/b2c-cli/skills/b2c-cip/SKILL.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Reports & Dashboards non-production URL: `https://ccac.stg.analytics.commerceclo
5151
1. Start with curated report commands (`b2c cip report --help`).
5252
2. Use `--describe` to inspect expected parameters.
5353
3. Use `--sql` to preview generated SQL.
54-
4. Pipe SQL into `cip query --stdin` when you need custom execution/output handling.
54+
4. Pipe SQL into `cip query` when you need custom execution/output handling.
5555

5656
## Curated Report Examples
5757

@@ -82,7 +82,7 @@ b2c cip report top-referrers --site-id Sites-RefArch-Site --limit 25 --staging -
8282

8383
```bash
8484
b2c cip report sales-analytics --site-id Sites-RefArch-Site --sql \
85-
| b2c cip query --stdin --tenant-id zzxy_prd --client-id <client-id> --client-secret <client-secret>
85+
| b2c cip query --tenant-id zzxy_prd --client-id <client-id> --client-secret <client-secret>
8686
```
8787

8888
## Raw SQL Query Examples
@@ -98,7 +98,7 @@ b2c cip query \
9898
You can also use:
9999

100100
- `--file ./query.sql`
101-
- `--stdin` (pipe query text from standard input)
101+
- pipe query text from standard input (for example `cat query.sql | b2c cip query ...`)
102102

103103
### Date Placeholders
104104

0 commit comments

Comments
 (0)