GithubHelp home page GithubHelp logo

mnemesong / class-model Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 193 KB

Class scheme definition by decorator with type-validators and loaders

License: MIT License

JavaScript 56.59% TypeScript 43.41%

class-model's Introduction

class-model

Class scheme definition by decorator with type-validators and loaders

Example of usage

import * as classModel from "class-model"

//custom validator funciton
function strNotEmptyValidator(prop: string, label: string, model: any) {
    return (model[prop].length > 0)
            ? []
            : ([label + " should be grater then 0"])
}

//model class
class UserAuth {
    @classModel.property("Login", strNotEmptyValidator)
    login: string

    @classModel.property("Password", strNotEmptyValidator)
    pass: string
}

//loading
const user = new UserAuth()
const loadResult = classModel.loadData(user, {login: "asdsa", pass: "c412"})
assert.strictEqual(loadResult, true)
assert.strictEqual(user.login, "asdsa")
assert.strictEqual(user.pass, "c412")

//validation
const validationErrors1 = classModel.validationErrors(user)
assert.strictDeepEqual(validationErrors1, [])

user.password = ""
const validationErrors2 = classModel.validationErrors(user)
assert.strictDeepEqual(validationErrors2, ["Password should be grater then 0"])

//gettingPropertyLabels
assert.deepStrictEqual(classModel.utils.getAllPropertiesLabels(user), {
    login: "Login",
    pass: "Password",
})

Installation

npm i class-model

Usage

1. Set decorator to the property

class UserAuth {
    @classModel.property("Login", 
        classModel.valid.strictEqual("asdsa") //validator
    )
    login: string

    @classModel.property("Password", classModel.valid.stringLength(sl => sl > 8))
    pass: string
}

2. Use load funciton to load structure or object to model using decorated properties

const user = new UserAuth()
const loadResult = classModel.loadData(user, {login: "asdsa", pass: "c412"})
assert.strictEqual(loadResult, true)
assert.strictEqual(user.login, "asdsa")
assert.strictEqual(user.pass, "c412")

3. Use validationErrors function

user.password = ""
const validationErrors2 = classModel.validationErrors(user)
assert.strictDeepEqual(validationErrors2, ["Password should be equals \"c412\""])

//You also may assert model by them
classModel.assert(user) //Error: Password should be equals "c412"

Utils

Package provides utils functions to access metadata of model

//[class-model].utils.dts

import { MakeProperty } from "./make";
import { PropertyValidator } from "./valid";
export declare const __classModelPropertiesKey = "__classModelProperties";
export type PropertyMeta = {
    makeModel: MakeProperty;
    validator: PropertyValidator | null;
    label: string | null;
};
/**
 * Sets property to model
 */
export declare function setProperty(
    model: object, 
    propName: string | symbol, 
    label?: string | null, 
    validator?: PropertyValidator | null, 
    makeModel?: MakeProperty | null
): void;

/**
 * Gets meta-structure with validators and label of property
 */
export declare function getPropertyMeta(
    model: object, 
    propName: string | symbol
): PropertyMeta | null;

/**
 * Get structure kind of {[registeredProperty]: [labelOfProperty]}
 */
export declare function getAllPropertiesLabels(model: object): {};

/**
 * Gets structure kind of {[registeredProperty]: {label: ..., validators: [...]}}
 */
export declare function getAllPropertiesMeta(model: object): Record<string, PropertyMeta>;

/**
 * Get all properties as a string
 */
export declare function getProperties(obj: object): Array<string>;

/**
 * Returns label of property or returns property name
 * if special label had not been registered
 */
export declare function getPropertyLabel(
    model: object, 
    propName: string | symbol
): string;

/**
 * Returns all geristered validators of the property
 */
export declare function getPropertyValidator(
    model: object, 
    propName: string | symbol
): PropertyValidator | null;

/**
 * Returns special constructor of property, is it exists
 */
export declare function getMaybeMakeModelFn(
    model: object, 
    propName: string | symbol
): null | MakeProperty;

/**
 * assert anonimous value by validator
 */
export declare function assertByValidator(
    val: any, 
    validator: (propName: string | symbol, propLabel: string, propVal: any) => string[]
): void;

Special property constructors

If you want to load aggregated data or define special property construction logic on loading, you should define special constructor in property decorator

class SubModel {
    @classModel.property("A")
    a: number = 12
}

class MakeModelTestClass {
    @classModel.property("As", valid.any(), 
        classModel.make.model(() => new SubModel()) /*special property constructor*/)
    public as: SubModel //aggreagated property
}

const obj = new MakeModelTestClass()
const data = {as: {a: 15}}
const loadResult = classModel.loadData(obj, data)
assert.strictEqual(loadResult, true)
assert.strictEqual(obj.as.a, 15)

Special property constructors

We prepared two popular constructors in classModel.make module:

// classModel.make module

export type MakeProperty = (data: any) => any;

/**
 * Load model uses getter
 */
export declare function model(getModel: () => object): MakeProperty;

/**
 * Load array of models uses getter
 */
export declare function modelsArray(getModel: () => object): MakeProperty;

/**
 * Load bigint
 */
export declare function bigInt(printData?: ((v: any) => string) | null): MakeProperty;

/**
 * Constructs Date from loading data
 */
export declare function date(printData?: ((v: any) => string) | null): MakeProperty;

/**
 * Parse data as a Float
 */
export declare function float(printData?: ((v: any) => string) | null): MakeProperty;

/**
 * Parse data as a Float
 */
export declare function int(
    printData?: ((v: any) => string) | null, 
    roundStrategy?: "round" | "floor" | "ceil"
): MakeProperty;

