Skip to content

Commit b570575

Browse files
committed
Merge branch 'main' into feature/open-source-template
2 parents 86090ea + 9a6d98c commit b570575

19 files changed

Lines changed: 931 additions & 0 deletions

File tree

easy-setup-step-by-step.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env bash
2+
3+
export SFCC_MRT_PROJECT=cli
4+
export REALM="zzpq"
5+
export SFCC_CLIENT_ID="a0a4deb0-5e03-477b-bfdc-e42ccfae6161"
6+
7+
b2c ods create -r $REALM --wait --ttl 0
8+
9+
# create mrt env called chuck in the cli project
10+
b2c mrt env create chuck --name chuck \
11+
--allow-cookies \
12+
--proxy api=kv7kzm78.api.commercecloud.salesforce.com \
13+
--proxy einstein=api.cquotient.com
14+
15+
# construct redirect-uri from ssr_external_hostname above and don't use localhost:3000
16+
b2c slas client create \
17+
--channels MarketStreet \
18+
--tenant-id zzpq_014 \
19+
--short-code kv7kzm78 \
20+
--redirect-uri https://myproject-chuck.sfdc-8tgtt5-ecom1.exp-delivery.com/callback,http://localhost:3000/callback \
21+
--default-scopes
22+
23+
# get clientId and COMMERCE_API_SLAS_SECRET from the output of the previous command and callback from the redirect-uri above
24+
b2c mrt env var set -e chuck \
25+
PUBLIC__app__commerce__api__clientId=5810be72-3b2f-49bc-8ca1-eb88119de2fa \
26+
PUBLIC__app__commerce__api__organizationId=f_ecom_zzpq_014 \
27+
PUBLIC__app__commerce__api__siteId=RefArch \
28+
PUBLIC__app__commerce__api__shortCode= \
29+
PUBLIC__app__commerce__api__callback=https://myproject-chuck.sfdc-8tgtt5-ecom1.exp-delivery.com/callback \
30+
PUBLIC__app__commerce__api__privateKeyEnabled=true \
31+
COMMERCE_API_SLAS_SECRET=sk_kasdjlkjsalkjasd
32+
33+
# import market street data from storefront-datasets repo
34+
b2c job import --server zzpq-014.dx.commercecloud.salesforce.com ~/code/storefront-datasets/demo_data_marketstreet
35+
36+
b2c code deploy
37+
b2c mrt push -e headertest -p cli -b ~/code/SFCC-Odyssey/packages/template-retail-rsc-app/build --ssr-only='ssr.js,ssr.mjs,chunk.mjs,server/**/*'
38+
39+

