WIP graphql schema definitions

This commit is contained in:
James
2020-04-03 15:11:09 -04:00
parent 36d7d87067
commit c835269ef2
4 changed files with 255 additions and 226 deletions

View File

@@ -1,16 +1,238 @@
const { GraphQLObjectType } = require('graphql');
const fieldToSchemaMap = require('./fieldToSchemaMap');
const {
GraphQLString,
GraphQLFloat,
GraphQLBoolean,
GraphQLNonNull,
GraphQLList,
GraphQLInterfaceType,
GraphQLEnumType,
GraphQLObjectType,
} = require('graphql');
const getTypeWithNullable = (field, type) => {
if (field.required && !field.localized) {
return new GraphQLNonNull(type);
}
return type;
};
const buildObjectType = (config, { name, fields }) => {
const getLocalizedType = (field, type) => {
if (config.localization && field.localized) {
return new GraphQLObjectType({
name: `${field.name} - Locale`,
fields: config.localization.locales.reduce((localeFields, locale) => {
return {
...localeFields,
[locale]: type,
};
}, {}),
});
}
return type;
};
const fieldToSchemaMap = {
number: (field) => {
const type = GraphQLFloat;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
text: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
email: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
textarea: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
WYSIWYG: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
code: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
date: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
upload: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
checkbox: field => ({
type: getLocalizedType(
field,
new GraphQLNonNull(GraphQLBoolean),
),
}),
relationship: (field) => {
const type = GraphQLString;
const typeWithLocale = getLocalizedType(
field,
getTypeWithNullable(field, type),
);
return {
type: field.hasMany ? new GraphQLList(typeWithLocale) : typeWithLocale,
};
},
repeater: (field) => {
const type = buildObjectType(config, {
name: field.label,
fields: field.fields,
});
const typeWithNullable = new GraphQLList(getTypeWithNullable(field, type));
return {
type: getLocalizedType(
field,
typeWithNullable,
),
};
},
group: (field) => {
const type = buildObjectType(config, {
name: field.label,
fields: field.fields,
});
return {
type,
};
},
select: (field) => {
const type = new GraphQLEnumType({
name: field.name,
values: field.options.reduce((values, option) => {
if (typeof option === 'object' && option.value) {
return {
...values,
[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) => {
return {
...blocks,
[block.slug]: buildObjectType(config, {
name: block.labels.singular,
fields: block.fields,
}),
};
}, {});
return getLocalizedType(
field,
new GraphQLList(new GraphQLInterfaceType({
name: field.name,
fields: {
blockType: {
type: new GraphQLEnumType({
name: 'Block Type',
values: field.blocks.reduce((values, block) => {
return {
...values,
[block.slug]: {
value: block.slug,
},
};
}, {}),
}),
},
blockName: { type: GraphQLString },
},
resolveType(value) {
return blockTypes[value.blockType];
},
})),
);
},
};
const buildType = ({ name, fields }) => {
return new GraphQLObjectType({
name,
fields: fields.reduce((schema, field) => {
return {
...schema,
[field.name]: fieldToSchemaMap(field),
[field.name]: fieldToSchemaMap[field.type](field),
};
}, {}),
});
};
module.exports = buildType;
module.exports = buildObjectType;

View File

@@ -1,221 +0,0 @@
const {
GraphQLString,
GraphQLFloat,
GraphQLBoolean,
GraphQLNonNull,
GraphQLList,
GraphQLInterfaceType,
GraphQLEnumType,
GraphQLObjectType,
} = require('graphql');
const buildObjectType = require('./buildObjectType');
const getTypeWithNullable = (field, type) => {
if (field.required && !field.localized) {
return new GraphQLNonNull(type);
}
return type;
};
const fieldToSchemaMap = (config) => {
const getLocalizedType = (field, type) => {
if (config.localization && field.localized) {
return new GraphQLObjectType({
name: `${field.name} - Locale`,
fields: config.localization.locales.reduce((fields, locale) => {
return {
...fields,
[locale]: type,
};
}, {}),
});
}
return type;
};
return {
number: (field) => {
const type = GraphQLFloat;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
text: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
textarea: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
WYSIWYG: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
code: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
date: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
upload: (field) => {
const type = GraphQLString;
return {
type: getLocalizedType(
field,
getTypeWithNullable(field, type),
),
};
},
checkbox: field => ({
type: getLocalizedType(
field,
new GraphQLNonNull(GraphQLBoolean),
),
}),
relationship: (field) => {
const type = GraphQLString;
const typeWithLocale = getLocalizedType(
field,
getTypeWithNullable(field, type),
);
return {
type: field.hasMany ? new GraphQLList(typeWithLocale) : typeWithLocale,
};
},
repeater: (field) => {
const type = buildObjectType({
name: field.label,
fields: field.fields,
});
const typeWithNullable = new GraphQLList(getTypeWithNullable(field, type));
return {
type: getLocalizedType(
field,
typeWithNullable,
),
};
},
group: (field) => {
const type = buildObjectType({
name: field.label,
fields: field.fields,
});
return {
type,
};
},
select: (field) => {
const type = new GraphQLEnumType({
name: field.name,
values: field.options.reduce((values, option) => {
if (typeof option === 'object' && option.value) {
return {
...values,
[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) => {
return {
...blocks,
[block.slug]: buildObjectType({
name: block.labels.singular,
fields: block.fields,
}),
};
}, {});
return getLocalizedType(
field,
new GraphQLList(new GraphQLInterfaceType({
name: field.name,
fields: {
blockType: {
type: new GraphQLEnumType({
name: 'Block Type',
values: field.blocks.reduce((values, block) => {
return {
...values,
[block.slug]: {
value: block.slug,
},
};
}, {}),
}),
},
blockName: { type: GraphQLString },
},
resolveType(value) {
return blockTypes[value.blockType];
},
})),
);
},
};
};
module.exports = fieldToSchemaMap;

View File

@@ -1,5 +1,6 @@
const graphQLHTTP = require('express-graphql');
const { GraphQLObjectType, GraphQLString, GraphQLSchema } = require('graphql');
const buildType = require('./buildObjectType');
const Query = {
name: 'Query',
@@ -33,6 +34,30 @@ function init() {
},
};
Object.keys(this.collections).forEach((collectionKey) => {
const collection = this.collections[collectionKey];
const label = collection.config.labels.singular.replace(' ', '');
collection.graphQLType = buildType(this.config, {
name: label,
fields: collection.config.fields,
});
Query.fields[label] = {
type: collection.graphQLType,
args: {
id: { type: GraphQLString },
},
resolve: (_, { id }) => {
return {
id,
email: 'test',
};
},
};
});
const query = new GraphQLObjectType(Query);
const mutation = new GraphQLObjectType(Mutation);

View File

@@ -17,6 +17,9 @@ const fieldToSchemaMap = {
text: (field) => {
return { ...formatBaseSchema(field), type: String };
},
email: (field) => {
return { ...formatBaseSchema(field), type: String };
},
textarea: (field) => {
return { ...formatBaseSchema(field), type: String };
},