working flexible field with all locales
This commit is contained in:
@@ -13,18 +13,21 @@ const buildWhereInputType = require('./schema/buildWhereInputType');
|
||||
const formatName = require('./utilities/formatName');
|
||||
const getLocaleStringType = require('./types/getLocaleStringType');
|
||||
const getLocaleFloatType = require('./types/getLocaleFloatType');
|
||||
const getBuildLocaleObjectType = require('./types/getBuildLocaleObjectType');
|
||||
const getLocaleBooleanType = require('./types/getLocaleBooleanType');
|
||||
const getBuildLocaleCustomType = require('./types/getBuildLocaleCustomType');
|
||||
const getCheckIfLocaleObject = require('./utilities/getCheckIfLocaleObject');
|
||||
const { getFind, getFindByID } = require('../collections/graphql/resolvers');
|
||||
|
||||
class GraphQL {
|
||||
constructor(config, collections) {
|
||||
this.config = config;
|
||||
this.collections = collections;
|
||||
|
||||
this.init = this.init.bind(this);
|
||||
this.registerUser = this.registerUser.bind(this);
|
||||
this.registerCollections = this.registerCollections.bind(this);
|
||||
this.buildBlockTypeIfMissing = this.buildBlockTypeIfMissing.bind(this);
|
||||
|
||||
this.config = config;
|
||||
this.collections = collections;
|
||||
this.checkIfLocaleObject = getCheckIfLocaleObject(this.config.localization);
|
||||
|
||||
this.Query = {
|
||||
name: 'Query',
|
||||
@@ -37,12 +40,13 @@ class GraphQL {
|
||||
};
|
||||
|
||||
this.types = {
|
||||
LocaleStringType: getLocaleStringType(this.config.localization),
|
||||
LocaleFloatType: getLocaleFloatType(this.config.localization),
|
||||
LocaleStringType: getLocaleStringType(this),
|
||||
LocaleFloatType: getLocaleFloatType(this),
|
||||
LocaleBooleanType: getLocaleBooleanType(this),
|
||||
blockTypes: {},
|
||||
};
|
||||
|
||||
this.buildLocaleObjectType = getBuildLocaleObjectType(this);
|
||||
this.buildLocaleCustomType = getBuildLocaleCustomType(this);
|
||||
this.buildObjectType = getBuildObjectType(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-use-before-define */
|
||||
const {
|
||||
GraphQLString,
|
||||
GraphQLFloat,
|
||||
@@ -14,90 +15,76 @@ const combineParentName = require('../utilities/combineParentName');
|
||||
const withNullableType = require('./withNullableType');
|
||||
|
||||
function getBuildObjectType(context) {
|
||||
const withLocalizedType = (field, type) => {
|
||||
if (context.config.localization && field.localized) {
|
||||
if (type instanceof GraphQLObjectType) {
|
||||
const LocaleObjectType = context.buildLocaleObjectType(field, type);
|
||||
return LocaleObjectType;
|
||||
}
|
||||
|
||||
if (type === GraphQLString) {
|
||||
return context.types.LocaleStringType;
|
||||
}
|
||||
|
||||
if (type === GraphQLFloat) {
|
||||
return context.types.LocaleFloatType;
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
};
|
||||
|
||||
const buildObjectType = (name, fields, parent, resolver) => {
|
||||
const fieldToSchemaMap = {
|
||||
number: (field) => {
|
||||
return {
|
||||
type: withLocalizedType(field, withNullableType(field, GraphQLFloat)),
|
||||
type: withNullableType(
|
||||
field,
|
||||
field.localized ? context.types.LocaleFloatType : GraphQLFloat,
|
||||
),
|
||||
};
|
||||
},
|
||||
text: (field) => {
|
||||
return {
|
||||
type: withLocalizedType(field, withNullableType(field, GraphQLString)),
|
||||
type: withNullableType(
|
||||
field,
|
||||
field.localized ? context.types.LocaleStringType : GraphQLString,
|
||||
),
|
||||
};
|
||||
},
|
||||
email: (field) => {
|
||||
return {
|
||||
type: withLocalizedType(
|
||||
type: withNullableType(
|
||||
field,
|
||||
withNullableType(field, GraphQLString),
|
||||
field.localized ? context.types.LocaleStringType : GraphQLString,
|
||||
),
|
||||
};
|
||||
},
|
||||
textarea: (field) => {
|
||||
return {
|
||||
type: withLocalizedType(
|
||||
type: withNullableType(
|
||||
field,
|
||||
withNullableType(field, GraphQLString),
|
||||
field.localized ? context.types.LocaleStringType : GraphQLString,
|
||||
),
|
||||
};
|
||||
},
|
||||
WYSIWYG: (field) => {
|
||||
return {
|
||||
type: withLocalizedType(
|
||||
type: withNullableType(
|
||||
field,
|
||||
withNullableType(field, GraphQLString),
|
||||
field.localized ? context.types.LocaleStringType : GraphQLString,
|
||||
),
|
||||
};
|
||||
},
|
||||
code: (field) => {
|
||||
return {
|
||||
type: withLocalizedType(
|
||||
type: withNullableType(
|
||||
field,
|
||||
withNullableType(field, GraphQLString),
|
||||
field.localized ? context.types.LocaleStringType : GraphQLString,
|
||||
),
|
||||
};
|
||||
},
|
||||
date: (field) => {
|
||||
return {
|
||||
type: withLocalizedType(
|
||||
type: withNullableType(
|
||||
field,
|
||||
withNullableType(field, GraphQLString),
|
||||
field.localized ? context.types.LocaleStringType : GraphQLString,
|
||||
),
|
||||
};
|
||||
},
|
||||
upload: (field) => {
|
||||
const type = GraphQLString;
|
||||
return {
|
||||
type: withLocalizedType(
|
||||
type: withNullableType(
|
||||
field,
|
||||
withNullableType(field, type),
|
||||
field.localized ? context.types.LocaleStringType : GraphQLString,
|
||||
),
|
||||
};
|
||||
},
|
||||
checkbox: field => ({
|
||||
type: withLocalizedType(
|
||||
type: withNullableType(
|
||||
field,
|
||||
new GraphQLNonNull(GraphQLBoolean),
|
||||
field.localized ? context.types.LocaleBooleanType : GraphQLBoolean,
|
||||
),
|
||||
}),
|
||||
select: (field) => {
|
||||
@@ -132,10 +119,7 @@ function getBuildObjectType(context) {
|
||||
const typeWithNullable = withNullableType(field, typeWithList);
|
||||
|
||||
return {
|
||||
type: withLocalizedType(
|
||||
field,
|
||||
typeWithNullable,
|
||||
),
|
||||
type: field.localized ? context.buildLocaleCustomType(field, typeWithNullable, parent) : typeWithNullable,
|
||||
};
|
||||
},
|
||||
relationship: (field) => {
|
||||
@@ -158,16 +142,17 @@ function getBuildObjectType(context) {
|
||||
relationshipType = context.collections[relationTo].graphQLType;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
relationshipType = relationshipType || blockType;
|
||||
// If the relationshipType is undefined at this point,
|
||||
// it can be assumed that this blockType can have a relationship
|
||||
// to itself. Therefore, we set the relationshipType equal to the blockType
|
||||
// that is currently being created.
|
||||
|
||||
const typeWithLocale = withLocalizedType(
|
||||
field,
|
||||
withNullableType(field, relationshipType),
|
||||
);
|
||||
relationshipType = relationshipType || newlyCreatedBlockType;
|
||||
|
||||
const localizedType = field.localized ? context.buildLocaleCustomType(field, relationshipType, parent) : relationshipType;
|
||||
|
||||
return {
|
||||
type: field.hasMany ? new GraphQLList(typeWithLocale) : typeWithLocale,
|
||||
type: field.hasMany ? new GraphQLList(localizedType) : localizedType,
|
||||
};
|
||||
},
|
||||
repeater: (field) => {
|
||||
@@ -176,10 +161,7 @@ function getBuildObjectType(context) {
|
||||
const typeWithNullable = new GraphQLList(withNullableType(field, type));
|
||||
|
||||
return {
|
||||
type: withLocalizedType(
|
||||
field,
|
||||
typeWithNullable,
|
||||
),
|
||||
type: field.localized ? context.buildLocaleCustomType(field, typeWithNullable, parent) : typeWithNullable,
|
||||
};
|
||||
},
|
||||
group: (field) => {
|
||||
@@ -191,25 +173,35 @@ function getBuildObjectType(context) {
|
||||
};
|
||||
},
|
||||
flexible: (field) => {
|
||||
const types = field.blocks.map((block) => {
|
||||
const blockTypes = field.blocks.map((block) => {
|
||||
context.buildBlockTypeIfMissing(block);
|
||||
return context.types.blockTypes[block.slug];
|
||||
});
|
||||
|
||||
return {
|
||||
type: withLocalizedType(
|
||||
field,
|
||||
new GraphQLList(
|
||||
new GraphQLUnionType({
|
||||
name: combineParentName(parent, field.label),
|
||||
types,
|
||||
resolveType(data) {
|
||||
return context.types.blockTypes[data.blockType];
|
||||
},
|
||||
}),
|
||||
),
|
||||
),
|
||||
};
|
||||
const flexibleType = new GraphQLList(
|
||||
new GraphQLUnionType({
|
||||
name: combineParentName(parent, field.label),
|
||||
blockTypes,
|
||||
resolveType(data) {
|
||||
// If the field contains all locales, it's a locale object
|
||||
// Send back the locale object type
|
||||
// Otherwise, grab the appropriate block type and send that
|
||||
if (context.checkIfLocaleObject(data)) {
|
||||
return flexibleLocaleObjectType;
|
||||
}
|
||||
return context.types.blockTypes[data.blockType];
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const flexibleLocaleObjectType = context.buildLocaleCustomType(field, flexibleType, parent);
|
||||
|
||||
if (field.localized) {
|
||||
blockTypes.push(flexibleLocaleObjectType);
|
||||
return { type: flexibleLocaleObjectType };
|
||||
}
|
||||
|
||||
return flexibleType;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -232,9 +224,9 @@ function getBuildObjectType(context) {
|
||||
objectSchema.resolve = resolver;
|
||||
}
|
||||
|
||||
const blockType = new GraphQLObjectType(objectSchema);
|
||||
const newlyCreatedBlockType = new GraphQLObjectType(objectSchema);
|
||||
|
||||
return blockType;
|
||||
return newlyCreatedBlockType;
|
||||
};
|
||||
|
||||
return buildObjectType;
|
||||
|
||||
34
src/graphql/types/getBuildLocaleCustomType.js
Normal file
34
src/graphql/types/getBuildLocaleCustomType.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const { GraphQLScalarType } = require('graphql');
|
||||
const combineParentName = require('../utilities/combineParentName');
|
||||
|
||||
module.exports = (context) => {
|
||||
return (field, type, parent) => {
|
||||
const fullName = combineParentName(parent, field.label);
|
||||
|
||||
const coerceType = (value) => {
|
||||
const isLocaleObject = context.checkIfLocaleObject(value);
|
||||
|
||||
if (isLocaleObject) {
|
||||
// const allKeysValid = Object.values(value).every(locale => isValidJSValue(locale, type));
|
||||
|
||||
// if (allKeysValid) {
|
||||
return value;
|
||||
// }
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
// throw new Error(`${fullName}LocaleType can only represent an object containing locales or a matchiing ${fullName} type.`);
|
||||
};
|
||||
|
||||
const LocaleCustomType = new GraphQLScalarType({
|
||||
name: `${fullName}LocaleType`,
|
||||
description: `Handles locale values that can either be an object containing locales or a matching ${fullName} type.`,
|
||||
serialize: coerceType,
|
||||
parseValue: coerceType,
|
||||
parseLiteral: ast => ast.value,
|
||||
});
|
||||
|
||||
return LocaleCustomType;
|
||||
};
|
||||
};
|
||||
@@ -1,29 +0,0 @@
|
||||
const { GraphQLScalarType } = require('graphql');
|
||||
const getIsLocaleObject = require('../utilities/getIsLocaleObject');
|
||||
const combineParentName = require('../utilities/combineParentName');
|
||||
|
||||
module.exports = (config) => {
|
||||
return (field, type, parent) => {
|
||||
const fullName = combineParentName(parent, field.label);
|
||||
|
||||
const coerceType = (value) => {
|
||||
const isLocaleObject = getIsLocaleObject(config, value);
|
||||
|
||||
if (value instanceof type || isLocaleObject) {
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new Error(`LocaleFloatType can only represent an object containing locales or ${fullName} properties.`);
|
||||
};
|
||||
|
||||
const LocaleObjectType = new GraphQLScalarType({
|
||||
name: `${fullName}LocaleType`,
|
||||
description: `Handles locale values that can either be an object containing all locales or an object containing ${fullName} properties.`,
|
||||
serialize: coerceType,
|
||||
parseValue: coerceType,
|
||||
parseLiteral: ast => ast.value,
|
||||
});
|
||||
|
||||
return LocaleObjectType;
|
||||
};
|
||||
};
|
||||
23
src/graphql/types/getLocaleBooleanType.js
Normal file
23
src/graphql/types/getLocaleBooleanType.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const { GraphQLScalarType } = require('graphql');
|
||||
|
||||
module.exports = (context) => {
|
||||
const coerceType = (value) => {
|
||||
const isLocaleObject = context.checkIfLocaleObject(value);
|
||||
|
||||
if (typeof value === 'boolean' || isLocaleObject) {
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new Error('LocaleBooleanType can only represent a boolean or an object containing all locales.');
|
||||
};
|
||||
|
||||
const LocaleBooleanType = new GraphQLScalarType({
|
||||
name: 'LocaleBooleanType',
|
||||
description: 'Handles locale values that can either be an object containing all locales or a boolean of a single locale.',
|
||||
serialize: coerceType,
|
||||
parseValue: coerceType,
|
||||
parseLiteral: ast => ast.value,
|
||||
});
|
||||
|
||||
return LocaleBooleanType;
|
||||
};
|
||||
@@ -1,25 +1,23 @@
|
||||
const { GraphQLScalarType } = require('graphql');
|
||||
const getIsLocaleObject = require('../utilities/getIsLocaleObject');
|
||||
|
||||
module.exports = (localization) => {
|
||||
module.exports = (context) => {
|
||||
const coerceType = (value) => {
|
||||
const isLocaleObject = getIsLocaleObject(localization, value);
|
||||
const isLocaleObject = context.checkIfLocaleObject(value);
|
||||
|
||||
if (typeof value === 'number'
|
||||
|| isLocaleObject) {
|
||||
if (typeof value === 'number' || isLocaleObject) {
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new Error('LocaleFloatType can only represent a float or an object containing all locales.');
|
||||
};
|
||||
|
||||
const LocaleString = new GraphQLScalarType({
|
||||
name: 'LocaleType',
|
||||
const LocaleFloatType = new GraphQLScalarType({
|
||||
name: 'LocaleFloatType',
|
||||
description: 'Handles locale values that can either be an object containing all locales or a float of a single locale.',
|
||||
serialize: coerceType,
|
||||
parseValue: coerceType,
|
||||
parseLiteral: ast => ast.value,
|
||||
});
|
||||
|
||||
return LocaleString;
|
||||
return LocaleFloatType;
|
||||
};
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
const { GraphQLScalarType } = require('graphql');
|
||||
const getIsLocaleObject = require('../utilities/getIsLocaleObject');
|
||||
|
||||
module.exports = (localization) => {
|
||||
module.exports = (context) => {
|
||||
const coerceType = (value) => {
|
||||
const isLocaleObject = getIsLocaleObject(localization, value);
|
||||
const isLocaleObject = context.checkIfLocaleObject(value);
|
||||
|
||||
if (typeof value === 'string'
|
||||
|| isLocaleObject) {
|
||||
if (typeof value === 'string' || isLocaleObject) {
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new Error('LocaleString can only represent a string or an object containing all locales.');
|
||||
};
|
||||
|
||||
const LocaleString = new GraphQLScalarType({
|
||||
name: 'LocaleType',
|
||||
const LocaleStringType = new GraphQLScalarType({
|
||||
name: 'LocaleStringType',
|
||||
description: 'Handles locale values that can either be an object containing all locales or a string of a single locale.',
|
||||
serialize: coerceType,
|
||||
parseValue: coerceType,
|
||||
parseLiteral: ast => ast.value,
|
||||
});
|
||||
|
||||
return LocaleString;
|
||||
return LocaleStringType;
|
||||
};
|
||||
|
||||
6
src/graphql/utilities/getCheckIfLocaleObject.js
Normal file
6
src/graphql/utilities/getCheckIfLocaleObject.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = (localization) => {
|
||||
return (value) => {
|
||||
return typeof value === 'object'
|
||||
&& Object.keys(value).some(key => localization.locales.indexOf(key) > -1);
|
||||
};
|
||||
};
|
||||
@@ -1,4 +0,0 @@
|
||||
module.exports = (localization, value) => {
|
||||
return typeof value === 'object'
|
||||
&& Object.keys(value).every(key => localization.locales.indexOf(key) > -1);
|
||||
};
|
||||
Reference in New Issue
Block a user