Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 98 additions & 29 deletions docs/api-readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,27 @@ npm install @salesforce/b2c-tooling-sdk

## Quick Start

### From Environment Configuration (Recommended)
### From Configuration (Recommended)

The easiest way to create an instance is from environment configuration files:
Use `resolveConfig()` to load configuration from project files (dw.json) and create a B2C instance:

```typescript
import { B2CInstance } from '@salesforce/b2c-tooling-sdk';
import { resolveConfig } from '@salesforce/b2c-tooling-sdk/config';

// Load configuration from environment files (dw.json, etc.), override secrets from environment
const instance = B2CInstance.fromEnvironment({
// Load configuration, override secrets from environment
const config = resolveConfig({
clientId: process.env.SFCC_CLIENT_ID,
clientSecret: process.env.SFCC_CLIENT_SECRET,
});

// Validate configuration before use
if (!config.hasB2CInstanceConfig()) {
throw new Error('Missing B2C instance configuration');
}

// Create instance from validated config
const instance = config.createB2CInstance();

// Use typed WebDAV client
await instance.webdav.mkcol('Cartridges/v1');
await instance.webdav.put('Cartridges/v1/app.zip', zipBuffer);
Expand All @@ -31,11 +39,16 @@ await instance.webdav.put('Cartridges/v1/app.zip', zipBuffer);
const { data, error } = await instance.ocapi.GET('/sites', {
params: { query: { select: '(**)' } },
});

// Check for configuration warnings
for (const warning of config.warnings) {
console.warn(warning.message);
}
```

### Direct Construction

You can also construct an instance directly with configuration:
For advanced use cases, you can construct a B2CInstance directly:

```typescript
import { B2CInstance } from '@salesforce/b2c-tooling-sdk';
Expand All @@ -51,6 +64,70 @@ const instance = new B2CInstance(
);
```

## Configuration Resolution

The `resolveConfig()` function provides a robust configuration system with multi-source loading and validation.

### Multi-Source Loading

Configuration is loaded from multiple sources with the following priority (highest to lowest):

1. **Explicit overrides** - Values passed to `resolveConfig()`
2. **dw.json** - Project configuration file (searched upward from cwd)
3. **~/.mobify** - Home directory file for MRT API key

```typescript
import { resolveConfig } from '@salesforce/b2c-tooling-sdk/config';

// Override specific values, rest loaded from dw.json
const config = resolveConfig({
hostname: process.env.SFCC_SERVER, // Override hostname
clientId: process.env.SFCC_CLIENT_ID, // Override from env
clientSecret: process.env.SFCC_CLIENT_SECRET,
});
```

### Validation Helpers

The resolved config provides methods to check what configuration is available:

```typescript
const config = resolveConfig();

// Check for B2C instance configuration
if (config.hasB2CInstanceConfig()) {
const instance = config.createB2CInstance();
}

// Check for MRT configuration
if (config.hasMrtConfig()) {
const mrtClient = config.createMrtClient({ project: 'my-project' });
}

// Other validation methods
config.hasOAuthConfig(); // OAuth credentials available?
config.hasBasicAuthConfig(); // Basic auth credentials available?
```

### Configuration Warnings

The config system detects potential issues and provides warnings:

```typescript
const config = resolveConfig({
hostname: 'staging.demandware.net', // Different from dw.json
});

// Check warnings
for (const warning of config.warnings) {
console.warn(`[${warning.code}] ${warning.message}`);
}
```

### Hostname Protection

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.

## Authentication

B2CInstance supports multiple authentication methods:
Expand All @@ -60,36 +137,28 @@ B2CInstance supports multiple authentication methods:
Used for OCAPI and can be used for WebDAV:

```typescript
const instance = new B2CInstance(
{ hostname: 'sandbox.demandware.net' },
{
oauth: {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
scopes: ['SALESFORCE_COMMERCE_API:...:dwsid'],
}
}
);
const config = resolveConfig({
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
scopes: ['SALESFORCE_COMMERCE_API:...:dwsid'],
});

const instance = config.createB2CInstance();
```

### Basic Auth

Used for WebDAV operations (Business Manager credentials):

```typescript
const instance = new B2CInstance(
{ hostname: 'sandbox.demandware.net' },
{
basic: {
username: 'admin',
password: 'your-access-key'
},
oauth: {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
}
}
);
const config = resolveConfig({
username: 'admin',
password: 'your-access-key',
clientId: 'your-client-id', // Still needed for OCAPI
clientSecret: 'your-client-secret',
});

const instance = config.createB2CInstance();
```

