Skip to content
forked from webiny/commodo

Commodo is a set of higher order functions that let you define and compose rich data models.

License

Notifications You must be signed in to change notification settings

Pavel910/commodo

ย 
ย 

Repository files navigation

Commodo - composable model objects

Prettier license SemVer lerna Commitizen friendly Gitter

Commodo is a set of higher order functions (HOFs) that let you define and compose rich data model objects.

Quick example

A simple model

The following example shows how to create a simple data model, which you can later use to validate data (e.g. data received as body of an HTTP request):

import { withFields, string, number, boolean } from "@commodo/fields";

const Animal = withFields({
    name: string({
        validate: value => {
            if (!value) {
                throw Error("A pet must have a name!");
            }
        }
    }),
    age: number(),
    isAwesome: boolean(),
    about: fields({
        value: {},
        instanceOf: withFields({
            type: string({ value: "cat" }),
            dangerous: boolean({ value: true })
        })()
    })
})();

const animal = new Animal();
animal.populate({ age: "7" }); // Throws data type error, cannot populate a string with number.

animal.populate({ age: 7 });
await animal.validate(); // Throws a validation error - name must be defined.

animal.name = "Garfield";
await animal.validate(); // All good.
More complex model

Using other HOFs, you can create more complex models, that have a name, attached hooks, and even storage layer, so that you can easily save the data to the database:

import { withFields, string, number, boolean, fields, onSet } from "@commodo/fields";
import { withName } from "@commodo/name";
import { withHooks } from "@commodo/hooks";
import { withStorage } from "@commodo/fields-storage";
import { MongoDbDriver, withId } from "@commodo/fields-storage-mongodb";
import { compose } from "ramda";

// Define User and Verification models.
const Verification = compose(
  withFields({
    verified: boolean(),
    verifiedOn: string()
  })
)();

const User = compose(
  withFields({
    firstName: string(),
    lastName: string(),
    email: compose(
      onSet(value => value.toLowerCase())
    )(string()),
    age: number(),
    scores: number({ list: true }),
    enabled: boolean({ value: false }),
    verification: fields({ instanceOf: Verification })
  }),
  withHooks({
    async beforeCreate() {
      if (await User.count({ query: { email: this.email } })) {
        throw Error("User with same e-mail already exists.");
      }
    }
  }),
  withName("User"), // Utilized by storage layer, to determine collection / table name.
  withId(),
  withStorage({
    driver: new MongoDbDriver({ database })
  })
)();

const user = new User();
user.populate({
  firstName: "Adrian",
  lastName: "Smith",
  email: "[email protected]",
  enabled: true,
  scores: [34, 66, 99],
  verification: {
    verified: true,
    verifiedOn: "2019-01-01"
  }
});

await user.save();

Is Commodo an ORM/ODM?

Fundamentally, Commodo is not an ORM/ODM, but can very quickly become one, by utilizing an additional HOF. You can use the already provided @commodo/fields-storage or even create your own if you don't like the existing one.

Using HOFs is a very flexible approach for defining your data models, because you can append only the functionality you actually need and will use.

Core packages:

The following section shows all of the useful higher order functions that you can use right now.

Package Short Description Version
@commodo/fields The starting point of every model. Provides base string, number, boolean and model fields.
@commodo/name Assign a name to your models.
@commodo/hooks Provides methods for defining and triggering hooks on your models.
@commodo/fields-storage Enables saving models to a database (with an appropriate driver, e.g. MySQL).

Additional packages:

Package Short Description Version
@commodo/fields-storage-ref Provides ref field, for saving references to other models saved in database.
@commodo/fields-storage-mongodb A MongoDB driver for @commodo/fields-storage package.
@commodo/fields-storage-soft-delete Introduces deleted boolean field to mark whether a model was deleted or not, instead of physically deleting the entry in the storage.

Community packages:

Package Short Description Version
commodo-fields-date Provides date field, for saving dates.
commodo-fields-object Provides object field, for saving plain objects.
commodo-fields-int Provides int field, for saving integer numbers.
commodo-fields-float Provides float field, for saving float numbers.
commodo-fields-storage-crud-logs Adds and automatically manages createdOn, updatedOn, savedOn fields.

Contributing

Please see our Contributing Guideline which explains repo organization, linting, testing, and other steps.

License

This project is licensed under the terms of the MIT license.

Contributors

Thanks goes to these wonderful people (emoji key):


Adrian Smijulj

๐Ÿ’ป ๐Ÿ“– ๐Ÿ’ก ๐Ÿ‘€ โš ๏ธ

This project follows the all-contributors specification. Contributions of any kind welcome!

About

Commodo is a set of higher order functions that let you define and compose rich data models.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%