2.5.2 • Published 8 years ago

moldy v2.5.2

Weekly downloads
110
License
MIT
Repository
github
Last release
8 years ago

TOC

moldy

Create a Moldy.

var personMoldy = Moldy.extend( 'person' )
	.$property( 'id' )
	.$property( 'name' )
	.$property( 'age' )
	.create();
personMoldy.should.have.a.property( 'id', undefined );
personMoldy.should.have.a.property( 'name', undefined );
personMoldy.should.have.a.property( 'age', undefined );

Property Attributes

Type & default

Properties can by strongly typed. If a type has been defined, values are cast to that type automatically. If a value cannot be cast to a type then the value will be set to null or the default if it has been defined.

var personMoldy = Moldy.extend( 'person', {
				properties: {
					'age': 'number',
					'active': {
						type: 'boolean',
						default: false
					},
					'tags': 'array'
				}
			} ).create();
			/**
			 * When a model's properties have been `typed` the assigned values are cast on the fly
			 * to ensure the model's data remains sanitized.
			 */
			/**
			 * Cast a `string` for `age` to a `number`
			 */
			personMoldy.age = '13';
			personMoldy.age.should.equal( 13 ).and.be.an.instanceOf( Number );
			/**
			 * Cast a truthy `string` for `active` as a `boolean`
			 */
			personMoldy.active = 'yes';
			personMoldy.active.should.equal( true ).and.be.an.instanceOf( Boolean );
			/**
			 * `active` is typed as a `boolean` _and_ a `default` has been defined. When an
			 * assigned value that cannot be cast as a `boolean` is set then the `default` will
			 * apply.
			 */
			personMoldy.active = 'this is not a boolean';
			should( personMoldy.active ).equal( false ).and.be.an.instanceOf( Boolean );
			/**
			 * Cast a `string` for `tags` as an `array`
			 */
			personMoldy.tags = 'lorem';
			should( personMoldy.tags ).eql( [ 'lorem' ] ).and.be.an.instanceOf( Array );

Optional

Properties can be optional. By making a property optional, isValid() and toJson() will ignore it if is has not been set.

var personMoldy = Moldy.extend( 'person' )
	.$property( 'id' )
	.$property( 'name' )
	.$property( 'age', {
		type: 'number',
		optional: true
	} )
	.$property( 'active', {
		type: 'boolean',
		default: false
	} )
	.$property( 'tags', {
		type: 'array',
		optional: true
	} )
	.create();
/**
 * To ensure this `person` is valid we only need to set the `id` and `name` because
 * the other keys are either `optional` or have `defaults`.
 */
personMoldy.id = 1;
personMoldy.name = 'David';
personMoldy.$isValid().should.be.ok;

Arrays of a type

A property can be defined as array of a type like an array of strings, or an array of numbers.

var personMoldy = Moldy.extend( 'person' )
	.$property( 'id' )
	.$property( 'tags', {
		type: [ 'string' ]
	} )
	.create();
/**
 * When defining an array of a type, the arrays are normal arrays however they have been
 * extended to allow hooks into the necessary methods for sanitization.
 */
personMoldy.tags.should.be.an.Array;
personMoldy.tags.should.have.a.property( 'length' ).and.be.a.Number;
personMoldy.tags.should.have.a.property( 'pop' ).and.be.a.Function;
personMoldy.tags.should.have.a.property( 'push' ).and.be.a.Function;
personMoldy.tags.should.have.a.property( 'reverse' ).and.be.a.Function;
personMoldy.tags.should.have.a.property( 'shift' ).and.be.a.Function;
personMoldy.tags.should.have.a.property( 'sort' ).and.be.a.Function;
personMoldy.tags.should.have.a.property( 'splice' ).and.be.a.Function;
personMoldy.tags.should.have.a.property( 'unshift' ).and.be.a.Function;
/**
 * Pushing a value - like normal
 */
personMoldy.tags.push( 'yellow' );
/**
 * We are pushing a `number` here to show how the value will be cast to a string
 */
personMoldy.tags.push( 1 );
/**
 * The value `1` is now a string
 */
personMoldy.tags[ 1 ].should.equal( '1' );
personMoldy.tags.should.have.a.lengthOf( 2 );
personMoldy.tags.should.eql( [ 'yellow', '1' ] );
/**
 * A gotcha for using primitive types in this context is that they are not sanitized
 * based on the schema if they are changed directly
 */
personMoldy.tags[ 1 ] = 1;
/**
 * Technically this should have cast the number `1` to a string but it was a design
 * decision not to add getters/setters to each item in an array. A santize method will
 * be added in the next version
 */
personMoldy.tags[ 1 ].should.equal( 1 );

Array types can also be model schemas.

var personMoldy = Moldy.extend( 'person' )
	.$property( 'cars', {
		type: [ {
			name: 'car',
			properties: {
				make: 'string',
				model: {
					type: 'string',
					default: ''
				},
				year: 'number'
			}
		} ]
	} )
	.create();