easy-setup.sh

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Configuration - modify these values for your setup
5+
ENV_SLUG="demo15"
6+
ENV_NAME="demo15"
7+
SITE_ID="RefArch"
8+
TENANT_ID="zzpq_013"
9+
ORGANIZATION_ID="f_ecom_zzsa_009"
10+
SHORT_CODE="kv7kzm78"
11+
BUILD_PATH="${BUILD_PATH:-$HOME/code/SFCC-Odyssey/packages/template-retail-rsc-app/build}"
12+
13+
export SFCC_MRT_PROJECT="${SFCC_MRT_PROJECT:-cli}"
14+
15+
echo "=== Step 1: Creating MRT environment ==="
16+
ENV_JSON=$(b2c mrt env create "$ENV_SLUG" --name "$ENV_NAME" --json)
17+
echo "Environment created."
18+
19+
# Extract the external hostname for the callback URL
20+
SSR_EXTERNAL_HOSTNAME=$(echo "$ENV_JSON" | jq -r '.ssr_external_hostname // empty')
21+
if [[ -z "$SSR_EXTERNAL_HOSTNAME" ]]; then
22+
# Fall back to hostname if external hostname not set
23+
SSR_EXTERNAL_HOSTNAME=$(echo "$ENV_JSON" | jq -r '.hostname // empty')
24+
fi
25+
26+
if [[ -z "$SSR_EXTERNAL_HOSTNAME" ]]; then
27+
echo "Warning: Could not determine external hostname from environment. Using localhost."
28+
CALLBACK_URL="http://localhost:3000/callback"
29+
else
30+
CALLBACK_URL="https://${SSR_EXTERNAL_HOSTNAME}/callback"
31+
fi
32+
echo "Callback URL: $CALLBACK_URL"
33+
34+
echo ""
35+
echo "=== Step 2: Creating SLAS client ==="
36+
SLAS_JSON=$(b2c slas client create --channels "$SITE_ID" \
37+
--redirect-uri "$CALLBACK_URL" \
38+
--default-scopes \
39+
--tenant-id "$TENANT_ID" \
40+
--json)
41+
echo "SLAS client created."
42+
43+
# Extract client ID and secret from SLAS response
44+
CLIENT_ID=$(echo "$SLAS_JSON" | jq -r '.clientId')
45+
CLIENT_SECRET=$(echo "$SLAS_JSON" | jq -r '.secret // empty')
46+
47+
if [[ -z "$CLIENT_ID" ]]; then
48+
echo "Error: Failed to get client ID from SLAS response"
49+
exit 1
50+
fi
51+
52+
echo "Client ID: $CLIENT_ID"
53+
if [[ -n "$CLIENT_SECRET" ]]; then
54+
echo "Client Secret: $CLIENT_SECRET (save this - it won't be shown again)"
55+
fi
56+
57+
echo ""
58+
echo "=== Step 3: Setting environment variables ==="
59+
b2c mrt env var set -e "$ENV_SLUG" \
60+
"PUBLIC__app__commerce__api__clientId=$CLIENT_ID" \
61+
"PUBLIC__app__commerce__api__organizationId=$ORGANIZATION_ID" \
62+
"PUBLIC__app__commerce__api__siteId=$SITE_ID" \
63+
"PUBLIC__app__commerce__api__shortCode=$SHORT_CODE" \
64+
"PUBLIC__app__commerce__api__proxy=/mobify/proxy/api" \
65+
"PUBLIC__app__commerce__api__callback=$CALLBACK_URL" \
66+
"PUBLIC__app__commerce__api__privateKeyEnabled=true" \
67+
${CLIENT_SECRET:+"COMMERCE_API_SLAS_SECRET=$CLIENT_SECRET"}
68+
69+
echo ""
70+
echo "=== Step 4: Deploying code ==="
71+
b2c code deploy
72+
73+
echo ""
74+
echo "=== Step 5: Importing job data ==="
75+
b2c job import data/urls
76+
77+
echo ""
78+
echo "=== Step 6: Pushing to MRT ==="
79+
b2c mrt push -e "$ENV_SLUG" -b "$BUILD_PATH"
80+
81+
echo ""
82+
echo "=== Setup Complete ==="
83+
echo "Environment: $ENV_SLUG"
84+
echo "Client ID: $CLIENT_ID"
85+
echo "URL: https://${SSR_EXTERNAL_HOSTNAME:-localhost:3000}"

packages/b2c-cli/src/i18n/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
* SPDX-License-Identifier: Apache-2
44
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
55
*/
6+
/**
7+
* i18n setup for b2c-cli.
8+
*
9+
* This module registers CLI-specific translations with the 'cli' namespace.
10+
* The core i18n infrastructure comes from @salesforce/b2c-tooling-sdk.
11+
*
12+
* Usage in commands:
13+
* import { t } from '../i18n/index.js'
14+
* this.log(t('commands.sites.list.fetching', 'Fetching sites from {{hostname}}...', { hostname }))
15+
*/
616

717
import {registerTranslations, t as toolingT, type TOptions} from '@salesforce/b2c-tooling-sdk';
818
import {locales} from './locales/index.js';

