# mongoose-dto
Converts to/from JSON with validation and level-based hiding

## New Version & Owner
Ownership has been transferred to [MEAN Factory](http://www.meanfactory.com) and is available under their [mf-mongoose-dto](https://github.com/MEANFactory/mf-mongoose-dto) package.

**No updates will be made to this project.  Please replace all instances with the new version from [MEAN Factory](http://www.meanfactory.com).**




## Features ##

### Conversion ###
- Convert mongoose docs to JSON (from JSON coming soon)
- Conserve space by using shorthand field names in database
- Define dot notation for database fields on schema during output
- Override field names with dot notation at any level

### Hiding / Showing Fields (during conversion) ###
- Hide fields based on current user level or permissions
- Rules defined on schema, as plugin defaults, or with each call
- Override showing or hiding of fields at runtime
- Use explicit field names or user level / permissions

### Non-Destructive Deletes ###
- Increase data integrity by retaining deleted data
- Retain historical data
- Flag objects as "deleted"
- Automatically remove deleted data from result sets
- Manually find or count data with or without deleted items

### Audit Trails ###
- Add audit fields to schemas with one line of code
- Any combination of dates... modified, created, deleted
- Track user ID of the responsible CRUD operation
- Compare / contract version differences (coming soon)

## Example #1: Expanded Field Names ##
The `ToDtoPlugin` plugin will hydrate the resulting JSON object with using camel case names for all attributes.  If desired, complex object graphs may be created during the call.

### Logic ###
1. `key`: a dot-notated path will be constructed;
2. 'name': the plain-English name (used for error messages) will be converted and used;
3. the field name is used if neither `key` or `name` exist on the schema; and,
4. enumorators are always hydrated using an `id` field with an object.

### Schema ###
```
var mongoose = require('mongoose'),
	 dto      = require('mongoose-dto'),
	 enums    = require('../enums');

var personSchema = mongoose.Schema({

    s   : { type: String, name: 'SSN'  },

    p   : { type: String, name: 'Prefix', enums: enums.NamePrefix.ids },
    f   : { type: String, name: 'First Name', key: 'name.first' },
    m   : { type: String, name: 'Middle Name', key: 'name.middle' },
    l   : { type: String, name: 'Last Name', key: 'name.last' },

    bm  : { type: Number, name: 'Birth Month', key: 'dob.month' },
    bd  : { type: Number, name: 'Birth Day', key: 'dob.day' },
    by  : { type: Number, name: 'Birth Year', key: 'dob.year' }
});

personSchema.plugin(toDtoPlugin);

module.exports = mongoose.model('Person', personSchema);
```

#### Usage: ####
```
var result = person.toJSON();
```
#### Result: ####

```
{
    ssn : '123-45-6789',
    prefix : {
        id : 'MR'
    },
    name : {
        first : 'Joe',
        last  : 'Blow'
    },
    dob  : {
        month : 12,
        day   : 31,
        year  : 2000
    }
}
```


## Example #2: Dynamically Hiding Fields ##
The `ToDtoPlugin` plugin will hide fields based field names and/or parameters on the schema.  This allows for membership levels to be used at runtime to dynamically delect fields to be hidden or shown.

### Logic ###
1. default options, supplied to the plugin, are used if not supplied during `toJSON`;
2. field may be explicity shown or hidden by supplying the name of the field(s);
3. `level` statements and options are used to determine when to show or hide fields

### Schema ###
```
var mongoose = require('mongoose'),
	 dto      = require('mongoose-dto'),
	 enums    = require('../enums');

var GUEST = 10,
    USER  = 20,
	OWNER = 30,
	ADMIN = 40;

var personSchema = mongoose.Schema({

    s   : { type: String, name: 'SSN', hide: '< 30' },

    p   : { type: String, enums: enums.NamePrefix.ids },
    f   : { type: String, name: 'First Name' },
    m   : { type: String, name: 'Middle Name', show: '>= 20' },
    l   : { type: String, name: 'Last Name', show: 30 },

    bm  : { type: Number, name: 'Birth Month' },
    bd  : { type: Number, name: 'Birth Day', hide: true },
    by  : { type: Number, name: 'Birth Year', hide: '< 40' }
});

personSchema.plugin(toDtoPlugin)({ hide: ['__t', '__v'] });

module.exports = mongoose.model('Person', personSchema);
```

#### Usage: ####
```
var result = person.toJSON({
    hide  : '_id',
    show  : ['bd', 'by'],
    level : USER
});
```
#### Result: ####

```
{
    prefix : {
        id : 'MR'
    },
    firstName  : 'Joe',
    middleName : 'Dweezil'
    birthMonth : 12,
    birthDay   : 31,
    birthYear  : 2000
}
```
#### Explanation: ####
1. Default `hide` field names were supplied to the plugin when it was initialized.  Had the document contained either `__v` or `__t` fields they would have been hidden.
1. Since no `key` properties were supplied, the `name` properties were converted to a simple attribute name instead of the complex object in the previous example;
1. The `_id` field was expicity hidden during teh `toJSON` call;
1. The `bd` and `by` fields _would_ have been hidden because of the `hide` attribute on the schema (one was `true` and the other would have evaluated), however these fields were explicty shwon during the `toJSON` call;
1. The `l` (lastName) field was hidden because the current user `level` (supplied in the `toJSON` call) does not match the strict `show: 30` value on the schema (which means to only show if the level matches exactly); and,
1. Prefix is an enumerator and is always shown as and object with `id`.

## Sample ##

### Node App ###
The `lib/` folder contains a working example to show the plugins in use.  Optionally, you may use the Docker file to start a mongo database for testing without the need to configure a new environment.  Once docker is running, test the sample with `npm test`.

### Docker ###
Get up and running using `docker-compose up` from the project directory.  




## Contact Information ##
MEAN Factory  
[support@meanfactory.com](mailto:support@meanfactory.com)  
[www.MEANFactory.com](http://www.meanfactory.com)  


## Original Author ##
Fred Lackey  
[fred.lackey@gmail.com](mailto:fred.lackey@gmail.com)  
[www.fredlackey.com](http://www.fredlackey.com)  
