recordari
TypeScript icon, indicating that this package has built-in type declarations

1.2.4 • Public • Published

logo

Master Next
Tests CI - Master CI - Next
Coverage codecov codecov
Dependency Analysis Master - Known Vulnerabilities Next -  Known Vulnerabilities

Recordari is a type and structure validation tool for configuration files.

const { Record, R } = require('Recordari');
 
// 1) Create a Record of how the configurations should look
const RConfig = Record('MyConfig', {
  port: R.Number.Natural,
  env: R.String.Either(['dev', 'prod']),
  loglevel: R.String.Either(['none', 'error', 'warn', 'info', 'debug'])
});
 
// 2) Test the actual configurations against the Record
const config = RConfig(require('config.json')); // Will throw if any of the constraints fail
 
// 3) You can use all of the properties on config without worrying about some of them not being valid.
config.loglevel // Will ALWAYS be valid
config.port     // Will ALWAYS be valid
config.env      // Will ALWAYS be valid

Install

Latest: npm install recordari
Next: npm install recordari@next

Using Recordari

Using Recordari is divided into two steps, the record constructions, and the record evaluation.
In the construction you will be creating a sort of "template" for Recordari to use in the evaluation step. This "template" is what we call a record and will be denoted by the capital R preceding the variable name. Ex: ROptions or RConfig.

Construction

When constructing a record you will be using the Record function provided by Recordari.
This function takes two arguments, the first is the name of the record (this can be anything you like), and the second is the constraint object (this is the important part).

const { Record } = require('Recordari');
const RDemo = Record('Demo', {
  // This is the constraint object
});

In essence "the constraint object should be a modified copy of the object that you are creating a record for", let me explain.
Lets say you want to create a record for this object: { a: 42 }
And lets assume that the application expects the property a to always be a number.
We could then construct a constraint for the property a that asserts the type of the value to be a number, like this: R.Number

const { R, Record } = require('Recordari');
const RDemo = Record('Demo', {
  a: R.Number
});

R.Number is a constraint that tells Recordari that when it evaluates an object against the Demo record, the property a should be a number.

You can read about all the available constraints here!

Evaluation

After you've constructed a record you can now use it to assert the validity of objects.

const { R, Record } = require('Recordari');
const RDemo = Record('Demo', {
  a: R.Number
});
 
const demo = RDemo({ a: 42 });
console.log(demo.a); // 42

As you can see above, the Record function returns a function. This function expects a single argument, and it expects this argument to be an object that complies to the constraints of the record that you previously constructed.
If the argument does comply to the constraints, then function will act like the identity function (aka it will return the object that was passed in).
If the argument does not comply to the constraints then the function will throw a TypeError.

const { R, Record } = require('Recordari');
const RDemo = Record('Demo', {
  a: R.Number
});
 
const demo = RDemo({ a: 'hi' }); // Will throw TypeError
console.log(demo.a); // Won't be executed

Constraints

See docs/constraints.md

A great way to explore the available constraints is through intellisense exploration. Either by using typescript or by using a typescript enabled editor with javascript (such as vscode).

Contribute

See CONTRIBUTE.md

Examples

See docs/examples.md

Typescript interop

Most of Recordari is already typed out of the box.
However unfortunately typescript types needs to exists prior to compilation so we can't dynamically type an object as it goes through a Recordari record. This means that you will have to trust in Recordari to do all necessary type checks, and then override typescript by explicitly casting the resulting record to the corresponding typescript type.

  const RDemo = Record('Demo', {
    foo: R.Number.Natural,
    bar: R.String.Either(['a', 'b']),
  });
  interface IDemo {
    foo: number;
    bar: 'a' | 'b';
  }
  const demo = RDemo({
    foo: 1,
    bar: 'a',
  }) as IDemo;

.

Package Sidebar

Install

npm i recordari

Weekly Downloads

1

Version

1.2.4

License

MIT

Unpacked Size

67.1 kB

Total Files

53

Last publish

Collaborators

  • olian04