|
| 1 | +--- |
| 2 | +id: 1jIkH5R6W3pM8IYR2gOji |
| 3 | +title: Cookbook |
| 4 | +desc: '' |
| 5 | +updated: 1637185314831 |
| 6 | +created: 1634737110155 |
| 7 | +--- |
| 8 | + |
| 9 | +## Configuration |
| 10 | + |
| 11 | +### Add New Config |
| 12 | +> Configuration is currently under active migration and the information here will be revised once the configs have been fully migrated. |
| 13 | +> As of this writing, we are on v3, where _commands_ and _workspace_ related configurations are migrated. |
| 14 | +
|
| 15 | +Dendron configuration in `dendron.yml` is defined in the following places: |
| 16 | + - new style configuration defined [here](https://github.com/dendronhq/dendron/blob/master/packages/common-all/src/types/configs/dendronConfig.ts) |
| 17 | + - legacy style configuration defined [here](https://github.com/dendronhq/dendron/blob/master/packages/common-all/src/types/workspace.ts). |
| 18 | + |
| 19 | +During config migration, these two types are used to compose an [IntermediateDendronConfig](https://github.com/dendronhq/dendron/blob/6a7be61db3ec7e6fab61871b30ec215c47f1cb59/packages/common-all/src/types/intermediateConfigs.ts#L28), which has both old and new config keys. |
| 20 | + |
| 21 | +*** |
| 22 | + |
| 23 | +When introducing a new config key, consider these points below: |
| 24 | + |
| 25 | +1. What namespace does this new config belong? Is the namespace migrated yet? |
| 26 | + - If the namespace is already migrated, |
| 27 | + - Add the new config to an appropriate namespace of the new `DendronConfig`. |
| 28 | + - If the namespace is not yet migrated, |
| 29 | + - Add the config to the top level of the old `DendronConfig` |
| 30 | + - These will later be migrated when the namespace is migrated. |
| 31 | + - Follow the config conventions descirbed below as if you are adding to the new namespace to simplify the migration process. |
| 32 | +1. How should I name the config? Should it be optional or required? |
| 33 | + - For the sake of consistency, please consult the [[configuration conventions|dendron.dev.style.config]] note. |
| 34 | +1. When adding a config key to the new namespace type(s), you also have to add a corresponding entry in the [DendronConfigEntryCollection](https://github.com/dendronhq/dendron/blob/6a7be61db3ec7e6fab61871b30ec215c47f1cb59/packages/common-all/src/constants/configs/dendronConfig.ts#L10) |
| 35 | + - 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. |
| 36 | + - If this step is omitted, Typescript will complain that `DendronConfigEntryCollection` is missing a key. |
| 37 | +1. As per the [[configuration conventions|dendron.dev.style.config]], consider adding a sensible default of the newly introduced config key in the appropriate `genDefault{namespace}Config` method. |
| 38 | + - Each namespace is divided into separate modules [here](https://github.com/dendronhq/dendron/tree/master/packages/common-all/src/types/configs), and the namespace type and default generating methods live in the same module. |
| 39 | + - 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. |
| 40 | +1. You will notice that when introducing a new config that is required and has a default value, `Extension.test.ts` will fail. Some test in `engine-test-utils` may fail as well since the snapshot should be updated. |
| 41 | + - Update the failing test in `Extension.test.ts` |
| 42 | + - Update the snapshot by running `yarn run test:updateSnapshot` |
| 43 | +1. Any time the config is changed, our the JSON schema that is validationg `dendron.yml` should be updated. |
| 44 | + - Run `yarn gen:data` at the root of the monorepo |
| 45 | + |
| 46 | +### Accessing config values from `dendron.yml` |
| 47 | + |
| 48 | +`ConfigUtils` is a collection of helpers that let you get or set config values from `dendron.yml`. |
| 49 | +Prefer using the getters and setters defined here over directly accessing from the config object. |
| 50 | + |
| 51 | +e.g.) |
| 52 | + |
| 53 | +```js |
| 54 | + const config = engine.config; |
| 55 | + // bad |
| 56 | + const noteLookupConfig = config.commands.lookup.note; |
| 57 | + // good |
| 58 | + const noteLookupConfig = ConfigUtils.getLookup(config).note; |
| 59 | + |
| 60 | + ... |
| 61 | + // bad |
| 62 | + config.commands.lookup.note = someProcessedNoteConfig; |
| 63 | + // good |
| 64 | + ConfigUtils.setNoteLookupProps(config, "confirmVaultOnCreate", true); |
| 65 | +``` |
| 66 | + |
| 67 | +The advantage over directly accessing |
| 68 | + - 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. |
| 69 | + ```js |
| 70 | + static getProp<K extends keyof StrictConfigV3>( |
| 71 | + config: IntermediateDendronConfig, |
| 72 | + key: K |
| 73 | + ): StrictConfigV3[K] { |
| 74 | + const defaultConfig = ConfigUtils.genDefaultConfig(); |
| 75 | + const configWithDefaults = _.defaultsDeep(config, defaultConfig); |
| 76 | + return configWithDefaults[key]; |
| 77 | + } |
| 78 | + ``` |
| 79 | + - It will also narrow down the types for you. |
| 80 | + - This is especially important during active config migration because we can avoid unnecessary type assertions. |
| 81 | + |
| 82 | +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. |
| 83 | + |
| 84 | +## NoteProps |
| 85 | + |
| 86 | +- try having plain objects on the note props |
| 87 | + |
| 88 | +### Adding a new frontmatter property |
| 89 | + |
| 90 | +In VSCode, you can use the "Goto symbol in workspace" command and type the function name or class name to find the following locations. |
| 91 | + |
| 92 | +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! |
| 93 | +2. In `DNodeUtils.create` add prop name to `optionalProps`. |
| 94 | +3. In `NoteUtils.serializeMeta` add prop name to `builtinProps`. |
| 95 | +4. In `DNodeUtils.getCustomProps` add prop name to `blacklist`. |
| 96 | +5. In `SchemaUtils.TEMPLATE_COPY_PROPS` add prop name if the prop should be copied over when a template note is used. |
| 97 | +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. |
0 commit comments