Skip to content

Commit ab356ed

Browse files
committed
Merge main into branch: resolved conflict in README.md by keeping both Prompting Tips and Configuration sections
2 parents 8d97e75 + b563936 commit ab356ed

119 files changed

Lines changed: 4129 additions & 1381 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/code-bugfix.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/doc-improvements.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/log-tailing-feature.md

Lines changed: 0 additions & 6 deletions
This file was deleted.

.changeset/mrt-warnings.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ jobs:
5757
- name: Run SDK tests
5858
id: sdk-test
5959
working-directory: packages/b2c-tooling-sdk
60-
run: pnpm run test:ci && pnpm run lint
60+
run: pnpm run pretest && pnpm run test:ci && pnpm run lint
6161

6262
- name: Run CLI tests
6363
id: cli-test
6464
if: always() && steps.sdk-test.conclusion != 'cancelled'
6565
working-directory: packages/b2c-cli
66-
run: pnpm run test:ci && pnpm run lint
66+
run: pnpm run pretest && pnpm run test:ci && pnpm run lint
6767

6868
- name: Test Report
6969
uses: dorny/test-reporter@fe45e9537387dac839af0d33ba56eed8e24189e8 # v2.3.0

.github/workflows/e2e-tests.yml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
name: e2e tests
22

33
on:
4-
# Nightly workflow - Run at 2 AM UTC daily
4+
# Scheduled workflow
5+
# 13:00 UTC ~= 8:00 AM ET (EST)
6+
# 01:00 UTC ~= 8:00 PM ET (EST)
57
schedule:
6-
- cron: '0 2 * * *'
7-
# Post-merge - Run after changes are merged to main
8-
push:
9-
branches: [main]
8+
- cron: '0 13 * * *'
9+
- cron: '0 1 * * *'
1010
# Manual trigger - Support workflow_dispatch for on-demand runs
1111
workflow_dispatch:
1212
inputs:
@@ -32,9 +32,10 @@ on:
3232
type: string
3333
jobs:
3434
e2e-tests:
35+
# E2E tests run only on the current LTS Node version for stability and speed.
3536
strategy:
3637
matrix:
37-
node-version: [22.x, 24.x]
38+
node-version: [22.x]
3839
runs-on: ubuntu-latest
3940
environment: e2e-dev
4041
timeout-minutes: 25
@@ -51,8 +52,10 @@ jobs:
5152
TEST_REALM: ${{ vars.TEST_REALM }}
5253
SFCC_ACCOUNT_MANAGER_HOST: ${{ vars.SFCC_ACCOUNT_MANAGER_HOST }}
5354
SFCC_SANDBOX_API_HOST: ${{ vars.SFCC_SANDBOX_API_HOST }}
55+
SFCC_SHORTCODE: ${{ vars.SFCC_SHORTCODE }}
56+
SFCC_EXTRA_HEADERS: ${{ secrets.SFCC_EXTRA_HEADERS }}
5457
run: |
55-
if [ -n "$SFCC_CLIENT_ID" ] && [ -n "$SFCC_CLIENT_SECRET" ] && [ -n "$TEST_REALM" ] && [ -n "$SFCC_ACCOUNT_MANAGER_HOST" ] && [ -n "$SFCC_SANDBOX_API_HOST" ]; then
58+
if [ -n "$SFCC_CLIENT_ID" ] && [ -n "$SFCC_CLIENT_SECRET" ] && [ -n "$TEST_REALM" ] && [ -n "$SFCC_ACCOUNT_MANAGER_HOST" ] && [ -n "$SFCC_SANDBOX_API_HOST" ] && [ -n "$SFCC_SHORTCODE" ]; then
5659
echo "has-secrets=true" >> $GITHUB_OUTPUT
5760
else
5861
echo "has-secrets=false" >> $GITHUB_OUTPUT
@@ -61,6 +64,7 @@ jobs:
6164
echo " - TEST_REALM (var): ${TEST_REALM:+✓}" >> $GITHUB_STEP_SUMMARY
6265
echo " - SFCC_ACCOUNT_MANAGER_HOST (var): ${SFCC_ACCOUNT_MANAGER_HOST:+✓}" >> $GITHUB_STEP_SUMMARY
6366
echo " - SFCC_SANDBOX_API_HOST (var): ${SFCC_SANDBOX_API_HOST:+✓}" >> $GITHUB_STEP_SUMMARY
67+
echo " - SFCC_SHORTCODE (var): ${SFCC_SHORTCODE:+✓}" >> $GITHUB_STEP_SUMMARY
6468
fi
6569
- name: Setup pnpm
6670
uses: pnpm/action-setup@v4
@@ -97,6 +101,8 @@ jobs:
97101
SFCC_ACCOUNT_MANAGER_HOST: ${{ inputs.sfcc_account_manager_host || vars.SFCC_ACCOUNT_MANAGER_HOST }}
98102
SFCC_SANDBOX_API_HOST: ${{ inputs.sfcc_sandbox_api_host || vars.SFCC_SANDBOX_API_HOST }}
99103
TEST_REALM: ${{ inputs.test_realm || vars.TEST_REALM }}
104+
SFCC_SHORTCODE: ${{ vars.SFCC_SHORTCODE }}
105+
SFCC_EXTRA_HEADERS: ${{ secrets.SFCC_EXTRA_HEADERS }}
100106
# Test configuration
101107
NODE_ENV: test
102108
SFCC_LOG_LEVEL: silent
@@ -124,7 +130,7 @@ jobs:
124130
retention-days: 30
125131

