Skip to content

Commit 7b3524f

Browse files
committed
slas:client:get render redirect & callback URIs as lists
The SLAS API returns redirectUri and callbackUri as pipe-delimited strings. printClientDetails now splits them via parseRedirectUris and renders one URI per line, matching the formatting used for scopes.
1 parent d0ae137 commit 7b3524f

3 files changed

Lines changed: 65 additions & 3 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@salesforce/b2c-cli': patch
3+
---
4+
5+
`b2c slas:client:get` now displays redirect URIs and callback URIs as lists (one per line) instead of the raw pipe-delimited strings returned by the SLAS API, matching the formatting used for scopes.

packages/b2c-cli/src/utils/slas/client.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,27 @@ export function normalizeClientResponse(client: Client): ClientOutput {
6666
*/
6767
export function printClientDetails(output: ClientOutput, showSecret = true): void {
6868
const ui = cliui({width: process.stdout.columns || 80});
69-
const labelWidth = 14;
69+
const labelWidth = 16;
7070

7171
ui.div('');
7272
ui.div({text: 'Client ID:', width: labelWidth}, {text: output.clientId});
7373
ui.div({text: 'Name:', width: labelWidth}, {text: output.name});
7474
ui.div({text: 'Private:', width: labelWidth}, {text: String(output.isPrivateClient)});
7575
ui.div({text: 'Channels:', width: labelWidth}, {text: output.channels.join(', ')});
7676
ui.div({text: 'Scopes:', width: labelWidth}, {text: output.scopes.join('\n' + ' '.repeat(labelWidth))});
77-
ui.div({text: 'Redirect URI:', width: labelWidth}, {text: output.redirectUri});
77+
78+
const redirectUris = parseRedirectUris(output.redirectUri);
79+
ui.div(
80+
{text: 'Redirect URIs:', width: labelWidth},
81+
{text: redirectUris.length > 0 ? redirectUris.join('\n' + ' '.repeat(labelWidth)) : ''},
82+
);
7883

7984
if (output.callbackUri) {
80-
ui.div({text: 'Callback URI:', width: labelWidth}, {text: output.callbackUri});
85+
const callbackUris = parseRedirectUris(output.callbackUri);
86+
ui.div(
87+
{text: 'Callback URIs:', width: labelWidth},
88+
{text: callbackUris.length > 0 ? callbackUris.join('\n' + ' '.repeat(labelWidth)) : output.callbackUri},
89+
);
8190
}
8291

8392
if (showSecret && output.secret) {

packages/b2c-cli/test/utils/slas/client.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,32 @@ describe('utils/slas/client', () => {
203203
expect(text).not.to.include('my-secret');
204204
});
205205

206+
it('renders multiple redirect URIs one per line', () => {
207+
const stdoutStub = sinon.stub(ux, 'stdout');
208+
const output = {
209+
clientId: 'client-1',
210+
name: 'Test',
211+
scopes: [],
212+
channels: [],
213+
redirectUri: 'http://a.example.com|http://b.example.com|http://c.example.com',
214+
isPrivateClient: true,
215+
};
216+
217+
printClientDetails(output, false);
218+
const text = stdoutStub.firstCall.args[0] as string;
219+
expect(text).to.include('Redirect URIs:');
220+
expect(text).to.not.include('|');
221+
const lines = text.split('\n');
222+
const aLine = lines.find((l) => l.includes('http://a.example.com'));
223+
const bLine = lines.find((l) => l.includes('http://b.example.com'));
224+
const cLine = lines.find((l) => l.includes('http://c.example.com'));
225+
expect(aLine, 'a on its own line').to.exist;
226+
expect(bLine, 'b on its own line').to.exist;
227+
expect(cLine, 'c on its own line').to.exist;
228+
expect(aLine).to.not.include('http://b.example.com');
229+
expect(bLine).to.not.include('http://c.example.com');
230+
});
231+
206232
it('prints callbackUri when present', () => {
207233
const stdoutStub = sinon.stub(ux, 'stdout');
208234
const output = {
@@ -220,5 +246,27 @@ describe('utils/slas/client', () => {
220246
const text = stdoutStub.firstCall.args[0];
221247
expect(text).to.include('https://example.com/cb');
222248
});
249+
250+
it('renders multiple callback URIs one per line', () => {
251+
const stdoutStub = sinon.stub(ux, 'stdout');
252+
const output = {
253+
clientId: 'client-1',
254+
name: 'Test',
255+
scopes: [],
256+
channels: [],
257+
redirectUri: '',
258+
isPrivateClient: true,
259+
callbackUri: 'https://a.example.com/cb|https://b.example.com/cb|https://c.example.com/cb',
260+
};
261+
262+
printClientDetails(output, false);
263+
const text = stdoutStub.firstCall.args[0] as string;
264+
expect(text).to.include('Callback URIs:');
265+
expect(text).to.not.include('|');
266+
const lines = text.split('\n');
267+
expect(lines.find((l) => l.includes('https://a.example.com/cb'))).to.exist;
268+
expect(lines.find((l) => l.includes('https://b.example.com/cb'))).to.exist;
269+
expect(lines.find((l) => l.includes('https://c.example.com/cb'))).to.exist;
270+
});
223271
});
224272
});

0 commit comments

Comments
 (0)