1.6.0 • Published 1 year ago

codata v1.6.0

Weekly downloads
-
License
ISC
Repository
gitlab
Last release
1 year ago

Codata

YAML & OOP (multiple inheritance supported) based data utility with JS hooks. For example: config A extends config B, which extends config C, and every of them can exec associated JS script.

More specifically - Config A deepmerge with its super config B, which deepmerge with super config C. After each config parsed, JS hook can be executed to apply some modifications which much easier to do with JS rather than with any kind of templating language. Basic templating implemented too BTW... Before parse supported data types (Yaml & Json for now), utility search and replace placeholders like ${VAR}

Configs organized in 'modules'. Module addressed by name, and stored in a file with according or shortened name. Module 'project_beta' can be described in a file project_beta.yaml|json or in a file project.yaml|json. It is useful for multi-environment system with a lot of similar configs.

Install & test

$ npm install codata
$ npm run test

Usage

Assume that you have _general.yaml, _general.js, project.yaml & project.js files in ./codata folder (can be changed with codata.pathToModules) with following content:

_general.yaml:

_general:
  __constructor: _general.js
  templatingTest: from _general.yml ${PROJECT}
  someJSValues:
    - general.yaml
  worker:
    replicas: 10

_general.js:

export let _general = function (){         // function with module`s name
	this.someJSValues.push ('General');
}

project.yaml:

project:
  __extends: _general
  __constructor: project.js
  title: Project
  worker:
    replicas: 1

project_beta:
  __extends: project
  __constructor: project.js
  title: Project (BETA)

project.js:

export let project = function () {          // function with module`s name
	this.someJSValues.push ('Project');
}

export let project_beta = function () {     // function with module`s name
	this.someJSValues.push ('Project_beta');
}

In this case, we can get resulting config for modules '_general', 'project' & 'project_beta'. Config for 'project_beta' will contain following (note that __constructor & __extends fields are removed):

{
	templatingTest: 'from _general.yml My Project'                          // from _general
	someJSValues: ['general.yaml', 'General', 'Project', 'Project_beta']    // code execution order
	worker: {replicas: 1}                                                   // from 'project'
	title: 'Project (BETA)'                                                 // from 'project_beta'
}

To achieve that just load data with this code:

import codata from "codata";

codata.templatingData = {PROJECT: 'My project'}; // process.env by default
let data = await codata.load ('project_beta');

Instantiate your own instance:

import {Codata} from "codata";

let cd = new Codata ();
cd.modulesSplitBy = '_'
cd.pathToModules = '/usr/data/';

let data;
let data = await cd.load ('project_beta');

Codata basics

Codata operates with 'modules'. Each module have a unique name. Modules stored in Yaml files. One Yaml file may contain many of modules with according names. Module name in file should be the same as filename, or include filename as a part.

For example:

  • Module sockets must be placed in file sockets.yaml
  • Module sockets_ssl can be placed in one of filessockets_ssl.yamlorsockets.yaml
  • Module sockets_ssl_v2 can be placed in one of files sockets_ssl_v2.yaml or sockets_ssl.yaml or sockets.yaml

Config file format specials

File options

  • local - Define variables witch is accessible only inside this file with ${local.varName} syntax
  • __environment - Define or redefine ENV variables witch is accessible inside this file and all included modules as well with ${env.varName} syntax. . See __environment variables

Module options

  • __extends - Module or array of modules, which should be deepmerge with current module. See __extend formats
  • __environment - Define or redefine ENV variables

Module events

Module event described in following format - filename[#function] if #function omitted, module's name will be used instead. Function called with module object as this

  • __constructor (default: null) - Executed after current module data is parsed and before it will be deepmerge to its descendant. If constructor return any value, except undefined, result will be replaced with that value.
  • __onready (default: null) - Executed only one last function in inheritance chain after whole module data is constructed and ready to return. If descendant have this event, it will replace such event in ancestor, and only one call will occur
  • __script - Deprecated analogue of __constructor

__extend formats

  • String - name or path/name to module. e.g. 'myModule'
  • String@Object.Deep.Target - name of module as above. Module will be inserted not in a root of current object, but into the Object.Deep.Target instead. See 'healthcheck-a' & 'healthcheck-b' in v1.3.0 tests
  • {module: 'String', props: {propName: 'propValue'}} - Include module with passing extra options (props). Options is accessible in the module with ${props.propName} syntax.

__environment variables

Here is a three level of ENV variables is available. All of that kind of variables can be accessed with ${env.varName} syntax.

  • OS - Variables defined in OS.
  • File level - Variables defined in file's __environment section can define new variables or redefine OS variables.
  • Module level - Variables defined in module's __environment section can define new variables or redefine OS variables and variables from file's section.

Please note (v1.5): ENV variables, once defined in loaded module, marked as final, so other definitions in included modules are ignored.

1.6.0

1 year ago

1.5.0

1 year ago

1.4.1

1 year ago

1.4.0

2 years ago

1.3.3

2 years ago

1.3.2

2 years ago

1.3.1

2 years ago

1.3.0

2 years ago

1.2.0

2 years ago

1.1.0

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago