Skip to content

English__Theory__Data Source Tracing

Ramirez Vargas, José Pablo edited this page Feb 5, 2023 · 2 revisions

Data Source Tracing

With all the great and flexible ways to add data sources to your configuration object, there will probably be times where you might encounter problems with the values in the final configuration object, and you may be wondering why some value got there in the end.

To help easily resolve problems with configuration, wj-config can create a trace of all values that end up in the final configuration object. It adds two properties to the final configuration object: _trace and _qualifiedDs.

The _trace property is an object that will mimic the hierarchy of the final configuration object. For every leaf property in the final configuration object there will be a property in the _trace's hierarchy whose value will tell you the data source that added the value last in the form of an index property and a name property.

The index property just represents the numerical position of the data source in the collection of all data sources in the builder configuration, and matches the order in which the data sources were added in code. The name property, on the other hand is whatever name the data source was assigned to using the configuration builder's name() function. If no name was given, the data source itself will have provided a name, but note that some data sources and incapable of creating unique names. If you are performing tracing, it is best to assign a name to every data source.

The _qualifiedDs property is an array that contains the names and indices of all data sources that qualified to participate in the final configuration object. This directly tells you which data sources passed the when() predicate. The individual elements look the same as the values for traces: Objects that have index and name.

How to Enable Tracing

This is super simple: Just pass true to the builder's build() function:

import wjConfig, { Environment } from "wj-config";
...

const config = wjConfig()
    ...
    .build(true); // <--- Here!

export default await config;

Now the exported configuration object will contain the _trace and _qualifiedDs properties.

How to Name Data Sources

There are a few ways to get a data source named. Let's enumerate them all.

The name() Function

The configuration builder provides the name() function. It can be used immediately after adding a data source or immediately after conditioning a data source.

import wjConfig, { Environment } from "wj-config";
import mainConfig from "./config.json";
...

const config = wjConfig()
    .addObject(mainConfig)
    .name('Main') // <--- Setting the name for ^^^ (previous line)
    .build(true);

export default await config;

Naming with forEnvironment()

The builder's forEnvironment() function automatically names data sources as <Environment> (environment-specific), or <Environment> <count> (environment-specific) if more than one data source is added for a given environment, where <count> is a number that specifies how many data sources have been added for the specific environment.

If this naming convention displeases you, feel free to generate a new name for the data source using the function's second parameter:

import wjConfig, { Environment } from "wj-config";
import mainConfig from "./config.json";
...

const config = wjConfig()
    .addObject(mainConfig)
    .name('Main')
    .addFetched('/config.Dev.json')
    .forEnvironment('Dev', 'Fetched Dev') // <-- Here, using second parameter.
    .build(true);

export default await config;

Naming with addPerEnvironment()

The addPerEnvironment() function automatically delegates the naming of the data source to its internal call of the forEnvironment() function. If you would like a different name for a data source, return that name from the function provided to addPerEnvironment():

import wjConfig, { Environment } from "wj-config";
import mainConfig from "./config.json";
...
const env = ...
const config = wjConfig()
    .addObject(mainConfig)
    .includeEnvironment(env)
    .addPerEnvironment((b, e) => {
        b.addFetched(`/config.${e}.json`);
        return `Fetched ${e}`; // <--- Return the name.
    })
    .build(true);

export default await config;

Naming with when(), whenAllTraits() or whenAnyTrait()

All these functions provide a second parameter to set the last-added data source's name. They simply add the call to name() for you, so they are mere shorthands of .when().name(), .whenAllTraits().name() and .whenAnyTrait().name().