packages/b2c-tooling-sdk/src/auth/index.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,61 @@
33
* SPDX-License-Identifier: Apache-2
44
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
55
*/
6+
/**
7+
* Authentication strategies for B2C Commerce APIs.
8+
*
9+
* This module provides different authentication mechanisms for connecting to
10+
* B2C Commerce instances and platform services.
11+
*
12+
* ## Available Strategies
13+
*
14+
* - {@link BasicAuthStrategy} - Username/password authentication for WebDAV operations
15+
* - {@link OAuthStrategy} - OAuth 2.0 client credentials for OCAPI and platform APIs
16+
* - {@link ImplicitOAuthStrategy} - Interactive browser-based OAuth for CLI/desktop apps
17+
* - {@link ApiKeyStrategy} - API key authentication for MRT services
18+
*
19+
* ## Strategy Resolution
20+
*
21+
* Use {@link resolveAuthStrategy} to automatically select the best strategy based on
22+
* available credentials and allowed methods:
23+
*
24+
* ```typescript
25+
* import { resolveAuthStrategy } from '@salesforce/b2c-tooling-sdk';
26+
*
27+
* // Automatically picks client-credentials if secret available, otherwise implicit
28+
* const strategy = resolveAuthStrategy({
29+
* clientId: 'your-client-id',
30+
* clientSecret: process.env.CLIENT_SECRET, // may be undefined
31+
* });
32+
*
33+
* // Force a specific method
34+
* const implicitOnly = resolveAuthStrategy(
35+
* { clientId: 'your-client-id' },
36+
* { allowedMethods: ['implicit'] }
37+
* );
38+
* ```
39+
*
40+
* ## Direct Usage
41+
*
42+
* All strategies implement the {@link AuthStrategy} interface:
43+
*
44+
* ```typescript
45+
* import { OAuthStrategy, ImplicitOAuthStrategy } from '@salesforce/b2c-tooling-sdk';
46+
*
47+
* // For automated/server usage (client credentials)
48+
* const oauthAuth = new OAuthStrategy({
49+
* clientId: 'your-client-id',
50+
* clientSecret: 'your-client-secret',
51+
* });
52+
*
53+
* // For interactive/CLI usage (opens browser)
54+
* const implicitAuth = new ImplicitOAuthStrategy({
55+
* clientId: 'your-client-id',
56+
* });
57+
* ```
58+
*
59+
* @module auth
60+
*/
661

