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 = { isRoot?: boolean, name?: string, settings?: { dynamicConfig: DynamicConfigModes, }, schema: Record<string, ConfigItemDefinitionOrShorthand>, // rest of props only available when isRoot !== true parent?: string, tags?: string[], pick?: Array<PickConfigItemDefinition | string>,
};
Name | Type | Required | Description |
---|---|---|---|
isRoot | boolean | No | MUST be set to true for root service only. |
name | string | No | The name of the workspace. |
parent | string | No | The name of the parent service. |
tags | string[] | No | An array of tags for the service. |
settings | { dynamicConfig: DynamicConfigModes } | No | Settings to apply to the service and as defaults for any children |
pick | Array<PickConfigItemDefinition | string> | No | An array of items to pick from the parent or other service(s). This can be a string (the key) or a PickItemDefinition object. |
schema | Record<string, ConfigItemDefinitionOrShorthand> | Yes | The schema for the workspace. These are the configuration items that will be available to all services. |
Note that when isRoot
is true, some of the options are not available:
parent
is the name of the parent service.tags
is an array of tags for the service.pick
is an array of items to pick from the parent or other services. This can be a string (the key) or aPickConfigItemDefinition
object.
PickItemDefinition
The PickItemDefinition
type is an object with the following properties:
type PickConfigItemDefinition = { /** which service to pick from, defaults to "root" */ source?: string; /** key(s) to pick, or function that matches against all keys from source */ key: string | Array<string> | ((key: string) => boolean), /** new key name or function to rename key(s) */ renameKey?: string | ((key: string) => string), /** function to transform value(s) */ transformValue?: (value: any) => any,};
Example:
import { defineDmnoService, DmnoBaseTypes } from 'dmno';
export default defineDmnoService({ name: 'MyConfig', parent: 'root', pick: [ { key: 'ITEM0', }, { key: 'ITEM1', renameKey: 'NEW_ITEM1', }, { key: 'ITEM2', transformValue: (value) => `${value} transformed`, }, ], schema: { MYFIELD: DmnoBaseTypes.string({ required: true, }), MYFIELD2: DmnoBaseTypes.number({ required: true, }), MYFIELD3: DmnoBaseTypes.boolean({ required: true, }), },});
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, exportEnvKey?: string, expose?: boolean, extends?: DmnoDataType | string | () => DmnoDataType, externalDocs?: { description?, url } | Array<{ description?, url }>, importEnvKey?: string, required?: boolean, sensitive?: boolean, summary?: string, typeDescription?: string, ui?: { color, icon }, useAt?: 'build' | 'boot' | 'run' | 'deploy' , validate?: function(), value?: InlineValueResolverDef }
Name | Type | Required | Description |
---|---|---|---|
asyncValidate | function | No | An async function to validate the value. |
coerce | function | No | A function to coerce the value. |
description | string | No | A description of the item. |
dynamic | boolean | No | Whether the item is dynamic. |
exampleValue | any | No | An example value for the item. |
exportEnvKey | string | No | The key to use when exporting the item to an env var. |
expose | boolean | No | Whether the item should be exposed to other services. i.e., is it "pickable" by siblings |
extends | DmnoDataType | string | () => DmnoDataType | No | A string (the name of the type), an initialized dmno data type, or a function that returns a DmnoDataType |
externalDocs | { description?, url } | Array<{ description?, url }> | No | External documentation for the item. |
importEnvKey | string | No | The key to use when importing the item from the environment. |
required | boolean | No | Whether the item is required. |
sensitive | boolean | No | Whether the item is sensitive. |
summary | string | No | A short summary description of the item. |
typeDescription | string | No | A description of the type. |
ui | { color, icon } | No | UI settings for the item. COMING SOON |
useAt | ConfigRequiredAtTypes | No | When the item is required. |
validate | function | No | A function to validate the value. |
value | InlineValueResolverDef | No | A static value, a function that returns a static value, or a "resolver" like a plugin helper function that fetches a value. |
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, { opts })
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 opts = { _default?: any; [key: string]: any;};
Note: _default
is a reserved key that will be used if the current key is not defined in the object. All the other keys should match the possible values of the SWITCH_BY_KEY
config item.
Example:
import { switchBy } from 'dmno';
export default defineDmnoService({ schema: { SWITCH_BY_KEY: { value: 'val1', }, // MY_CONFIG_ITEM will be 'first value' MY_CONFIG_ITEM: { value: switchBy('SWITCH_BY_KEY', { _default: 'default value', val1: 'first value', val2: 'second value', val3: 'third value', }), }, },});
switchByNodeEnv
switchByNodeEnv({ opts })
This method is used to define different configurations for different environments. It takes an object as an argument with the following properties:
type SwitchByNodeEnvOpts = { _default?: any; development?: any; staging?: any; production?: any; [key: string]: any;};
Note: _default
is a reserved key that will be used if the current environment is not defined in the object. All the other keys should match the possible values of the NODE_ENV
environment variable.
Example:
import { switchByNodeEnv } from 'dmno';
export default defineDmnoService({ schema: { MY_CONFIG_ITEM: { value: switchByNodeEnv({ _default: 'default value', development: 'development value', staging: 'staging value', production: 'production value', }), }, },});