126132
- name: Notify on Failure
127-
if: failure() && (github.event_name == 'schedule' || github.event_name == 'push') && steps.check-secrets.outputs.has-secrets == 'true'
133+
if: failure() && github.event_name == 'schedule' && steps.check-secrets.outputs.has-secrets == 'true'
128134
uses: actions/github-script@v7
129135
with:
130136
script: |

docs/.vitepress/config.mts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ export default defineConfig({
5252
description: 'Salesforce Commerce Cloud B2C Developer Experience - CLI, MCP Server, and SDK',
5353
base: '/b2c-developer-tooling/',
5454

55+
// Ignore dead links in api-readme.md (links are valid after TypeDoc generates the API docs)
56+
ignoreDeadLinks: [/^\.\/clients\//],
57+
5558
// Show deeper heading levels in the outline
5659
markdown: {
5760
toc: { level: [2, 3, 4] },

docs/api-readme.md

Lines changed: 98 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,68 +4,98 @@ description: API reference for the B2C Tooling SDK with typed WebDAV and OCAPI c
44

55
# API Reference
66

7-
The `@salesforce/b2c-tooling-sdk` package provides a programmatic API for interacting with Salesforce B2C Commerce instances.
7+
The `@salesforce/b2c-tooling-sdk` package provides TypeScript APIs for B2C Commerce development, including instance clients (WebDAV, OCAPI), platform service clients (SCAPI, SLAS, MRT, ODS), high-level operations, and developer utilities.
88

99
## Installation
1010

1111
```bash
1212
npm install @salesforce/b2c-tooling-sdk
1313
```
1414

15-
## Quick Start
15+
## Package Structure
16+
17+
The SDK is organized into focused submodules that can be imported individually:
1618

17-
### From Configuration (Recommended)
19+
```
20+
@salesforce/b2c-tooling-sdk
21+
├── /config # Configuration resolution (dw.json, env vars)
22+
├── /auth # Authentication strategies (OAuth, Basic, API Key)
23+
├── /clients # Low-level API clients (WebDAV, OCAPI, SLAS, ODS, MRT)
24+
├── /logging # Pino-based logging configuration
25+
26+
├── /operations/code # Code deployment, cartridge management
27+
├── /operations/jobs # Job execution, site archive import/export
28+
├── /operations/logs # Log tailing and retrieval
29+
├── /operations/mrt # Managed Runtime bundle operations
30+
├── /operations/ods # On-demand sandbox utilities
31+
32+
├── /docs # B2C Script API documentation search
33+
└── /schemas # OpenAPI schema utilities
34+
```
1835

19-
Use `resolveConfig()` to load configuration from project files (dw.json) and create a B2C instance:
36+
Import from specific submodules to access their functionality:
2037

2138
```typescript
2239
import { resolveConfig } from '@salesforce/b2c-tooling-sdk/config';
40+
import { findAndDeployCartridges } from '@salesforce/b2c-tooling-sdk/operations/code';
41+
import { tailLogs } from '@salesforce/b2c-tooling-sdk/operations/logs';
42+
```
2343

24-
// Load configuration, override secrets from environment
25-
const config = resolveConfig({
26-
clientId: process.env.SFCC_CLIENT_ID,
27-
clientSecret: process.env.SFCC_CLIENT_SECRET,
28-
});
44+
## Quick Start
2945

30-
// Validate configuration before use
31-
if (!config.hasB2CInstanceConfig()) {
32-
throw new Error('Missing B2C instance configuration');
33-
}
46+
### B2C Instance Operations
3447

35-
// Create instance from validated config
36-
const instance = config.createB2CInstance();
48+
```typescript
49+
import { B2CInstance } from '@salesforce/b2c-tooling-sdk';
3750

38-
// Use typed WebDAV client
39-
await instance.webdav.mkcol('Cartridges/v1');
40-
await instance.webdav.put('Cartridges/v1/app.zip', zipBuffer);
51+
const instance = new B2CInstance(
52+
{ hostname: 'your-sandbox.demandware.net', codeVersion: 'v1' },
53+
{ oauth: { clientId: 'your-client-id', clientSecret: 'your-client-secret' } }
54+
);
4155

42-
// Use typed OCAPI client (openapi-fetch)
43-
const { data, error } = await instance.ocapi.GET('/sites', {
44-
params: { query: { select: '(**)' } },
45-
});
56+
// Typed WebDAV client
57+
await instance.webdav.put('Cartridges/v1/app.zip', zipBuffer);
4658

47-
// Check for configuration warnings
48-
for (const warning of config.warnings) {
49-
console.warn(warning.message);
50-
}
59+
// Typed OCAPI client (openapi-fetch)
60+
const { data } = await instance.ocapi.GET('/sites');
5161
```
5262

53-
### Direct Construction
63+
### Job Execution
64+
65+
```typescript
66+
import { executeJob, waitForJob } from '@salesforce/b2c-tooling-sdk/operations/jobs';
67+
68+
const execution = await executeJob(instance, 'MyCustomJob');
69+
const result = await waitForJob(instance, 'MyCustomJob', execution.id!);
70+
```
5471

55-
For advanced use cases, you can construct a B2CInstance directly:
72+
### Platform Service Clients
5673

5774
```typescript
58-
import { B2CInstance } from '@salesforce/b2c-tooling-sdk';
75+
import { createSlasClient, OAuthStrategy } from '@salesforce/b2c-tooling-sdk';
5976

60-
const instance = new B2CInstance(
61-
{ hostname: 'your-sandbox.demandware.net', codeVersion: 'v1' },
62-
{
63-
oauth: {
64-
clientId: 'your-client-id',
65-
clientSecret: 'your-client-secret'
66-
}
67-
}
68-
);
77+
const auth = new OAuthStrategy({
78+
clientId: 'your-client-id',
79+
clientSecret: 'your-client-secret',
80+
});
81+
82+
const slasClient = createSlasClient({ shortCode: 'kv7kzm78' }, auth);
83+
const { data } = await slasClient.GET('/tenants/{tenantId}/clients', {
84+
params: { path: { tenantId: 'your-tenant' } },
85+
});
86+
```
87+
88+
### MRT Operations
89+
90+
```typescript
91+
import { pushBundle, ApiKeyStrategy } from '@salesforce/b2c-tooling-sdk';
92+
93+
const auth = new ApiKeyStrategy(process.env.MRT_API_KEY!);
94+
const result = await pushBundle({
95+
projectSlug: 'my-storefront',
96+
buildDirectory: './build',
97+
target: 'staging',
98+
}, auth);
6999
```
70100

71101
## Configuration Resolution
@@ -105,33 +135,14 @@ if (config.hasB2CInstanceConfig()) {
105135

106136
// Check for MRT configuration
107137
if (config.hasMrtConfig()) {
108-
const mrtClient = config.createMrtClient({ project: 'my-project' });
138+
const mrtAuth = config.createMrtAuth();
109139
}
110140

111141
// Other validation methods
112142
config.hasOAuthConfig(); // OAuth credentials available?
113143
config.hasBasicAuthConfig(); // Basic auth credentials available?
114144
```
115145

116-
### Configuration Warnings
117-
118-
The config system detects potential issues and provides warnings:
119-
120-
```typescript
121-
const config = resolveConfig({
122-
hostname: 'staging.demandware.net', // Different from dw.json
123-
});
124-
125-
// Check warnings
126-
for (const warning of config.warnings) {
127-
console.warn(`[${warning.code}] ${warning.message}`);
128-
}
129-
```
130-
131-
### Hostname Protection
132-
133-
When you explicitly override the hostname with a value that differs from dw.json, the system protects against credential leakage by ignoring the dw.json credentials. This prevents accidentally using production credentials against a staging server.
134-
135146
## Authentication
136147

137148
B2CInstance supports multiple authentication methods:
@@ -169,32 +180,48 @@ When both are configured, WebDAV uses Basic auth and OCAPI uses OAuth.
169180

170181
## Typed Clients
171182

183+
The SDK provides typed clients for B2C Commerce APIs. All clients use [openapi-fetch](https://openapi-ts.dev/openapi-fetch/) for full TypeScript support with type-safe paths, parameters, and responses.
184+
185+
### Instance Clients
186+
187+
These clients are accessed via `B2CInstance` for operations on a specific B2C Commerce instance:
188+
189+
| Client | Description | API Reference |
190+
|--------|-------------|---------------|
191+
| [WebDavClient](./clients/classes/WebDavClient.md) | File operations (upload, download, list) | WebDAV |
192+
| [OcapiClient](./clients/type-aliases/OcapiClient.md) | Data API operations (sites, jobs, code versions) | [OCAPI Data API](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/b2c-commerce-ocapi/b2c-api-doc.html) |
193+
194+
### Platform Service Clients
195+
196+
These clients are created directly for platform-wide services:
197+
198+
| Client | Description | API Reference |
199+
|--------|-------------|---------------|
200+
| [SlasClient](./clients/type-aliases/SlasClient.md) | SLAS tenant and client management | [SLAS Admin API](https://developer.salesforce.com/docs/commerce/commerce-api/references/slas-admin?meta=Summary) |
201+
| [OdsClient](./clients/type-aliases/OdsClient.md) | On-demand sandbox management | [ODS REST API](https://developer.salesforce.com/docs/commerce/b2c-commerce/references/ods-rest-api?meta=Summary) |
202+
| [MrtClient](./clients/type-aliases/MrtClient.md) | Managed Runtime projects and deployments | [MRT Admin API](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-admin?meta=Summary) |
203+
| [MrtB2CClient](./clients/type-aliases/MrtB2CClient.md) | MRT B2C Commerce integration | [MRT B2C Config API](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/references/mrt-b2c-config?meta=Summary) |
204+
| [CdnZonesClient](./clients/type-aliases/CdnZonesClient.md) | eCDN zone and cache management | [CDN Zones API](https://developer.salesforce.com/docs/commerce/commerce-api/references/cdn-api-process-apis?meta=Summary) |
205+
| [ScapiSchemasClient](./clients/type-aliases/ScapiSchemasClient.md) | SCAPI schema discovery | [SCAPI Schemas API](https://developer.salesforce.com/docs/commerce/commerce-api/references/scapi-schemas?meta=Summary) |
206+
| [CustomApisClient](./clients/type-aliases/CustomApisClient.md) | Custom SCAPI endpoint status | [Custom APIs](https://developer.salesforce.com/docs/commerce/commerce-api/references/custom-apis?meta=Summary) |
207+
172208
### WebDAV Client
173209

174210
```typescript
175-
// Create directories
176-
await instance.webdav.mkcol('Cartridges/v1');
177-
178211
// Upload files
179212
await instance.webdav.put('Cartridges/v1/app.zip', buffer, 'application/zip');
180213

181-
// Download files
182-
const content = await instance.webdav.get('Cartridges/v1/app.zip');
183-
184-
// List directory
214+
// List directory contents
185215
const entries = await instance.webdav.propfind('Cartridges');
186216

187-
// Check existence
188-
const exists = await instance.webdav.exists('Cartridges/v1');
217+
// Download files
218+
const content = await instance.webdav.get('Cartridges/v1/app.zip');
189219

190-
// Delete
191-
await instance.webdav.delete('Cartridges/v1/old-file.zip');
220+
// Also supports: mkcol, exists, delete, unzip, request
192221
```
193222

194223
### OCAPI Client
195224

196-
The OCAPI client uses [openapi-fetch](https://openapi-ts.dev/openapi-fetch/) with full TypeScript support:
197-
198225
```typescript
199226
// List sites
200227
const { data, error } = await instance.ocapi.GET('/sites', {

0 commit comments

Comments
 (0)