Skip to content

Commit b95fe98

Browse files
authored
feat: refactor SDK module structure for cleaner public API (#87)
* feat: refactor SDK module structure for cleaner public API Reorganize SDK modules to improve discoverability and align with documentation structure: Module reorganization: - Move operations/docs -> docs/ (top-level for B2C Script API docs) - Move operations/scapi-schemas -> schemas/ (top-level for OpenAPI utils) - Remove platform/ module (consolidated into operations/mrt, operations/ods) - Remove deprecated src/logger.ts (use logging/ module) Documentation updates: - Revise API landing page intro to reflect full SDK scope - Restructure Quick Start with capability examples (instance ops, jobs, platform clients, MRT operations) - Update typedoc.json entry points to match actual modules and align ordering with documentation structure CLI command updates: - Update docs commands to import from new @salesforce/b2c-tooling-sdk/docs - Update scapi schemas command to import from new /schemas module * docs: add curated endpoint documentation to API clients Add common endpoints table, code examples, and API reference links to each client type alias JSDoc. Also adds a Typed Clients section to the API landing page linking to all available clients.
1 parent bf7b8cd commit b95fe98

43 files changed

Lines changed: 375 additions & 900 deletions

Some content is hidden

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

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', {

packages/b2c-cli/src/commands/docs/download.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
import {Args, Flags} from '@oclif/core';
77
import {InstanceCommand} from '@salesforce/b2c-tooling-sdk/cli';
8-
import {downloadDocs, type DownloadDocsResult} from '@salesforce/b2c-tooling-sdk/operations/docs';
8+
import {downloadDocs, type DownloadDocsResult} from '@salesforce/b2c-tooling-sdk/docs';
99
import {t} from '../../i18n/index.js';
1010

1111
export default class DocsDownload extends InstanceCommand<typeof DocsDownload> {

packages/b2c-cli/src/commands/docs/read.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {marked} from 'marked';
88

99
import {markedTerminal} from 'marked-terminal';
1010
import {BaseCommand} from '@salesforce/b2c-tooling-sdk/cli';
11-
import {readDocByQuery, type DocEntry} from '@salesforce/b2c-tooling-sdk/operations/docs';
11+
import {readDocByQuery, type DocEntry} from '@salesforce/b2c-tooling-sdk/docs';
1212
import {t} from '../../i18n/index.js';
1313

1414
interface ReadDocsResult {

packages/b2c-cli/src/commands/docs/schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
import {Args, Flags} from '@oclif/core';
77
import {BaseCommand} from '@salesforce/b2c-tooling-sdk/cli';
8-
import {readSchemaByQuery, listSchemas, type SchemaEntry} from '@salesforce/b2c-tooling-sdk/operations/docs';
8+
import {readSchemaByQuery, listSchemas, type SchemaEntry} from '@salesforce/b2c-tooling-sdk/docs';
99
import {t} from '../../i18n/index.js';
1010

1111
interface SchemaResult {

packages/b2c-cli/src/commands/docs/search.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
import {Args, Flags, ux} from '@oclif/core';
77
import {BaseCommand, createTable, type ColumnDef} from '@salesforce/b2c-tooling-sdk/cli';
8-
import {searchDocs, listDocs, type SearchResult, type DocEntry} from '@salesforce/b2c-tooling-sdk/operations/docs';
8+
import {searchDocs, listDocs, type SearchResult, type DocEntry} from '@salesforce/b2c-tooling-sdk/docs';
99
import {t} from '../../i18n/index.js';
1010

1111
interface SearchDocsResponse {

packages/b2c-cli/src/commands/scapi/schemas/get.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
getSchemaNames,
1111
getExampleNames,
1212
type OpenApiSchemaInput,
13-
} from '@salesforce/b2c-tooling-sdk/operations/scapi-schemas';
13+
} from '@salesforce/b2c-tooling-sdk/schemas';
1414
import {ScapiSchemasCommand, formatApiError} from '../../../utils/scapi/schemas.js';
1515
import {t, withDocs} from '../../../i18n/index.js';
1616

packages/b2c-tooling-sdk/package.json

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,6 @@
5757
"default": "./dist/cjs/instance/index.js"
5858
}
5959
},
60-
"./platform": {
61-
"development": "./src/platform/index.ts",
62-
"import": {
63-
"types": "./dist/esm/platform/index.d.ts",
64-
"default": "./dist/esm/platform/index.js"
65-
},
66-
"require": {
67-
"types": "./dist/cjs/platform/index.d.ts",
68-
"default": "./dist/cjs/platform/index.js"
69-
}
70-
},
7160
"./operations/code": {
7261
"development": "./src/operations/code/index.ts",
7362
"import": {
@@ -101,26 +90,26 @@
10190
"default": "./dist/cjs/operations/mrt/index.js"
10291
}
10392
},
104-
"./operations/docs": {
105-
"development": "./src/operations/docs/index.ts",
93+
"./docs": {
94+
"development": "./src/docs/index.ts",
10695
"import": {
107-
"types": "./dist/esm/operations/docs/index.d.ts",
108-
"default": "./dist/esm/operations/docs/index.js"
96+
"types": "./dist/esm/docs/index.d.ts",
97+
"default": "./dist/esm/docs/index.js"
10998
},
11099
"require": {
111-
"types": "./dist/cjs/operations/docs/index.d.ts",
112-
"default": "./dist/cjs/operations/docs/index.js"
100+
"types": "./dist/cjs/docs/index.d.ts",
101+
"default": "./dist/cjs/docs/index.js"
113102
}
114103
},
115-
"./operations/scapi-schemas": {
116-
"development": "./src/operations/scapi-schemas/index.ts",
104+
"./schemas": {
105+
"development": "./src/schemas/index.ts",
117106
"import": {
118-
"types": "./dist/esm/operations/scapi-schemas/index.d.ts",
119-
"default": "./dist/esm/operations/scapi-schemas/index.js"
107+
"types": "./dist/esm/schemas/index.d.ts",
108+
"default": "./dist/esm/schemas/index.js"
120109
},
121110
"require": {
122-
"types": "./dist/cjs/operations/scapi-schemas/index.d.ts",
123-
"default": "./dist/cjs/operations/scapi-schemas/index.js"
111+
"types": "./dist/cjs/schemas/index.d.ts",
112+
"default": "./dist/cjs/schemas/index.js"
124113
}
125114
},
126115
"./operations/logs": {

packages/b2c-tooling-sdk/src/cli/mrt-command.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import {loadConfig, extractMrtFlags} from './config.js';
99
import type {LoadConfigOptions} from './config.js';
1010
import type {ResolvedB2CConfig} from '../config/index.js';
1111
import type {AuthStrategy} from '../auth/types.js';
12-
import {MrtClient} from '../platform/mrt.js';
13-
import type {MrtProject} from '../platform/mrt.js';
1412
import {t} from '../i18n/index.js';
1513
import {DEFAULT_MRT_ORIGIN} from '../clients/mrt.js';
1614

@@ -108,13 +106,4 @@ export abstract class MrtCommand<T extends typeof Command> extends BaseCommand<T
108106
);
109107
}
110108
}
111-
112-
/**
113-
* Creates an MRT client for the given project.
114-
*/
115-
protected createMrtClient(project: MrtProject): MrtClient {
116-
this.requireMrtCredentials();
117-
118-
return new MrtClient(project, this.getMrtAuth());
119-
}
120109
}

packages/b2c-tooling-sdk/src/cli/oauth-command.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,6 @@ export abstract class OAuthCommand<T extends typeof Command> extends BaseCommand
7070
}),
7171
};
7272

73-
/**
74-
* Parses auth methods from flags.
75-
* Returns methods in the order specified (priority order).
76-
* @deprecated Use extractOAuthFlags() instead which handles this internally
77-
*/
78-
protected parseAuthMethods(): AuthMethod[] | undefined {
79-
const flagValues = this.flags['auth-methods'] as string[] | undefined;
80-
if (!flagValues || flagValues.length === 0) {
81-
return undefined;
82-
}
83-
84-
const methods = flagValues
85-
.map((s) => s.trim())
86-
.filter((s): s is AuthMethod => ALL_AUTH_METHODS.includes(s as AuthMethod));
87-
88-
return methods.length > 0 ? methods : undefined;
89-
}
90-
9173
protected override loadConfiguration(): ResolvedB2CConfig {
9274
return loadConfig(
9375
extractOAuthFlags(this.flags as Record<string, unknown>),

0 commit comments

Comments
 (0)