Muesli
Simple, ORM-agnostic domain driven model management
Installation
npm install muesli
or
yarn add muesli
Optional packages(in TODO)
npm install muesli-filtersnpm install muesli-validatorsnpm install muesli-constraints
Usage
Model
class from muesli
package.
Import ;// orconst Model = ;
Define your model's props
Bookprops = ISBN: filter: 'string' value: '' constraints: {} json: {} title: filter: 'string' author: Author reference: CustomModelStore ;
Add settings for your model
BookpropsSettings = nameStrategy: 'camel' // currently affected only during json serialization for attributes' keys strict: false // if true is set, then model won't accept non schema attributes. It won't throw an error throwOnStrictError: false // if true it will throw an error when `strict` is true and you are trying to set non schema attribute useGetters: true // default to true -- give access to direct access to props via model.values object useSetters: true // default to true validators: // model validators that can validate all object's values MuesliValidators MuesliValidators ;
Setting name | Default value | Possible values | Description |
---|---|---|---|
nameStrategy | <empty string> |
(camel OR pascal OR title OR snake OR lower OR upper OR constant ) |
Props names' serialization strategy. Look inside package https://www.npmjs.com/package/change-case |
strict | false |
true OR false |
if true is set, then model won't accept non schema props. |
throwOnStrictError | false |
true OR false |
if true is set and strict === true , model will throw an error when model tries to set non schema prop |
useGetters | true |
true OR false |
gives direct access to props values via model.values object |
useSetters | true |
true OR false |
|
validators | [] |
array of model validators that can validate through whole model |
Model validation
const book = Book; book ;
There is static method to make the same operation quicker
Book ;
You can also validate only part of the model using validation group
book ;
Custom constraints and validators
Constraints and validators are asynchronous by default, but you not required to use Promises
if you don't need to.
const customConstraint = { return { return { if !groups // It is very important that you handle validation groups inside custom constraint ; return; if propValue !== 'custom value' ; return; ; }; };};
const customValidator = { return { if !groups // It is very important that you handle validation groups inside custom constraint return; if valuespassword !== valuespassword_confirmation throw 'Password and password confirmation must be equal'; // You don't need to return anything if everything is fine };};
Computed props
{}Authorprops = firstName: filter: String value: 'Dmytro' lastName: filter: String fullName: { return deps; } computed: 'firstName' 'lastName' ;const author = ; console; // output -> 'Dmytro'author;console; // output -> 'Dmytro Zelenetskyi'
Deserializing and serializing model(fromJSON/toJSON)
{} Authorprops = name: filter: 'string' constraints: MusliConstraints lastName: filter: 'string' ; const horror = Author;console;// outputs `true` console;// outputs `{ name: "Stephen", lastName: "King" }`
useGetters
and useSetters
options
Using if useGetters
or/and useSetters
options are set to true
,
then you can use props' values directly via model.values
object.
Example:
{}Authorprops = name: filter: 'string' value: 'Default value' age: filter: 'number' value: 0 ;AuthorpropsSettings = useGetters: true useSetters: true; const model = ;console; // outputs: 'Default value'console; // outputs: 0 // or you can use settermodelvaluesage = 30;console; // outputs: 30
model.values
object can't be extended. Only props from schema are available. Setters won't be provided for
computed properties.
Model version
With each model mutation model increases it's version, so you can track it.
const author = Author;console; // output: 1model;console; // output: 2
Creating ORM-like entities
const pg = ;const SQL = static { throw 'Implement me'; } static async { const rows = await pool); return this; } static { return 'users'; } static { return first_name: filter: 'string' last_name: filter: 'string' password: filter: 'string' ; } const user = UserEntity;console;console;
Events
Model inherits event system from rx-emitter
(github link) package that uses rxjs
and handles all events as observables.
const book = ; RxObservable; book;book;
License
Muesli is released under the MIT license.