4.2.0 • Published 6 months ago

clean-schema v4.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

Foreword

Clean-schema is a user story focused utility that helps you build factory methods to manage entities and their values in your domain.

In short, it is an event-driven schema validator which provides an interface for you to clearly define the behaviour of your entities at creation and during updates.

Installation

$ npm i clean-schema

Importing

// Using Nodejs `require`
const { Schema } = require('clean-schema');

// Using ES6 imports
import { Schema } from 'clean-schema';

Defining a schema

import { Schema, type Summary } from 'clean-schema';

type UserRole = 'admin' | 'user';

type Input = {
  firstName: string;
  lastName: string;
  password: string;
  role?: UserRole;
};

type Output = {
  createdAt: Date;
  firstName: string;
  fullName: string;
  id: number;
  lastName: string;
  password: string;
  role: UserRole;
  updatedAt: Date;
};

type ISummary = Summary<Input, Output>;

const userSchema = new Schema<Input, Output>(
  {
    firstName: {
      required: true,
      validator: validateString('invalid first name')
    },
    fullName: {
      default: '',
      dependent: true,
      dependsOn: ['firstName', 'lastName'],
      resolver: getFullName
    },
    id: { constant: true, value: generateUserId },
    lastName: {
      required: true,
      validator: validateString('invalid last name')
    },
    password: { required: true, validator: validatePassword },
    role: { default: 'user', shouldInit: false, validator: validateRole }
  },
  { timestamps: true }
);

// resolvers
function getFullName({ context: { firstName, lastName } }: ISummary) {
  return `${firstName} ${lastName}`;
}

function generateUserId() {
  return Math.random() * 1e18;
}

function hashPassword(value) {
  return Math.random().toString(value.length);
}

// validators
function validatePassword(value) {
  const isValidString = validateString()(value);

  if (!isValidString.valid) return isValidString;

  let validated = isValidString.validated;

  const valid = validated.length >= 8;

  if (!valid) return { valid, reason: 'minimum characters should be 8' };

  return { valid, validated: hashPassword(validated) };
}

function validateRole(value) {
  const isValidString = validateString()(value);

  if (!isValidString.valid) return isValidString;

  const valid = ['admin', 'user'].includes(validated);

  if (!valid) return { valid, reason: 'invalid user role' };

  return { valid, validated: isValidString.validated };
}

function validateString(message = '') {
  return (value) => {
    const typeProvided = typeof value;

    if (typeProvided != 'string') {
      const reason = message || `expected a string but got '${typeProvided}'`;

      return { valid: false, reason };
    }

    return { valid: true, validated: value.trim() };
  };
}

// get the model
const UserModel = userSchema.getModel();

Creating an entity

import userDb from 'db-of-choice'; // use any db that supports the information you are modelling

const { data: user, handleSuccess } = await UserModel.create({
  firstName: 'John',
  fullName: 'Mr. James',
  id: 1,
  lastName: 'Doe',
  lastSeen: new Date(),
  name: 'John Doe',
  password: 'au_34ibUv^T-adjInFjj',
  role: 'admin'
});

console.log(user);
//  {
//   createdAt: new Date(),
//   firstName: "John",
//   fullName: "John Doe",
//   id: 18927934748659724,
//   lastName: "Doe",
//   password: "**************",
//   role: "user",
//   updatedAt: new Date(),
// };

await userDb.insert(user);

await handleSuccess();

Updating an entity

const user = await userDb.findById(18927934748659724);

if (!user) throw new Error('User not found');

const { data, handleSuccess } = await UserModel.update(user, {
  firstName: 'Peter',
  id: 2,
  age: 34,
  fullName: 'Tony Stark'
});

// age is ignored because it is not a valid property
// fullName is ignored because it is dependent
// id is ignored because it is a constant
console.log(data); // { firstName: "Peter", fullName: "Peter Doe", updatedAt: new Date() }

await userDb.updateOne({ id: user.id }, data);

await handleSuccess();

Docs

4.0.1

7 months ago

4.0.0

7 months ago

4.0.2

7 months ago

3.5.3

8 months ago

3.5.2

8 months ago

3.5.1

9 months ago

3.5.0

10 months ago

3.4.0

10 months ago

4.2.0

6 months ago

3.3.1

10 months ago

3.3.0

10 months ago

4.0.0-beta.1

7 months ago

4.0.0-beta.0

8 months ago

4.1.0

6 months ago

3.2.1

1 year ago

3.2.0

1 year ago

3.2.0-beta.0

1 year ago

3.1.0

1 year ago

3.0.7

1 year ago

3.0.6

1 year ago

2.5.8

1 year ago

2.5.9

1 year ago

2.6.0

1 year ago

3.0.4

1 year ago

3.0.3

1 year ago

3.0.2

1 year ago

3.0.1

1 year ago

3.0.5

1 year ago

3.0.0

1 year ago

2.5.14

1 year ago

2.5.15

1 year ago

2.5.16

1 year ago

2.5.10

1 year ago

2.5.11

1 year ago

2.5.12

1 year ago

2.5.13

1 year ago

2.4.1

2 years ago

2.4.0

2 years ago

2.4.2

2 years ago

2.5.6

1 year ago

2.5.5

1 year ago

2.5.7

1 year ago

2.3.0

2 years ago

2.2.0

2 years ago

2.5.0

2 years ago

2.5.2

2 years ago

2.5.1

2 years ago

2.5.4

2 years ago

2.5.3

2 years ago

1.4.6

2 years ago

2.0.1

2 years ago

2.0.0

2 years ago

1.5.1

2 years ago

1.5.0

2 years ago

2.1.1

2 years ago

2.1.0

2 years ago

1.4.9

2 years ago

1.4.11

2 years ago

1.4.8

2 years ago

1.4.10

2 years ago

1.4.7

2 years ago

1.2.0

2 years ago

1.0.19

2 years ago

1.0.18

2 years ago

1.0.17

2 years ago

1.0.16

2 years ago

1.4.5

2 years ago

1.0.9

2 years ago

1.4.4

2 years ago

1.2.6

2 years ago

1.4.3

2 years ago

1.2.5

2 years ago

1.4.2

2 years ago

1.2.4

2 years ago

1.4.1

2 years ago

1.2.3

2 years ago

1.4.0

2 years ago

1.2.2

2 years ago

1.2.1

2 years ago

1.3.10

2 years ago

1.0.22

2 years ago

1.0.21

2 years ago

1.3.11

2 years ago

1.0.20

2 years ago

1.0.26

2 years ago

1.0.25

2 years ago

1.0.24

2 years ago

1.0.23

2 years ago

1.0.29

2 years ago

1.0.28

2 years ago

1.0.27

2 years ago

1.3.9

2 years ago

1.3.8

2 years ago

1.0.33

2 years ago

1.0.32

2 years ago

1.0.31

2 years ago

1.0.30

2 years ago

1.0.35

2 years ago

1.0.34

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.3.7

2 years ago

1.1.9

2 years ago

1.3.6

2 years ago

1.1.8

2 years ago

1.3.5

2 years ago

1.1.7

2 years ago

1.3.4

2 years ago

1.1.6

2 years ago

1.3.3

2 years ago

1.1.5

2 years ago

1.3.2

2 years ago

1.1.4

2 years ago

1.3.1

2 years ago

1.1.3

2 years ago

1.3.0

2 years ago

1.1.2

2 years ago

1.1.12

2 years ago

1.1.11

2 years ago

1.1.10

2 years ago

1.0.11

2 years ago

1.0.10

2 years ago

1.0.15

2 years ago

1.0.14

2 years ago

1.0.13

2 years ago

1.0.12

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago