Skip to content

Commit

Permalink
refactor(type): graffiti level models
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Marton committed Jul 30, 2015
1 parent f3912d4 commit d7bb657
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 92 deletions.
55 changes: 24 additions & 31 deletions src/field.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,41 @@
import {reduce, isDate} from 'lodash';
import {isDate} from 'lodash';

import {
GraphQLString,
GraphQLFloat,
GraphQLBoolean,
GraphQLList
} from 'graphql/type';
}
from 'graphql/type';

import {getProjection} from './projection';

/**
* @method get
* @param {Object} path
* @method getField
* @param {Object} field
* @param {Object} types
* @param {Object} models
* @return {Object} field
*/
function get (path, types, models) {

// Convert array of models to map
var modelMap = reduce(models, (map, model) => {
map[model.modelName] = model;

return map;
}, {});

if (path.path === '__v') {
function getField(field, types, models) {
if (field.name === '__v') {
return;
}

// String
if (['String', 'ObjectID'].indexOf(path.instance) > -1) {
if (['String', 'ObjectID'].indexOf(field.instance) > -1) {
return {
type: GraphQLString
};

// Number
} else if (path.instance === 'Number') {
// Number
} else if (field.instance === 'Number') {
return {
type: GraphQLFloat
};

// Date
} else if (path.instance === 'Date') {
// Date
} else if (field.instance === 'Date') {
return {
type: GraphQLString,
resolve: (modelInstance, params, source, fieldASTs) => {
Expand All @@ -55,47 +48,47 @@ function get (path, types, models) {
};

// Boolean
} else if (path.instance === 'Boolean') {
} else if (field.instance === 'Boolean') {
return {
type: GraphQLBoolean
};

// Array
} else if (path.instance === 'Array') {
} else if (field.instance === 'Array') {
var type;

// Array of refs
if (path.caster.instance === 'ObjectID') {
type = path.caster.options.ref;
if (field.caster.instance === 'ObjectID') {
type = field.caster.ref;

return {
type: new GraphQLList(types[type]),
resolve: (modelInstance, params, source, fieldASTs) => {
var projections = getProjection(fieldASTs);
return modelMap[type].find({
return models[type].model.find({
_id: {
// to make it easily testable
$in: modelInstance[path.path].map((id) => id.toString())
$in: modelInstance[field.name].map((id) => id.toString())
}
}, projections);
}
};

// Array of primitives
// Array of primitives
} else {
if (path.caster.instance === 'Number') {
if (field.caster.instance === 'Number') {
return {
type: new GraphQLList(GraphQLFloat)
};
} else if (path.caster.instance === 'String') {
} else if (field.caster.instance === 'String') {
return {
type: new GraphQLList(GraphQLString)
};
} else if (path.caster.instance === 'Boolean') {
} else if (field.caster.instance === 'Boolean') {
return {
type: new GraphQLList(GraphQLBoolean)
};
} else if (path.caster.instance === 'Date') {
} else if (field.caster.instance === 'Date') {
return {
type: new GraphQLList(GraphQLString),
resolve: (modelInstance, params, source, fieldASTs) => {
Expand All @@ -114,5 +107,5 @@ function get (path, types, models) {
}

export default {
get: get
getField
};
31 changes: 17 additions & 14 deletions src/field.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import {
} from 'graphql/type';

import User from '../fixture/user';
import {get} from './field';
import {getField} from './field';

var projection = require('./projection');

describe('field', () => {
it('should resolve String properly', () => {
var field = get({
var field = getField({
instance: 'String'
});

Expand All @@ -23,7 +23,7 @@ describe('field', () => {
});

it('should resolve Number properly', () => {
var field = get({
var field = getField({
instance: 'Number'
});

Expand All @@ -33,7 +33,7 @@ describe('field', () => {
});

it('should resolve Boolean properly', () => {
var field = get({
var field = getField({
instance: 'Boolean'
});

Expand All @@ -43,7 +43,7 @@ describe('field', () => {
});

it('should resolve Date properly', () => {
var field = get({
var field = getField({
instance: 'Date'
});

Expand Down Expand Up @@ -73,18 +73,21 @@ describe('field', () => {
});
var findStub = this.sandbox.stub(User, 'find').returnsWithResolve(users);

var field = get({
var field = getField({
instance: 'Array',
path: 'value',
name: 'value',
caster: {
instance: 'ObjectID',
options: {
ref: 'User'
}
ref: 'User'
}
}, {
User: 'foo'
}, [User]);
}, {
User: {
model: User
}
});

var result = yield field.resolve({
value: [users[0]._id, users[1]._id]
Expand All @@ -110,7 +113,7 @@ describe('field', () => {
});

it('should resolve Array of String properly', () => {
var field = get({
var field = getField({
instance: 'Array',
caster: {
instance: 'String'
Expand All @@ -123,7 +126,7 @@ describe('field', () => {
});

it('should resolve Array of Number properly', () => {
var field = get({
var field = getField({
instance: 'Array',
caster: {
instance: 'Number'
Expand All @@ -136,7 +139,7 @@ describe('field', () => {
});

it('should resolve Array of Boolean properly', () => {
var field = get({
var field = getField({
instance: 'Array',
caster: {
instance: 'Boolean'
Expand All @@ -149,7 +152,7 @@ describe('field', () => {
});

it('should resolve Array of Dates properly', () => {
var field = get({
var field = getField({
instance: 'Array',
caster: {
instance: 'Date'
Expand Down
16 changes: 12 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import {graphql} from 'graphql';

import {getModels} from './model';
import {getSchema} from './schema';
import {getTypes} from './type';

export default {
graphql,
getSchema,
getTypes
module.exports.getSchema = function (mongooseModels) {
var models = getModels(mongooseModels);
return getSchema(models);
};

module.exports.getTypes = function (mongooseModels) {
var models = getModels(mongooseModels);
return getTypes(models);
};

module.exports.graphql = graphql;
3 changes: 2 additions & 1 deletion src/integration.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import ObjectID from 'bson-objectid';
import {graphql} from 'graphql';

import {getSchema} from './schema';
import {getModels} from './model';
import User from '../fixture/user';

describe('schema integration test', () => {
let schema = getSchema([User]);
let schema = getSchema(getModels([User]));

describe('singular resource', () => {
it('should get data by id with selected fields', function* () {
Expand Down
54 changes: 54 additions & 0 deletions src/model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {map} from 'lodash';

/**
* Turn mongoose model to graffiti model
* @method getModel
* @param {Object} mongooseModel
* @return {Object} graffiti model
*/
export function getModel (mongooseModel) {
var fields = map(mongooseModel.schema.paths, (schemaPath, name) => {

var options = schemaPath.options || {};

var field = {
name: name,
path: schemaPath.path,
instance: schemaPath.instance,
indexed: options.index ? true : false
};

if (schemaPath.caster) {
field.caster = {
path: schemaPath.caster.path,
instance: schemaPath.caster.instance
};

if (schemaPath.caster.options.ref) {
field.caster.ref = schemaPath.caster.options.ref;
}
}

return field;
});

return {
name: mongooseModel.modelName,
fields: fields,
model: mongooseModel
};
}

/**
* @method getModels
* @param {Array} mongooseModels
* @return {Object} - graffiti models
*/
export function getModels (mongooseModels) {
return mongooseModels
.map(getModel)
.reduce((models, model) => {
models[model.name] = model;
return models;
}, {});
}
Empty file added src/model.spec.js
Empty file.
Loading

0 comments on commit d7bb657

Please sign in to comment.