Cookbook

Configuration

Add New Config

Summary

This goes over adding a new dendron.yml configuration

Details

Dendron configuration is defined in ../packages/common-all/src/types/configs/dendronConfig.ts (Private)

Steps

  1. Decide on a scope
  1. Decide on a name

  2. Add config description

  • When adding a config key to the new namespace type(s), you also have to add a corresponding entry in the ../packages/common-all/src/constants/configs/dendronConfig.ts (Private)
    • This is an object that holds every possible config key's label and description that will later be used to automatically generate a configuration view.
    • If this step is omitted, Typescript will complain that DendronConfigEntryCollection is missing a key.
  1. Decide on the default
  • As per the configuration conventions, consider adding a sensible default of the newly introduced config key in the appropriate genDefault{namespace}Config method.
    • Each namespace is divided into separate modules here, and the namespace type and default generating methods live in the same module.
    • These default generating methods will be used by the ConfigUtils that are used to get and set configs later, so it is important to define a default here to simplify the process down the line.
  1. Update tests and json schema

    Update Json

    1. Update the json schema Run yarn gen:data at the root of the monorepo
    2. Update snapshots

      Start anchor updating-test-snapshots not found

      ../packages/plugin-core/src/test/suite-integ/SetupWorkspace.test.ts (Private)

  2. Update UI preview for config : This process is currently manual

  • Update the new config in : ..\packages\dendron-plugin-views\src\utils\dendronConfig.ts (Private).
    • the key is the entire nested path of the newly added config. for example: dev.enableSelfContainedVaults
    • add the type and group of the config. For selecting type:
    • if the config has enum, update the type to beselect. eg: workspace.journal.addBehavior
    • if the config value is in key:value pair, update the type to list. eg: workspace.task.prioritySymbols
    • for complicated values of config, update the type to be : object, this will add a edit in dendron.yml link in UI. eg: workspace.vaults

Deprecating Existing Config

Steps

  1. Scrub through the entire codebase that references the config key, and modify the logic accordingly.
  2. Add the deprecated path in ../packages/engine-server/src/migrations/utils.ts (Private)
  3. Once the deprecated path is added, ConfigUtils.detectDeprecatedConfigs will catch it in the subsequent release (if extensionInstallStatus === InstallStatus.UPGRADED). The user will be prompted to trigger a doctor command. This means we don't have to explicitly write migration code that scrubs the deprecated config key from dendron.yml.
  4. Update tests and json schema

    Update Json

    1. Update the json schema Run yarn gen:data at the root of the monorepo
    2. Update snapshots

      Start anchor updating-test-snapshots not found

      ../packages/plugin-core/src/test/suite-integ/SetupWorkspace.test.ts (Private)

    Set a new default for new users but don't change behavior existing users

    Do this when setting a new default for new users.

    1. Update genLatestConfig and set a sensible default there. New users will get this
    2. Old users will get whatever value was set in Add New Config

Accessing config values from dendron.yml

ConfigUtils is a collection of helpers that let you get or set config values from dendron.yml. Prefer using the getters and setters defined here over directly accessing from the config object.

e.g.)

  const config = engine.config;
  // bad
  const noteLookupConfig = config.commands.lookup.note;
  // good
  const noteLookupConfig = ConfigUtils.getLookup(config).note;

  ...
  // bad
  config.commands.lookup.note = someProcessedNoteConfig;
  // good
  ConfigUtils.setNoteLookupProps(config, "confirmVaultOnCreate", true);

The advantage over directly accessing

  • All helpers defined in ConfigUtils recursively account for missing values and replace them with the default values defined for the key you are accessing / modifying.
static getProp<K extends keyof StrictConfigV3>(
  config: IntermediateDendronConfig,
  key: K
): StrictConfigV3[K] {
  const defaultConfig = ConfigUtils.genDefaultConfig();
  const configWithDefaults = _.defaultsDeep(config, defaultConfig);
  return configWithDefaults[key];
}
  • It will also narrow down the types for you.
    • This is especially important during active config migration because we can avoid unnecessary type assertions.

Some commonly used getters and setters are defined in ConfigUtils. Use the best of your knowledge to use existing helpers or define a new one in a similar fashion if it doesn't exist.

Updating Default for Existing Config Values

When updating the defaults, we need to

  1. Modify genDefaultConfig (Private) and update the default value
  2. Update tests and json schema

    Start anchor modifying-config not found

NoteProps

  • try having plain objects on the note props

Adding a new frontmatter property

In VSCode, you can use the "Goto symbol in workspace" command and type the function name or class name to find the following locations.

  1. In DNodeProps, add the prop to the type. Unless the prop has to be mandatory for all notes, it should be optional (prop?: type). Most props don't have to be mandatory!
  2. In DNodeUtils.create add prop name to optionalProps.
  3. In NoteUtils.serializeMeta add prop name to builtinProps.
  4. In DNodeUtils.getCustomProps add prop name to blacklist.
  5. In SchemaUtils.TEMPLATE_COPY_PROPS add prop name if the prop should be copied over when a template note is used.
  6. If and only if it's a prop that's required (mandatory) for all notes, in foundation.ts add prop name to REQUIRED_DNODEPROPS. Again, most props don't have to be mandatory.

Children
  1. Add New Config
  2. Modify Dendron Config
  3. Remove Existing Config
  4. Vault Path

Backlinks