diff --git a/packages/b2c-cli/package.json b/packages/b2c-cli/package.json index b3319fc2..6146e3f9 100644 --- a/packages/b2c-cli/package.json +++ b/packages/b2c-cli/package.json @@ -17,7 +17,8 @@ "@salesforce/b2c-tooling-sdk": "workspace:*", "cliui": "^9.0.1", "marked": "^15.0.0", - "marked-terminal": "^7.3.0" + "marked-terminal": "^7.3.0", + "open": "^11.0.0" }, "bundleDependencies": [ "@oclif/core", diff --git a/packages/b2c-cli/src/commands/slas/client/open.ts b/packages/b2c-cli/src/commands/slas/client/open.ts new file mode 100644 index 00000000..a7a6f243 --- /dev/null +++ b/packages/b2c-cli/src/commands/slas/client/open.ts @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025, Salesforce, Inc. + * SPDX-License-Identifier: Apache-2 + * For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0 + */ +import {Args, Flags} from '@oclif/core'; +import {BaseCommand} from '@salesforce/b2c-tooling-sdk/cli'; +import {t} from '../../../i18n/index.js'; + +async function openBrowser(url: string): Promise { + try { + const open = await import('open'); + await open.default(url); + } catch { + // If open fails, the URL will still be printed to console + } +} + +export default class SlasClientOpen extends BaseCommand { + static args = { + clientId: Args.string({ + description: 'SLAS client ID to open in the admin UI', + required: true, + }), + }; + + static description = t('commands.slas.client.open.description', 'Open the SLAS Admin UI for a client'); + + static examples = [ + '<%= config.bin %> <%= command.id %> my-client-id --tenant-id abcd_123', + '<%= config.bin %> <%= command.id %> my-client-id --tenant-id abcd_123 --short-code kv7kzm78', + ]; + + static flags = { + ...BaseCommand.baseFlags, + 'tenant-id': Flags.string({ + description: 'SLAS tenant ID (organization ID)', + env: 'SFCC_TENANT_ID', + required: true, + }), + 'short-code': Flags.string({ + description: 'SCAPI short code', + env: 'SFCC_SHORTCODE', + }), + }; + + async run(): Promise<{url: string}> { + const {'tenant-id': tenantId, 'short-code': shortCodeFlag} = this.flags; + const {clientId} = this.args; + + const shortCode = shortCodeFlag ?? this.resolvedConfig.shortCode; + + if (!shortCode) { + this.error( + t( + 'error.shortCodeRequired', + 'SCAPI short code required. Provide --short-code, set SFCC_SHORTCODE, or configure short-code in dw.json.', + ), + ); + } + + const url = `https://${shortCode}.api.commercecloud.salesforce.com/shopper/auth-admin/v1/ui/client?clientId=${encodeURIComponent(clientId)}&tenantId=${encodeURIComponent(tenantId)}`; + + this.log(t('commands.slas.client.open.opening', 'Opening SLAS Admin UI...')); + this.log(url); + + await openBrowser(url); + + return {url}; + } +} diff --git a/packages/b2c-cli/src/commands/slas/client/update.ts b/packages/b2c-cli/src/commands/slas/client/update.ts index 243f7d5d..a07f4876 100644 --- a/packages/b2c-cli/src/commands/slas/client/update.ts +++ b/packages/b2c-cli/src/commands/slas/client/update.ts @@ -119,11 +119,11 @@ export default class SlasClientUpdate extends SlasClientCommand (typeof uri === 'string' ? uri.split('|').map((s) => s.trim()) : [])) : typeof existing.redirectUri === 'string' - ? [existing.redirectUri] + ? existing.redirectUri.split('|').map((s) => s.trim()) : []; // oclif handles comma-separation via delimiter option diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ca377f4a..80477e3c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ importers: marked-terminal: specifier: ^7.3.0 version: 7.3.0(marked@15.0.12) + open: + specifier: ^11.0.0 + version: 11.0.0 devDependencies: '@eslint/compat': specifier: ^1