Skip to content
DMNO
✨ If you've tried DMNO or looked through the docs, let us know what you think!

Helper methods

defineDmnoService

defineDmnoService({ opts })

See the service config in the schema guide for more information.

This method is used to define the configuration schema in each of your services, including the root. It takes an object as an argument with the following properties:

type DmnoServiceConfig = {
name?: string,
parent?: string,
tags?: string[],
settings?: {
dynamicConfig: DynamicConfigModes,
},
schema: Record<string, ConfigItemDefinitionOrShorthand>,
};

DynamicConfigModes

The DynamicConfigModes type has the following values:

type DynamicConfigModes =
/* non-sensitive = static, sensitive = dynamic (this is the default) */
'public_static' |
/* everything static, dynamic not supported */
'only_static' |
/* everything dynamic, static not supported */
'only_dynamic' |
/* default is static */
'default_static' |
/* default_dynamic */
'default_dynamic';

ConfigItemDefinition

The ConfigItemDefinition type is an object with the following properties:

type ConfigItemDefinition = {
asyncValidate?: function(),
coerce?: function(),
description?: string,
dynamic?: boolean,
exampleValue?: any,
extends?: DmnoDataType | string | () => DmnoDataType,
externalDocs?: { description?, url } | Array<{ description?, url }>,
required?: boolean,
sensitive?: boolean,
summary?: string,
typeDescription?: string,
ui?: { color, icon },
useAt?: 'build' | 'boot' | 'run' | 'deploy' ,
validate?: function(),
value?: InlineValueResolverDef
}

Examples illustrating implicit and explicit type extensions:

import { defineDmnoService, DmnoBaseTypes } from 'dmno';
export default defineDmnoService({
schema: {
ITEM0: {}, // defaults to string
ITEM1: 'string',
ITEM2: DmnoBaseTypes.string,
ITEM3: DmnoBaseTypes.string(),
ITEM4: {
extends: 'string',
},
ITEM5: {
extends: DmnoBaseTypes.string,
},
ITEM6: {
extends: DmnoBaseTypes.string({}),
},
},
});

createDmnoDataType

createDmnoDataType({ opts })

This method is used to create a new data type. It takes an object as an argument with the following properties:

type DataTypeOpts = {
name: string;
extends: string | DmnoDataType | (() => DmnoDataType);
settingsSchema?: Record<string, unknown>;
validate?: (ctx, settings) => boolean;
coerce?: (ctx, settings) => unknown;
};

Example:

const myType = createDmnoDataType({
name: 'MyType',
extends: DmnoBaseTypes.string({
// string specific settings object
}),
settingsSchema: {
// user type specific settings object
},
validate: (value) => {
// return true if value is valid
// has access to settingsSchema
},
coerce: (value) => {
// return coerced value
// has access to settingsSchema
},
});

You can then use it in your config schema like so:

const myType = DmnoBaseTypes.MyType({ settings });
export default defineDmnoService({
name: 'MyConfig',
parent: 'root',
schema: {
MYFIELD: {
extends: myType,
required: true,
},
MYFIELD2,
MYFIELD3,
},
});

switchBy

switchBy('SWITCH_BY_KEY': string, { branches })

This method is used to define different configurations for different values of a particular config item. Its arguments are a string (i.e., the key name) and an object with the following properties:

type branches = {
_default?: any;
[key: string]: any;
};

Note: _default is a reserved key to represent the default branch. This default will be selected if the current value of the switch is not found on any other branch. All the other keys should match the possible values of the SWITCH_BY_KEY config item.

A real example using an enviroment flag:

import { switchBy } from 'dmno';
export default defineDmnoService({
schema: {
APP_ENV: {
value: 'development',
},
MY_CONFIG_ITEM: {
value: switchBy('APP_ENV', {
_default: 'dev/default value', // <- matches
test: 'test value',
staging: 'staging value',
production: 'prod value',
}),
},
},
});