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
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@

- this is a monorepo project; packages:
- ./packages/b2c-cli - the command line interface built with oclif
- ./packages/b2c-tooling - the SDK/library for B2C Commerce operations; support the CLI and can be used standalone

## Setup/Packaging

- use `pnpm` over `npm` for package management
- the `pnpm run test` commands also run the linter after tests
- use `pnpm run -r format` (or individually in packages) to format code with prettier
- use `exports` field in package.json files to define public API surface for packages; use `development` field for nodejs --conditions for development ergonomics (packages/b2c-cli/bin/dev.js will use this condition)

## Documentation

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

- Separate CLI and SDK
- Logging
- redaction
- Localization Support
- supply chain security

## CLI

Expand Down
4 changes: 4 additions & 0 deletions docs/cli/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ These flags are available on all commands that interact with B2C instances:
- [Sandbox Commands](./sandbox) - Create and manage sandboxes
- [MRT Commands](./mrt) - Manage Managed Runtime environments

## Configuration

- [Logging](./logging) - Log levels, output formats, and environment variables

## Getting Help

Get help for any command:
Expand Down
123 changes: 123 additions & 0 deletions docs/cli/logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Logging

The CLI uses [pino](https://github.com/pinojs/pino) for structured logging with pretty-printed output by default.

## Output Modes

### Pretty Print (Default)

Human-readable output with colors, suitable for interactive terminal use:

```
[18:31:58] INFO: Deploying cartridges...
[18:31:59] INFO: Upload complete
```

### JSON Lines (`--json`)

Machine-readable output for scripting, CI/CD pipelines, and log aggregation:

```bash
b2c code deploy --json
```

```json
{"level":"info","time":1764113529411,"command":"code deploy","msg":"Deploying cartridges..."}
{"level":"info","time":1764113529412,"command":"code deploy","msg":"Upload complete"}
```

## Log Levels

Control verbosity with `--log-level` or `-D` for debug:

| Level | Description |
|-------|-------------|
| `trace` | Maximum verbosity |
| `debug` | Detailed operational info |
| `info` | Normal messages (default) |
| `warn` | Warnings |
| `error` | Errors only |
| `silent` | No output |

```bash
b2c code deploy --log-level debug
b2c code deploy -D # shorthand for --log-level debug
```

In debug/trace mode, context objects are displayed:

```
[18:31:58] INFO: Upload complete
command: "code deploy"
file: "cartridge.zip"
bytes: 45678
duration: 1234
```

## Flags

| Flag | Environment Variable | Description |
|------|---------------------|-------------|
| `--log-level` | `SFCC_LOG_LEVEL` | Set log verbosity |
| `-D, --debug` | `SFCC_DEBUG` | Enable debug logging |
| `--json` | | Output JSON lines |

## Environment Variables

| Variable | Description |
|----------|-------------|
| `SFCC_LOG_LEVEL` | Log level (trace, debug, info, warn, error, silent) |
| `SFCC_DEBUG` | Enable debug logging |
| `SFCC_LOG_TO_STDOUT` | Send logs to stdout instead of stderr |
| `SFCC_LOG_COLORIZE` | Force colors on/off |
| `SFCC_REDACT_SECRETS` | Set to `false` to disable secret redaction |
| `NO_COLOR` | Industry standard to disable colors |

## Output Streams

By default, logs go to **stderr** so that command output (data, IDs, etc.) can be piped cleanly:

```bash
# Logs go to stderr, JSON output goes to stdout
b2c sites list --json 2>/dev/null | jq '.sites[0].id'
```

To send logs to stdout instead:

```bash
SFCC_LOG_TO_STDOUT=1 b2c code deploy
```

## Secret Redaction

Sensitive fields are automatically redacted from log output:

- `password`, `secret`, `token`
- `client_secret`, `access_token`, `refresh_token`
- `api_key`, `authorization`

```
[18:31:58] INFO: Authenticating
client_id: "my-client"
client_secret: "[REDACTED]"
```

To disable redaction (for debugging):

```bash
SFCC_REDACT_SECRETS=false b2c code deploy --debug
```

## CI/CD Usage

For CI/CD pipelines, use JSON output and disable colors:

```bash
NO_COLOR=1 b2c code deploy --json 2>&1 | tee deploy.log
```

Or explicitly set the log level:

```bash
SFCC_LOG_LEVEL=info b2c code deploy --json
```
2 changes: 1 addition & 1 deletion packages/b2c-cli/bin/dev.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env -S node --import tsx
#!/usr/bin/env -S node --conditions development --import tsx

import {execute} from '@oclif/core';

Expand Down
45 changes: 45 additions & 0 deletions packages/b2c-cli/src/commands/_test/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {BaseCommand} from '@salesforce/b2c-tooling/cli';

export default class Test extends BaseCommand<typeof Test> {
static description = 'Test logging output';
static hidden = true;

async run(): Promise<void> {
// Test this.log() which now uses pino
this.log('Using this.log() - goes through pino');
this.warn('Using this.warn() - goes through pino');

// Test logger directly at different levels
this.logger.trace('Trace level message');
this.logger.debug('Debug level message');
this.logger.info('Info level message');
this.logger.error('Error level message');

// Context (visible in debug mode)
this.logger.info({operation: 'test', duration: 123}, 'Message with context');

this.logger.debug(
{
file: 'cartridge.zip',
bytes: 45_678,
instance: 'dev01.sandbox.us01.dx.commercecloud.salesforce.com',
},
'Debug with multiple context fields',
);

// Test redaction
this.logger.info(
{
username: 'testuser',
password: 'secret123',
client_secret: 'abc123xyz', // eslint-disable-line camelcase
accessToken: 'eyJhbGciOiJIUzI1NiJ9.test',
},
'This should have redacted fields',
);

// Child logger
const childLogger = this.logger.child({operation: 'upload'});
childLogger.info('Message from child logger');
}
}
25 changes: 0 additions & 25 deletions packages/b2c-cli/src/commands/hello/index.ts

This file was deleted.

16 changes: 0 additions & 16 deletions packages/b2c-cli/src/commands/hello/world.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/b2c-cli/src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* this.log(t('commands.sites.list.fetching', 'Fetching sites from {{hostname}}...', { hostname }))
*/

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

/** The namespace used by b2c-cli messages */
Expand Down
3 changes: 1 addition & 2 deletions packages/b2c-cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@ export {
// Config utilities
loadConfig,
findDwJson,
ResolvedConfig,
LoadConfigOptions,
} from '@salesforce/b2c-tooling/cli';
export type {ResolvedConfig, LoadConfigOptions} from '@salesforce/b2c-tooling/cli';
9 changes: 9 additions & 0 deletions packages/b2c-cli/test/commands/_test/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {runCommand} from '@oclif/test';
import {expect} from 'chai';

describe('_test', () => {
it('runs the smoke test command without errors', async () => {
const {error} = await runCommand('_test');
expect(error).to.be.undefined;
});
});
9 changes: 0 additions & 9 deletions packages/b2c-cli/test/commands/hello/index.test.ts

This file was deleted.

3 changes: 2 additions & 1 deletion packages/b2c-cli/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"rootDir": "src",
"skipLibCheck": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"verbatimModuleSyntax": true
},
"include": ["./src/**/*"]
}
Loading