| src | ||
| .babelrc | ||
| .editorconfig | ||
| .eslintrc.js | ||
| .gitignore | ||
| .nvmrc | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| webpack.common.js | ||
| webpack.dev.js | ||
| webpack.prod.js | ||
MCF-Objects
A lightweight JavaScript library for creating typed objects with built-in validation. Define a schema once, and every read/write to the object's fields is automatically type-checked and validated against the constraints you specify.
Table of contents
Features
- Simple schema-based object definitions
- Built-in support for common types:
string,number,boolean,array,enum - Field-level constraints:
required,defaultValue,min/max,minLength/maxLength,availableValues - Automatic validation on both instantiation and later assignment
- Extendable: build your own reusable typed objects on top of
DefinedObject(see the includedFileobject)
Installation
Add the next line to your package.json file:
"mcf-objects": "git+https://github.com/DausdasKreuz/mcf-objects.git"
Then run
npm install
npm run dist
Quick start
import { DefinedObject } from 'mcf-objects'
const user = new DefinedObject({
fields: {
name: { TYPE: 'string', required: true, maxLength: 50 },
age: { TYPE: 'number', min: 0, max: 120 },
role: { TYPE: 'enum', availableValues: ['admin', 'editor', 'viewer'], defaultValue: 'viewer' },
tags: { TYPE: 'array' },
active: { TYPE: 'boolean', defaultValue: true },
},
values: {
name: 'Jane Doe',
age: 32,
tags: ['staff', 'backend'],
},
})
console.log(user.getValue())
// { name: 'Jane Doe', age: 32, role: 'viewer', tags: ['staff', 'backend'], active: true }
user.setValue({ age: 33 })
console.log(user.getValue().age) // 33
user.setValue({ age: -5 })
// Throws: MCF-Objects ==> MCF_Number validation: the value -5 is lower than the minimum defined: 0
Core concepts
Defining an object
A DefinedObject is created from a definition with two parts:
fields: the schema — one entry per field, describing itsTYPEand constraints.values: the initial values for those fields.
new DefinedObject({
fields: { /* schema */ },
values: { /* initial data */ },
})
Supported field types and options
| TYPE | Options |
|---|---|
string |
required, defaultValue, minLength, maxLength |
number |
required, defaultValue, min, max |
boolean |
required, defaultValue |
array |
required, defaultValue, minLength, maxLength |
enum |
required, defaultValue, availableValues (array of allowed values) |
Common options for every field:
required: throws if the field is missing when the object is created.defaultValue: value used when none is provided.null: false: throws if the field ends upundefined/nullafter applyingrequiredanddefaultValue.
Reading and writing values
user.getValue() // returns a plain object with the current values of every field
user.setValue({ ... }) // validates and updates one or more fields
user.getDefinition() // returns the original schema/definition
Any value that fails validation throws a descriptive Error instead of silently applying an invalid value.
Working with array fields
updateArrayField(field, item, mustBeIncluded) adds or removes a single item from an array field without having to rebuild the whole array by hand:
user.updateArrayField('tags', 'frontend', true) // adds 'frontend' if not already present
user.updateArrayField('tags', 'staff', false) // removes 'staff' if present
Building reusable typed objects
You can extend DefinedObject to create your own domain objects with a fixed set of fields. The library ships with one example, File:
import { File } from 'mcf-objects'
const file = new File({
values: {
name: 'invoice.pdf',
extension: 'pdf',
mimeType: 'application/pdf',
},
})
console.log(file.getValue())
// { name: 'invoice.pdf', extension: 'pdf', mimeType: 'application/pdf', content: '' }
File predefines name (required), extension, mimeType, and content (defaults to ''), while still allowing extra custom fields to be merged in via definition.fields.
Development
Requires Node v12.13.1 (see .nvmrc).
npm install # install dependencies
npm start # run webpack-dev-server for local development
npm run dist # build the production bundle with webpack (outputs to dist/)
The library source lives in src/ and is transpiled with Babel and bundled with Webpack; the compiled output is published to dist/.
Project structure
src/
├── index.js # public exports
├── definedObject.js # DefinedObject base class
├── types/ # built-in field types (string, number, boolean, array, enum) + factory
└── objects/ # ready-to-use typed objects (e.g. File)
Contributing
Issues and pull requests are welcome.
License
This project is under Apache Licence