/**
 * Note, we are missing the `model` key and the `year` is a string
 */
personMoldy.cars.push( {
	make: 'honda',
	year: '2010'
} );
personMoldy.cars[ 0 ].$json().should.eql( {
	id: undefined,
	make: 'honda',
	model: '',
	year: 2010
} );

A model's url aka endpoint

A url (endpoint) is automatically generated based on the Moldy name, key, $url() and $baseUrl().

var Person = Moldy.extend( 'person', {
	baseUrl: '/api'
} );
var personMoldy = Person.create();
Person.$url().should.eql( '/api/person' );
/**
 * The url can be changed using either `base()` or `url()`
 */
Person.$url( 'v1' );
Person.$url().should.eql( '/api/person/v1' );

find

To find by id or key, give an object with appropriate conditions.

var personMoldy = Moldy.extend( 'person', {
	key: 'guid',
	properties: {
		name: ''
	}
} );
personMoldy.$findOne( {
	guid: '5f55821f-3a28-45c3-b91d-7df927a863d8'
}, function ( _error, _res ) {
	if ( _error ) {
		return _done( _error );
	}
	_done();
} );

If an adapter responds with an array the first item will be returned.

var Person = Moldy.extend( 'person', {
	key: 'guid',
	properties: {
		name: ''
	}
} );
/**
 * In this example the end point GET `http://localhost:3000/api` returns an array of items.
 * Moldy will return the first item out of the array. If you need to return an array you can
 * use the $collection method.
 */
Person.$findOne( function ( _error, _res ) {
	if ( _error ) {
		return _done( _error );
	}
	_res.should.not.be.an.Array;
	_done();
} );

find

To find an array of models.

var Person = Moldy.extend( 'person', {
	key: 'guid',
	properties: {
		name: 'string'
	}
} );
Person.$find( function ( _error, _people ) {
	if ( _error ) {
		return _done( _error );
	}
	_people.should.be.an.Array().with.a.lengthOf( 3 );
	_people.forEach( function ( _person ) {
		_person.should.be.a.Moldy;
	} );
	_done();
} );

save

To save the model, call save(). If the model is dirty (has not been saved to the server and therefore does not have a valid key) then the http method will be POST. If the model has been saved, then the http method will be PUT.

var personMoldy = Moldy.extend( 'person', {
	properties: {
		name: 'string'
	}
} ).create();
personMoldy.name = 'David';
personMoldy.$save( function ( _error, _res ) {
	if ( _error ) {
		return _done( _error );
	}
	personMoldy.$json().should.eql( _res.$json() );
	personMoldy.should.have.a.property( 'id' );
	personMoldy.name = 'Mr David';
	personMoldy.$save( function ( _error, _res ) {
		personMoldy.should.eql( _res );
		_done( _error );
	} );
} );

destroy

To destroy a model, call destroy().

var personMoldy = Moldy.extend( 'person', {
	key: 'guid',
	properties: {
		name: 'string'
	}
} ).create();
personMoldy.name = 'David';
personMoldy.$save( function ( _error, _res ) {
	if ( _error ) {
		return _done( _error );
	}
	personMoldy.$destroy( function ( _error, _res ) {
		personMoldy.$isDirty().should.be.true;
		//personMoldy.$isValid().should.be.false; -- DO NOT GET WHY SHOULD BE FALSE
		//personMoldy.__destroyed.should.be.true;
		_done( _error );
	} );
} );
2.5.2

8 years ago

2.5.1

8 years ago

2.5.0

8 years ago

2.4.0

8 years ago

2.3.0

8 years ago

2.2.0-0

8 years ago

2.2.0

8 years ago

2.1.3

9 years ago

2.1.2

9 years ago

2.1.1

9 years ago

2.1.0

9 years ago

2.0.0

9 years ago

1.3.6

9 years ago

1.3.5

10 years ago

1.3.4

10 years ago

1.3.3

10 years ago

1.3.2

10 years ago

1.3.1

10 years ago

1.3.0

10 years ago

1.2.0

10 years ago

1.1.8

10 years ago

1.1.7

10 years ago

1.1.6

10 years ago

1.1.5

10 years ago

1.1.4

10 years ago

1.1.3

10 years ago

1.1.2

10 years ago

1.1.1

10 years ago

1.1.0

10 years ago

1.0.1

10 years ago

1.0.0

10 years ago

0.1.1

10 years ago

0.1.0

10 years ago

0.0.29

10 years ago

0.0.28

10 years ago

0.0.27

10 years ago

0.0.26

10 years ago

0.0.25

10 years ago

0.0.24

10 years ago

0.0.23

10 years ago

0.0.22

10 years ago

0.0.21

10 years ago

0.0.20

10 years ago

0.0.19

10 years ago

0.0.18

10 years ago

0.0.17

10 years ago

0.0.16

10 years ago

0.0.15

10 years ago

0.0.14

10 years ago

0.0.13

10 years ago

0.0.12

10 years ago

0.0.11

10 years ago

0.0.10

10 years ago

0.0.9

10 years ago