builds where input query type

This commit is contained in:
James
2020-04-04 16:09:12 -04:00
parent c47cef4ac3
commit dc26fb1d20
10 changed files with 228 additions and 276 deletions

View File

@@ -9,7 +9,6 @@ module.exports = (User, config) => {
opts.secretOrKey = config.user.auth.secretKey;
return new JwtStrategy(opts, (token, done) => {
console.log(`Token authenticated for user: ${token.email}`);
User.findByUsername(token.email, (err, user) => {
if (err || !user) done(null, false);
return done(null, user);

View File

@@ -1,244 +0,0 @@
const {
GraphQLString,
GraphQLFloat,
GraphQLBoolean,
GraphQLList,
GraphQLInterfaceType,
GraphQLEnumType,
GraphQLObjectType,
} = require('graphql');
const formatName = require('./formatName');
const combineParentName = require('./combineParentName');
const getTypeWithOperators = require('./getTypeWithOperators');
const buildQueryInputObjectType = ({ name, fields, parent }) => {
const fieldToSchemaMap = {
number: (field) => {
const type = GraphQLFloat;
return {
type: getTypeWithOperators(
field,
type,
parent,
['equals', 'gte', 'gt', 'lte', 'lt', 'ne'],
),
};
},
text: (field) => {
const type = GraphQLString;
return {
type: getTypeWithOperators(
field,
type,
parent,
['equals', 'like', 'ne'],
),
};
},
email: (field) => {
const type = GraphQLString;
return {
type: getTypeWithOperators(
field,
type,
parent,
['equals', 'like', 'ne'],
),
};
},
textarea: (field) => {
const type = GraphQLString;
return {
type: getTypeWithOperators(
field,
type,
parent,
['equals', 'like', 'ne'],
),
};
},
WYSIWYG: (field) => {
const type = GraphQLString;
return {
type: getTypeWithOperators(
field,
type,
parent,
['equals', 'like', 'ne'],
),
};
},
code: (field) => {
const type = GraphQLString;
return {
type: getTypeWithOperators(
field,
type,
parent,
['equals', 'like', 'ne'],
),
};
},
date: (field) => {
const type = GraphQLString;
return {
type: getTypeWithOperators(
field,
type,
parent,
['equals', 'like', 'ne'],
),
};
},
upload: () => {
const type = GraphQLString;
return {
type,
};
},
checkbox: field => ({
type: getTypeWithOperators(
field,
GraphQLBoolean,
parent,
['equals', 'ne'],
),
}),
relationship: (field) => {
const type = GraphQLString;
const typeWithLocale = getLocalizedType(
field,
getTypeWithNullable(field, type),
);
return {
type: field.hasMany ? new GraphQLList(typeWithLocale) : typeWithLocale,
};
},
repeater: (field) => {
const fullName = combineParentName(parent, field.label);
const type = buildObjectType(config, {
name: fullName,
fields: field.fields,
parent: fullName,
});
const typeWithNullable = new GraphQLList(getTypeWithNullable(field, type));
return {
type: getLocalizedType(
field,
typeWithNullable,
),
};
},
group: (field) => {
const fullName = combineParentName(parent, field.label);
const type = buildObjectType(config, {
name: fullName,
fields: field.fields,
parent: fullName,
});
return {
type,
};
},
select: (field) => {
const fullName = combineParentName(parent, field.label);
const type = new GraphQLEnumType({
name: fullName,
values: field.options.reduce((values, option) => {
if (typeof option === 'object' && option.value) {
return {
...values,
[formatName(option.label)]: {
value: option.value,
},
};
}
if (typeof option === 'string') {
return {
...values,
[option]: {
value: option,
},
};
}
return values;
}, {}),
});
const typeWithList = field.hasMany ? new GraphQLList(type) : type;
const typeWithNullable = getTypeWithNullable(field, typeWithList);
return {
type: getLocalizedType(
field,
typeWithNullable,
),
};
},
flexible: (field) => {
const blockTypes = field.blocks.reduce((blocks, block) => {
const formattedBlockName = formatName(block.labels.singular);
const fullName = `${combineParentName(parent, field.label)}_${formattedBlockName}`;
return {
...blocks,
[block.slug]: buildObjectType(config, {
name: fullName,
fields: block.fields,
parent: fullName,
}),
};
}, {});
return {
type: getLocalizedType(
field,
new GraphQLList(new GraphQLInterfaceType({
name: combineParentName(parent, field.label),
fields: {
blockType: {
type: new GraphQLEnumType({
name: `${combineParentName(parent, field.label)}_BlockType`,
values: field.blocks.reduce((values, block) => {
return {
...values,
[block.slug]: {
value: block.slug,
},
};
}, {}),
}),
},
blockName: { type: GraphQLString },
},
resolveType(value) {
return blockTypes[value.blockType];
},
})),
),
};
},
};
return new GraphQLObjectType({
name,
fields: fields.reduce((schema, field) => {
const fieldName = formatName(field.label);
return {
...schema,
[fieldName]: fieldToSchemaMap[field.type](field),
};
}, {}),
});
};
module.exports = buildQueryInputObjectType;

View File

@@ -1,7 +1,9 @@
const graphQLHTTP = require('express-graphql');
const { GraphQLObjectType, GraphQLString, GraphQLSchema } = require('graphql');
const buildType = require('./buildObjectType');
const buildInputObjectType = require('./buildInputObjectType');
const buildType = require('./schema/buildObjectType');
const buildWhereInputType = require('./schema/buildWhereInputType');
const formatName = require('./utilities/formatName');
const withPolicy = require('./resolvers/withPolicy');
const Query = {
name: 'Query',
@@ -38,30 +40,41 @@ function init() {
Object.keys(this.collections).forEach((collectionKey) => {
const collection = this.collections[collectionKey];
const label = collection.config.labels.singular.replace(' ', '');
const {
config: {
policies,
fields,
labels: {
singular: singularLabel,
},
},
} = collection;
const label = formatName(singularLabel);
collection.graphQLType = buildType(this.config, {
name: label,
fields: collection.config.fields,
fields,
parent: label,
});
collection.graphQLInputType = buildInputObjectType({
collection.graphQLWhereInputType = buildWhereInputType({
name: label,
fields: collection.config.fields,
fields,
parent: label,
});
Query.fields[label] = {
type: collection.graphQLType,
args: {
data: collection.graphQLInputType,
where: { type: collection.graphQLWhereInputType },
},
resolve: async (_, { id }, context) => {
resolve: withPolicy(policies.read, async (_, args, context) => {
console.log(JSON.stringify(args);
return {
id,
email: 'test',
image: 'test',
};
},
}),
};
});

View File

@@ -0,0 +1,21 @@
const { Forbidden } = require('../../errors');
const withPolicy = (policy, resolver) => (_, args, context) => {
const { user } = context;
if (policy) {
if (!policy(user)) {
throw new Forbidden();
}
return resolver(_, args, context);
}
if (user) {
return resolver(_, args, context);
}
throw new Forbidden();
};
module.exports = withPolicy;

View File

@@ -9,9 +9,9 @@ const {
GraphQLObjectType,
} = require('graphql');
const formatName = require('./formatName');
const combineParentName = require('./combineParentName');
const getTypeWithNullable = require('./combineParentName');
const formatName = require('../utilities/formatName');
const combineParentName = require('../utilities/combineParentName');
const withNullableType = require('./withNullableType');
const buildObjectType = (config, { name, fields, parent }) => {
const getLocalizedType = (field, type) => {
@@ -36,7 +36,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
withNullableType(field, type),
),
};
},
@@ -45,7 +45,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
withNullableType(field, type),
),
};
},
@@ -54,7 +54,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
withNullableType(field, type),
),
};
},
@@ -63,7 +63,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
withNullableType(field, type),
),
};
},
@@ -72,7 +72,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
withNullableType(field, type),
),
};
},
@@ -81,7 +81,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
withNullableType(field, type),
),
};
},
@@ -90,7 +90,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
withNullableType(field, type),
),
};
},
@@ -99,7 +99,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
withNullableType(field, type),
),
};
},
@@ -113,7 +113,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
const type = GraphQLString;
const typeWithLocale = getLocalizedType(
field,
getTypeWithNullable(field, type),
withNullableType(field, type),
);
return {
@@ -129,7 +129,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
parent: fullName,
});
const typeWithNullable = new GraphQLList(getTypeWithNullable(field, type));
const typeWithNullable = new GraphQLList(withNullableType(field, type));
return {
type: getLocalizedType(
@@ -180,7 +180,7 @@ const buildObjectType = (config, { name, fields, parent }) => {
});
const typeWithList = field.hasMany ? new GraphQLList(type) : type;
const typeWithNullable = getTypeWithNullable(field, typeWithList);
const typeWithNullable = withNullableType(field, typeWithList);
return {
type: getLocalizedType(

View File

@@ -0,0 +1,163 @@
const {
GraphQLString,
GraphQLFloat,
GraphQLBoolean,
GraphQLList,
// GraphQLInterfaceType,
// GraphQLEnumType,
GraphQLInputObjectType,
} = require('graphql');
const formatName = require('../utilities/formatName');
// const combineParentName = require('./combineParentName');
const withTypeOperators = require('./withTypeOperators');
const buildWhereInputType = ({ name, fields, parent }) => {
const fieldToSchemaMap = {
number: (field) => {
const type = GraphQLFloat;
return {
type: withTypeOperators(
field,
type,
parent,
['equals', 'gte', 'gt', 'lte', 'lt', 'not_equals'],
),
};
},
text: (field) => {
const type = GraphQLString;
return {
type: withTypeOperators(
field,
type,
parent,
['equals', 'like', 'not_equals'],
),
};
},
email: (field) => {
const type = GraphQLString;
return {
type: withTypeOperators(
field,
type,
parent,
['equals', 'like', 'not_equals'],
),
};
},
textarea: (field) => {
const type = GraphQLString;
return {
type: withTypeOperators(
field,
type,
parent,
['equals', 'like', 'not_equals'],
),
};
},
WYSIWYG: (field) => {
const type = GraphQLString;
return {
type: withTypeOperators(
field,
type,
parent,
['equals', 'like', 'not_equals'],
),
};
},
code: (field) => {
const type = GraphQLString;
return {
type: withTypeOperators(
field,
type,
parent,
['equals', 'like', 'not_equals'],
),
};
},
date: (field) => {
const type = GraphQLString;
return {
type: withTypeOperators(
field,
type,
parent,
['equals', 'like', 'not_equals'],
),
};
},
upload: () => {
const type = GraphQLString;
return {
type,
};
},
checkbox: field => ({
type: withTypeOperators(
field,
GraphQLBoolean,
parent,
['equals', 'not_equals'],
),
}),
};
const fieldTypes = fields.reduce((schema, field) => {
const getFieldSchema = fieldToSchemaMap[field.type];
if (getFieldSchema) {
return {
...schema,
[formatName(field.label)]: getFieldSchema(field),
};
}
return schema;
}, {});
// fieldTypes.id = {
// text: (field) => {
// const type = GraphQLString;
// return {
// type: withTypeOperators(
// field,
// type,
// parent,
// ['equals', 'not_equals'],
// ),
// };
// },
// };
const fieldName = formatName(name);
return new GraphQLInputObjectType({
name: `${fieldName}Where`,
fields: {
...fieldTypes,
OR: {
type: new GraphQLList(new GraphQLInputObjectType({
name: `${fieldName}WhereOr`,
fields: {
...fieldTypes,
},
})),
},
AND: {
type: new GraphQLList(new GraphQLInputObjectType({
name: `${fieldName}WhereAnd`,
fields: {
...fieldTypes,
},
})),
},
},
});
};
module.exports = buildWhereInputType;

View File

@@ -1,17 +1,17 @@
const { GraphQLObjectType } = require('graphql');
const combineParentName = require('./combineParentName');
const { GraphQLInputObjectType } = require('graphql');
const combineParentName = require('../utilities/combineParentName');
const getTypeWithOperators = (field, type, parent, operators) => {
const fullName = combineParentName(parent, field.label);
return new GraphQLObjectType({
const fullName = `${combineParentName(parent, field.label)}_Operator`;
return new GraphQLInputObjectType({
name: fullName,
fields: operators.reduce((fields, operator) => {
return {
...fields,
[operator]: { type },
},
};
}, {}),
});
}
};
module.exports = getTypeWithOperators;