Skip to content

Commit 64aa557

Browse files
committed
better logging in config sources for debugging
1 parent d9b8ddf commit 64aa557

6 files changed

Lines changed: 68 additions & 9 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ export function loadConfig(
117117
sourcesAfter: pluginSources.after,
118118
});
119119

120+
// Log source summary
121+
for (const source of resolved.sources) {
122+
logger.trace(
123+
{source: source.name, path: source.path, fields: source.fieldsContributed},
124+
`[${source.name}] Contributed fields`,
125+
);
126+
}
127+
120128
// Log warnings
121129
for (const warning of resolved.warnings) {
122130
logger.trace({warning}, `[Config] ${warning.message}`);

packages/b2c-tooling-sdk/src/config/dw-json.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import * as fs from 'node:fs';
1515
import * as path from 'node:path';
1616
import type {AuthMethod} from '../auth/types.js';
17+
import {getLogger} from '../logging/logger.js';
1718

1819
/**
1920
* Configuration structure matching dw.json file format.
@@ -114,35 +115,58 @@ export function findDwJson(startDir: string = process.cwd()): string | undefined
114115
* 3. Root-level config
115116
*/
116117
function selectConfig(json: DwJsonMultiConfig, instanceName?: string): DwJsonConfig {
118+
const logger = getLogger();
119+
117120
// Single config or no configs array
118121
if (!Array.isArray(json.configs) || json.configs.length === 0) {
122+
logger.trace(
123+
{selection: 'root', instanceName: json.name},
124+
`[DwJsonSource] Selected config "${json.name ?? 'root'}" (single config)`,
125+
);
119126
return json;
120127
}
121128

122129
// Find by instance name
123130
if (instanceName) {
124131
// Check root first
125132
if (json.name === instanceName) {
133+
logger.trace(
134+
{selection: 'named', instanceName},
135+
`[DwJsonSource] Selected config "${instanceName}" by name (root)`,
136+
);
126137
return json;
127138
}
128139
// Then check configs array
129140
const found = json.configs.find((c) => c.name === instanceName);
130141
if (found) {
142+
logger.trace({selection: 'named', instanceName}, `[DwJsonSource] Selected config "${instanceName}" by name`);
131143
return found;
132144
}
133145
// Instance not found, fall through to other selection methods
146+
logger.trace(
147+
{requestedInstance: instanceName},
148+
`[DwJsonSource] Named instance "${instanceName}" not found, falling back`,
149+
);
134150
}
135151

136152
// Find active config
137153
if (json.active === false) {
138154
// Root is inactive, look for active in configs
139155
const activeConfig = json.configs.find((c) => c.active === true);
140156
if (activeConfig) {
157+
logger.trace(
158+
{selection: 'active', instanceName: activeConfig.name},
159+
`[DwJsonSource] Selected config "${activeConfig.name}" by active flag`,
160+
);
141161
return activeConfig;
142162
}
143163
}
144164

145165
// Default to root config
166+
logger.trace(
167+
{selection: 'root', instanceName: json.name},
168+
`[DwJsonSource] Selected config "${json.name ?? 'root'}" (default to root)`,
169+
);
146170
return json;
147171
}
148172

@@ -171,19 +195,26 @@ function selectConfig(json: DwJsonMultiConfig, instanceName?: string): DwJsonCon
171195
* const config = loadDwJson({ path: './config/dw.json' });
172196
*/
173197
export function loadDwJson(options: LoadDwJsonOptions = {}): DwJsonConfig | undefined {
198+
const logger = getLogger();
199+
174200
// If explicit path provided, use it. Otherwise default to ./dw.json (no upward search)
175201
const dwJsonPath = options.path ?? path.join(options.startDir || process.cwd(), 'dw.json');
176202

203+
logger.trace({path: dwJsonPath}, '[DwJsonSource] Checking for config file');
204+
177205
if (!fs.existsSync(dwJsonPath)) {
206+
logger.trace({path: dwJsonPath}, '[DwJsonSource] No config file found');
178207
return undefined;
179208
}
180209

181210
try {
182211
const content = fs.readFileSync(dwJsonPath, 'utf8');
183212
const json = JSON.parse(content) as DwJsonMultiConfig;
184213
return selectConfig(json, options.instance);
185-
} catch {
214+
} catch (error) {
186215
// Invalid JSON or read error
216+
const message = error instanceof Error ? error.message : String(error);
217+
logger.trace({path: dwJsonPath, error: message}, '[DwJsonSource] Failed to parse config file');
187218
return undefined;
188219
}
189220
}

packages/b2c-tooling-sdk/src/config/sources/dw-json-source.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,23 @@
1010
*/
1111
import * as path from 'node:path';
1212
import {loadDwJson} from '../dw-json.js';
13+
import {getPopulatedFields} from '../mapping.js';
1314
import {mapDwJsonToNormalizedConfig} from '../mapping.js';
1415
import type {ConfigSource, NormalizedConfig, ResolveConfigOptions} from '../types.js';
16+
import {getLogger} from '../../logging/logger.js';
1517

1618
/**
1719
* Configuration source that loads from dw.json files.
1820
*
1921
* @internal
2022
*/
2123
export class DwJsonSource implements ConfigSource {
22-
readonly name = 'dw.json';
24+
readonly name = 'DwJsonSource';
2325
private lastPath?: string;
2426

2527
load(options: ResolveConfigOptions): NormalizedConfig | undefined {
28+
const logger = getLogger();
29+
2630
const dwConfig = loadDwJson({
2731
instance: options.instance,
2832
path: options.configPath,
@@ -37,7 +41,12 @@ export class DwJsonSource implements ConfigSource {
3741
// Track the path for diagnostics - use explicit path or default location
3842
this.lastPath = options.configPath ?? path.join(options.startDir || process.cwd(), 'dw.json');
3943

40-
return mapDwJsonToNormalizedConfig(dwConfig);
44+
const normalized = mapDwJsonToNormalizedConfig(dwConfig);
45+
const fields = getPopulatedFields(normalized);
46+
47+
logger.trace({path: this.lastPath, fields}, '[DwJsonSource] Loaded config');
48+
49+
return normalized;
4150
}
4251

4352
getPath(): string | undefined {

packages/b2c-tooling-sdk/src/config/sources/mobify-source.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import * as fs from 'node:fs';
1212
import * as os from 'node:os';
1313
import * as path from 'node:path';
1414
import type {ConfigSource, NormalizedConfig, ResolveConfigOptions} from '../types.js';
15+
import {getLogger} from '../../logging/logger.js';
1516

1617
/**
1718
* Mobify config file structure (~/.mobify)
@@ -37,15 +38,20 @@ interface MobifyConfigFile {
3738
* @internal
3839
*/
3940
export class MobifySource implements ConfigSource {
40-
readonly name = 'mobify';
41+
readonly name = 'MobifySource';
4142
private lastPath?: string;
4243

4344
load(options: ResolveConfigOptions): NormalizedConfig | undefined {
45+
const logger = getLogger();
46+
4447
// Use explicit credentialsFile if provided, otherwise use default path
4548
const mobifyPath = options.credentialsFile ?? this.getMobifyPath(options.cloudOrigin);
4649
this.lastPath = mobifyPath;
4750

51+
logger.trace({path: mobifyPath}, '[MobifySource] Checking for credentials file');
52+
4853
if (!fs.existsSync(mobifyPath)) {
54+
logger.trace({path: mobifyPath}, '[MobifySource] No credentials file found');
4955
return undefined;
5056
}
5157

@@ -54,14 +60,19 @@ export class MobifySource implements ConfigSource {
5460
const config = JSON.parse(content) as MobifyConfigFile;
5561

5662
if (!config.api_key) {
63+
logger.trace({path: mobifyPath}, '[MobifySource] Credentials file found but no api_key present');
5764
return undefined;
5865
}
5966

67+
logger.trace({path: mobifyPath, fields: ['mrtApiKey']}, '[MobifySource] Loaded credentials');
68+
6069
return {
6170
mrtApiKey: config.api_key,
6271
};
63-
} catch {
72+
} catch (error) {
6473
// Invalid JSON or read error
74+
const message = error instanceof Error ? error.message : String(error);
75+
logger.trace({path: mobifyPath, error: message}, '[MobifySource] Failed to parse credentials file');
6576
return undefined;
6677
}
6778
}

packages/b2c-tooling-sdk/src/config/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export interface NormalizedConfig {
6464
mrtOrigin?: string;
6565

6666
// Metadata
67-
/** Instance name (from multi-config dw.json) */
67+
/** Instance name (from multi-config supporting sources) */
6868
instanceName?: string;
6969
}
7070

@@ -113,7 +113,7 @@ export interface ConfigResolutionResult {
113113
* Options for configuration resolution.
114114
*/
115115
export interface ResolveConfigOptions {
116-
/** Named instance from dw.json "configs" array */
116+
/** Named instance for supporting ConfigSources */
117117
instance?: string;
118118
/** Explicit path to config file (defaults to auto-discover) */
119119
configPath?: string;

packages/b2c-tooling-sdk/test/config/sources.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ describe('config/sources', () => {
126126
resolver.resolve();
127127
const {sources} = resolver.resolve();
128128

129-
const dwJsonSource = sources.find((s) => s.name === 'dw.json');
129+
const dwJsonSource = sources.find((s) => s.name === 'DwJsonSource');
130130
// Normalize paths to handle macOS symlinks (/var -> /private/var)
131131
const expectedPath = fs.realpathSync(dwJsonPath);
132132
const actualPath = dwJsonSource?.path ? fs.realpathSync(dwJsonSource.path) : undefined;
@@ -346,7 +346,7 @@ describe('config/sources', () => {
346346
resolver.resolve();
347347
const {sources} = resolver.resolve();
348348

349-
const mobifySource = sources.find((s) => s.name === 'mobify');
349+
const mobifySource = sources.find((s) => s.name === 'MobifySource');
350350
// Normalize paths to handle macOS symlinks
351351
const expectedPath = fs.realpathSync(mobifyPath);
352352
const actualPath = mobifySource?.path ? fs.realpathSync(mobifySource.path) : undefined;

0 commit comments

Comments
 (0)