When both are configured, WebDAV uses Basic auth and OCAPI uses OAuth.
Expand Down
16 changes: 10 additions & 6 deletions packages/b2c-tooling-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@ npm install @salesforce/b2c-tooling-sdk

## Quick Start

### From Environment Configuration (Recommended)
### From Configuration (Recommended)

The easiest way to create an instance is from environment configuration files:
Use `resolveConfig()` to load configuration from project files (dw.json) and create a B2C instance:

```typescript
import { B2CInstance } from '@salesforce/b2c-tooling-sdk';
import { resolveConfig } from '@salesforce/b2c-tooling-sdk/config';

// Load configuration from environment files (dw.json, etc.), override secrets from environment
const instance = B2CInstance.fromEnvironment({
// Load configuration, override secrets from environment
const config = resolveConfig({
clientId: process.env.SFCC_CLIENT_ID,
clientSecret: process.env.SFCC_CLIENT_SECRET,
});

// Create instance from validated config
const instance = config.createB2CInstance();

// Use typed WebDAV client
await instance.webdav.mkcol('Cartridges/v1');
await instance.webdav.put('Cartridges/v1/app.zip', zipBuffer);
Expand All @@ -40,7 +43,7 @@ const { data, error } = await instance.ocapi.GET('/sites', {

### Direct Construction

You can also construct an instance directly with configuration:
For advanced use cases, you can construct a B2CInstance directly:

```typescript
import { B2CInstance } from '@salesforce/b2c-tooling-sdk';
Expand Down Expand Up @@ -129,6 +132,7 @@ The SDK provides subpath exports for tree-shaking and organization:
| Export | Description |
|--------|-------------|
| `@salesforce/b2c-tooling-sdk` | Main entry point with all exports |
| `@salesforce/b2c-tooling-sdk/config` | Configuration resolution (resolveConfig) |
| `@salesforce/b2c-tooling-sdk/auth` | Authentication strategies (OAuth, Basic, API Key) |
| `@salesforce/b2c-tooling-sdk/instance` | B2CInstance class |
| `@salesforce/b2c-tooling-sdk/clients` | Low-level API clients (WebDAV, OCAPI, SLAS, ODS, MRT) |
Expand Down
6 changes: 4 additions & 2 deletions packages/b2c-tooling-sdk/src/clients/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
* and provides convenient `webdav` and `ocapi` getters.
*
* ```typescript
* import { B2CInstance } from '@salesforce/b2c-tooling-sdk';
* import { resolveConfig } from '@salesforce/b2c-tooling-sdk/config';
*
* const instance = B2CInstance.fromEnvironment({
* const config = resolveConfig({
* clientId: process.env.SFCC_CLIENT_ID,
* clientSecret: process.env.SFCC_CLIENT_SECRET,
* });
* const instance = config.createB2CInstance();
*
* // WebDAV operations via instance.webdav
* await instance.webdav.put('Cartridges/v1/app.zip', content);
Expand Down
4 changes: 3 additions & 1 deletion packages/b2c-tooling-sdk/src/clients/ocapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ export interface OcapiClientOptions {
*
* @example
* // Via B2CInstance (recommended)
* const instance = B2CInstance.fromEnvironment();
* import { resolveConfig } from '@salesforce/b2c-tooling-sdk/config';
* const config = resolveConfig();
* const instance = config.createB2CInstance();
* const { data, error } = await instance.ocapi.GET('/sites', {});
*
* @example
Expand Down
4 changes: 3 additions & 1 deletion packages/b2c-tooling-sdk/src/clients/webdav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ export interface PropfindEntry {
*
* @example
* // Via B2CInstance (recommended)
* const instance = B2CInstance.fromEnvironment();
* import { resolveConfig } from '@salesforce/b2c-tooling-sdk/config';
* const config = resolveConfig();
* const instance = config.createB2CInstance();
* await instance.webdav.mkcol('Cartridges/v1');
* await instance.webdav.put('Cartridges/v1/app.zip', zipBuffer);
*
Expand Down
2 changes: 1 addition & 1 deletion packages/b2c-tooling-sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export type {

// Context Layer - Instance
export {B2CInstance} from './instance/index.js';
export type {InstanceConfig, FromEnvironmentOptions, B2CInstanceOptions} from './instance/index.js';
export type {InstanceConfig} from './instance/index.js';

// Clients
export {
Expand Down
Loading
Loading