/**
 * Parse data as a boolean
 */
export declare function boolean(): MakeProperty;

/**
 * Parse data as a string
 */
export declare function string(): MakeProperty;

/**
 * Parse data as array
 */
 export function arrayOf(make: MakeProperty|null = null): MakeProperty

Validators

Validator is function kind of:

type PropertyValidator = (propName: string, propLabel: string, propVal: any) => string[]

Some popular validators are also prepared for you, and keeps in classModel.valid module.

Validator pakcage

You may use validators from validator pakage in property decorator using classModel.valid.lambda validator

import {isHexColor} form "validator"

class LambdaCheckClass {
    @property("A", valid.lambda(isHexColor))
    public a: any
}

const obj = new LambdaCheckClass()
obj.a = "#763820"
const validErrors = validationErrors(obj)
assert.deepStrictEqual(validErrors, [])

This package is not depends of validator package. Its needs to be installed, before using.

List of validators:

//classModel.valid module

export type PropertyValidator = (
    propName: string | symbol, 
    propLabel: string, propVal: any
) => string[];

export type ValuePrinter = (v: any) => string;

/**
 * Strict not deep equals to scalar val
 */
export declare function strictEqual(
    val: string | bigint | number | boolean | null | undefined | symbol, 
    printValue?: ValuePrinter | null
): PropertyValidator;

/**
 * Deep strict equals validator
 */
export declare function strictDeepEqual(
    val: any, 
    printValue?: ValuePrinter | null
): PropertyValidator;

/**
 * Value satisfies operator !!val
 */
export declare function required(): PropertyValidator;

/**
 * Value satisfies operator !val
 */
export declare function empty(): PropertyValidator;

/**
 * Value satisfies filter function
 */
export declare function filterFn(filterFn: (v: any) => boolean): PropertyValidator;

/**
 * Deep strict equals validator
 */
export declare function oneOf(
    vals: Array<string | symbol | number | boolean | null | undefined | bigint>, 
    printValue?: ValuePrinter | null = null
): PropertyValidator;

/**
 * Validator allows anything
 */
export declare function any(): PropertyValidator;

/**
 * Validator allows nothing
 */
export declare function never(): PropertyValidator;

/**
 * Checks is value type of bigint, symbol, number, string,
 * boolean or undefined
 */
export declare function scalar(): PropertyValidator;

/**
 * Checks is property value is array of X
 */
export declare function arrayOf(
    itemValidator?: PropertyValidator | null
): PropertyValidator;

/**
 * Checks is property value is array have n of X values
 */
export declare function arrayDeepStrictUnique(
    printVal?: ValuePrinter | null
): PropertyValidator;

/**
 * Checks array count by function
 */
export declare function arrayCount(
    countCheckFn?: ((n: number) => boolean) | null
): PropertyValidator;

/**
 * Checks property is a tuple match tuple of validators
 */
export declare function arrayTuple(
    valids?: PropertyValidator[] | null
): PropertyValidator;

/**
 * Return errors if one of validators are return errors
 */
export declare function and(valids: PropertyValidator[]): PropertyValidator;

/**
 * Return errors if everyone of validators are return errors
 */
export declare function or(valids: PropertyValidator[]): PropertyValidator;

/**
 * Return errors if everyone of validators are return errors
 */
export declare function not(valid: PropertyValidator): PropertyValidator;

/**
 * Date validation by lambda
 */
export declare function date(
    valid?: ((d: Date) => string[] | boolean) | null
): PropertyValidator;

/**
 * Validate number by lambda
 */
export declare function number(
    valid?: ((n: number) => string[] | boolean) | null
): PropertyValidator;

/**
 * Checks object is instance of X
 */
export declare function objInstance(construct?: Function | null): PropertyValidator;

/**
 * Checks object is valid as a Model
 */
export declare function objValidModel(): PropertyValidator;

/**
 * Checks object has keys
 */
export declare function objHasKeys(keys: (string | symbol)[]): PropertyValidator;

/**
 * Checks object values by structure of validators
 */
export declare function objProps(
    propValidators: Record<string | symbol, PropertyValidator>
): PropertyValidator;

/**
 * Validate string by lambda
 */
export declare function string(
    valid?: ((s: string) => string[] | boolean) | null
): PropertyValidator;

/**
 * Validate string by lambda
 */
export declare function stringLength(
    valid?: ((s: number) => string[] | boolean) | null
): PropertyValidator;

/**
 * Validate string by lambda
 */
export declare function stringRegMatch(regex: RegExp | string): PropertyValidator;

/**
 * Validate string by lambda
 */
export declare function stringUuid(): PropertyValidator;

/**
 * Validate boolean value
 */
export declare function boolean(
    valid?: ((s: boolean) => string[] | boolean) | null
): PropertyValidator;

/**
 * validate Symbol value
 */
export declare function symbol(
    valid?: ((s: symbol) => string[] | boolean) | null
): PropertyValidator;

/**
 * Validate value is Null
 */
export declare function isNull(): PropertyValidator;

/**
 * Validate value is Undefined
 */
export declare function isUndefined(): PropertyValidator;

/**
 * Validate value is function
 */
export declare function func(
    valid?: ((s: Function) => string[] | boolean) | null
): PropertyValidator;

/**
 * Validate value by lambda
 * (You may use it with `validator` package)
 */
export declare function lambda(valid: (a: any) => boolean | string[]): PropertyValidator;

/**
 * Modify any validator. Allows falsable values
 */
export function maybe(valid: PropertyValidator): PropertyValidator

Author

Anatoly Starodubtsev [email protected]

License

MIT

class-model's People

Contributors

mnemesong avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.