762
// Types
863
export type {

packages/b2c-tooling-sdk/src/auth/resolve.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,29 @@
33
* SPDX-License-Identifier: Apache-2
44
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
55
*/
6+
/**
7+
* Auth strategy resolution utilities.
8+
*
9+
* This module provides functions to automatically select and create the appropriate
10+
* authentication strategy based on available credentials and allowed methods.
11+
*
12+
* ## Usage
13+
*
14+
* ```typescript
15+
* import { resolveAuthStrategy, checkAvailableAuthMethods } from '@salesforce/b2c-tooling-sdk';
16+
*
17+
* // Auto-select best strategy based on credentials
18+
* const strategy = resolveAuthStrategy({
19+
* clientId: 'my-client-id',
20+
* clientSecret: process.env.CLIENT_SECRET,
21+
* });
22+
*
23+
* // Check which methods are available
24+
* const { available, unavailable } = checkAvailableAuthMethods(credentials);
25+
* ```
26+
*
27+
* @module auth/resolve
28+
*/
629

730
import type {AuthStrategy, AuthMethod, AuthCredentials} from './types.js';
831
import {ALL_AUTH_METHODS} from './types.js';

packages/b2c-tooling-sdk/src/cli/index.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,90 @@
33
* SPDX-License-Identifier: Apache-2
44
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
55
*/
6+
/**
7+
* CLI utilities and base command classes for building B2C Commerce CLI commands.
8+
*
9+
* This module provides reusable base classes, configuration loading, and table
10+
* rendering utilities for oclif-based CLI applications.
11+
*
12+
* ## Base Command Classes
13+
*
14+
* Extend these classes to create CLI commands with pre-configured functionality:
15+
*
16+
* - {@link BaseCommand} - Foundation class with logging, JSON output, and error handling
17+
* - {@link OAuthCommand} - Adds OAuth authentication setup
18+
* - {@link InstanceCommand} - Adds B2C Commerce instance configuration
19+
* - {@link CartridgeCommand} - Adds cartridge path configuration for code operations
20+
* - {@link JobCommand} - Adds job execution configuration
21+
* - {@link MrtCommand} - Adds Managed Runtime API authentication
22+
* - {@link OdsCommand} - Adds On-Demand Sandbox configuration
23+
*
24+
* ## Command Hierarchy
25+
*
26+
* Commands inherit in a chain, each adding specific functionality:
27+
*
28+
* ```
29+
* BaseCommand
30+
* └─ OAuthCommand (adds OAuth)
31+
* └─ InstanceCommand (adds instance config)
32+
* ├─ CartridgeCommand (adds cartridge paths)
33+
* └─ JobCommand (adds job config)
34+
* └─ MrtCommand (adds MRT API auth)
35+
* └─ OdsCommand (adds ODS config)
36+
* ```
37+
*
38+
* ## Example Usage
39+
*
40+
* ```typescript
41+
* import { InstanceCommand, createTable, type ColumnDef } from '@salesforce/b2c-tooling-sdk/cli';
42+
*
43+
* export default class ListSites extends InstanceCommand {
44+
* static description = 'List all sites on the instance';
45+
*
46+
* async run() {
47+
* const client = await this.createOcapiClient();
48+
* const sites = await client.getSites();
49+
*
50+
* const columns: Record<string, ColumnDef<Site>> = {
51+
* id: { header: 'ID', get: (s) => s.id },
52+
* name: { header: 'Name', get: (s) => s.display_name },
53+
* };
54+
*
55+
* createTable(columns).render(sites, ['id', 'name']);
56+
* }
57+
* }
58+
* ```
59+
*
60+
* ## Configuration Loading
61+
*
62+
* Use {@link loadConfig} to resolve configuration from multiple sources:
63+
*
64+
* ```typescript
65+
* import { loadConfig } from '@salesforce/b2c-tooling-sdk/cli';
66+
*
67+
* const config = await loadConfig({
68+
* flags: { hostname: 'example.com' },
69+
* configPath: './dw.json',
70+
* });
71+
* ```
72+
*
73+
* ## Table Rendering
74+
*
75+
* Use {@link createTable} for consistent tabular output:
76+
*
77+
* ```typescript
78+
* import { createTable, type ColumnDef } from '@salesforce/b2c-tooling-sdk/cli';
79+
*
80+
* const columns: Record<string, ColumnDef<Item>> = {
81+
* id: { header: 'ID', get: (item) => item.id },
82+
* status: { header: 'Status', get: (item) => item.status },
83+
* };
84+
*
85+
* createTable(columns).render(items, ['id', 'status']);
86+
* ```
87+
*
88+
* @module cli
89+
*/
690

791
// Base command classes
892
export {BaseCommand} from './base-command.js';

packages/b2c-tooling-sdk/src/cli/table.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,34 @@
33
* SPDX-License-Identifier: Apache-2
44
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
55
*/
6+
/**
7+
* Table rendering utilities for CLI output.
8+
*
9+
* Provides a consistent, flexible way to render tabular data in CLI commands
10+
* with dynamic column widths based on content.
11+
*
12+
* @module cli/table
13+
*
14+
* @example
15+
* ```typescript
16+
* import { TableRenderer, type ColumnDef } from '@salesforce/b2c-tooling-sdk/cli';
17+
*
18+
* interface User {
19+
* name: string;
20+
* email: string;
21+
* role: string;
22+
* }
23+
*
24+
* const columns: Record<string, ColumnDef<User>> = {
25+
* name: { header: 'Name', get: (u) => u.name },
26+
* email: { header: 'Email', get: (u) => u.email },
27+
* role: { header: 'Role', get: (u) => u.role },
28+
* };
29+
*
30+
* const table = new TableRenderer(columns);
31+
* table.render(users, ['name', 'email', 'role']);
32+
* ```
33+
*/
634
import {ux} from '@oclif/core';
735
import cliui from 'cliui';
836

0 commit comments

Comments
 (0)