@grapi/server
Version:
Grapi Schema Generator For GraphQL Server
177 lines (176 loc) • 7.87 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = exports.createDataModelFromSdlObjectType = exports.createDataFieldFromSdlField = exports.parseDataModelScalarType = void 0;
const graphql_1 = require("graphql");
const constants_1 = require("./constants");
const dataModel_1 = require("./dataModel");
const type_1 = require("./dataModel/type");
const lodash_1 = require("./lodash");
const rootNode_1 = __importDefault(require("./rootNode"));
const interface_1 = require("./sdlParser/field/interface");
const middlewares_1 = require("./sdlParser/middlewares");
const namedType_1 = require("./sdlParser/namedType");
const parser_1 = require("./sdlParser/parser");
const isGrapiDataModel = (sdlNamedType) => {
return Boolean((sdlNamedType.getDirectives() || {})[constants_1.MODEL_DIRECTIVE]);
};
const isRelationType = (sdlObjectType) => {
return Boolean(sdlObjectType.getInterfaces().find(interfaceName => interfaceName === constants_1.RELATION_INTERFACE_NAME));
};
const parseDataModelScalarType = (field) => {
const scalarTypes = {
[graphql_1.GraphQLString.name]: type_1.DataModelType.STRING,
[graphql_1.GraphQLInt.name]: type_1.DataModelType.INT,
[graphql_1.GraphQLFloat.name]: type_1.DataModelType.FLOAT,
[graphql_1.GraphQLBoolean.name]: type_1.DataModelType.BOOLEAN,
[graphql_1.GraphQLID.name]: type_1.DataModelType.ID
};
const scalarType = scalarTypes[field.getTypeName()];
if (!scalarTypes) {
throw new Error(`cant parse dataModel type for field type: ${field.getTypeName()}`);
}
return scalarType;
};
exports.parseDataModelScalarType = parseDataModelScalarType;
const createDataFieldFromSdlField = (field, getModel, getNamedType, getRelationConfig) => {
const fieldMeta = {
nonNull: field.isNonNull(),
list: field.isList(),
nonNullItem: field.isItemNonNull(),
};
const sdlFieldTypes = {
[interface_1.SdlFieldType.SCALAR]: () => {
return new dataModel_1.ScalarField({
type: (0, exports.parseDataModelScalarType)(field),
...fieldMeta,
});
},
[interface_1.SdlFieldType.CUSTOM_SCALAR]: () => {
return new dataModel_1.CustomScalarField({
typename: field.getTypeName(),
...fieldMeta,
});
},
[interface_1.SdlFieldType.ENUM]: () => {
return new dataModel_1.EnumField({
enumType: () => getNamedType(field.getTypeName()),
...fieldMeta,
});
},
[interface_1.SdlFieldType.OBJECT]: () => {
const objectField = field;
if (isGrapiDataModel(objectField.getObjectType())) {
const relationWith = (0, lodash_1.get)(objectField.getDirective(constants_1.RELATION_DIRECTIVE_NAME), `${constants_1.RELATION_ARGS}.${constants_1.RELATION_WITH}.${constants_1.RELATION_VALUE}`);
const relationConfig = (0, lodash_1.mapValues)(getRelationConfig(relationWith), (value) => {
if (value instanceof Object) {
return (0, lodash_1.mapValues)(value, (data) => {
return (0, lodash_1.get)(data, `value`, data);
});
}
return value;
});
return new dataModel_1.RelationField({
relationTo: () => getModel(objectField.getTypeName()),
relationConfig: relationWith === undefined ? null : () => relationConfig,
...fieldMeta,
});
}
else {
return new dataModel_1.ObjectField({
objectType: () => getNamedType(field.getTypeName()),
...fieldMeta,
});
}
}
};
return sdlFieldTypes[field.getFieldType()]();
};
exports.createDataFieldFromSdlField = createDataFieldFromSdlField;
const parseRelationConfig = (sdlObjectType) => {
return (0, lodash_1.mapValues)((0, lodash_1.get)(sdlObjectType.getDirectives(), 'config.args'), (inputValue) => inputValue.getValue());
};
const createDataModelFromSdlObjectType = (sdlObjectType, getModel, getNamedType, getRelationConfig) => {
const model = new dataModel_1.Model({
name: sdlObjectType.getName(),
});
(0, lodash_1.forEach)(sdlObjectType.getFields(), (sdlField, key) => {
model.appendField(key, (0, exports.createDataFieldFromSdlField)(sdlField, getModel, getNamedType, getRelationConfig));
});
return model;
};
exports.createDataModelFromSdlObjectType = createDataModelFromSdlObjectType;
const parseSdlNameTypes = (sdlNamedTypes, models, rootNode) => {
const relationConfigMap = {};
const namedTypes = {};
const getModel = (name) => {
return models[name];
};
const getNamedType = (name) => {
return namedTypes[name];
};
const getRelationConfig = (name) => relationConfigMap[name];
sdlNamedTypes.forEach((sdlNamedType) => {
const name = sdlNamedType.getName();
if (sdlNamedType instanceof namedType_1.SdlDirectiveType) {
rootNode.addSdl((0, parser_1.parseDefinitionNodeToSdl)(sdlNamedType.getTypeDef()), false);
}
if (sdlNamedType instanceof namedType_1.SdlEnumType) {
const enumType = new dataModel_1.EnumType({
name,
values: sdlNamedType.getValues(),
description: sdlNamedType.getDescription()
});
namedTypes[name] = enumType;
rootNode.addEnum(enumType);
}
const isSdlObjectType = sdlNamedType instanceof namedType_1.SdlObjectType;
const isModel = isGrapiDataModel(sdlNamedType);
const isRelation = isSdlObjectType && isRelationType(sdlNamedType);
if (isSdlObjectType && !isModel && !isRelation) {
namedTypes[name] = new dataModel_1.ObjectType({
name,
fields: (0, lodash_1.mapValues)(sdlNamedType.getFields(), sdlField => {
return (0, exports.createDataFieldFromSdlField)(sdlField, getModel, getNamedType, getRelationConfig);
}),
});
}
if (isSdlObjectType && isModel) {
models[name] = (0, exports.createDataModelFromSdlObjectType)(sdlNamedType, getModel, getNamedType, getRelationConfig);
}
if (isSdlObjectType && isRelation) {
relationConfigMap[name] = parseRelationConfig(sdlNamedType);
}
});
};
const parse = (sdl) => {
const parser = new parser_1.SdlParser();
const sdlNamedTypes = parser.parse(sdl);
const rootNode = new rootNode_1.default();
const models = {};
parseSdlNameTypes(sdlNamedTypes, models, rootNode);
const middlewares = [
new middlewares_1.BasicFieldMiddware(),
new middlewares_1.MetadataMiddleware(),
];
(0, lodash_1.forEach)(models, (model, key) => {
const sdlObjectType = parser.getSdlNamedType(key);
middlewares.forEach(middleware => middleware.visitGrapiDataModel && middleware.visitGrapiDataModel({
model,
sdlObjectType,
}));
(0, lodash_1.forEach)(model.getFields(), (dataModelField, name) => {
const sdlField = sdlObjectType.getField(name);
middlewares.forEach(mid => mid.visitField && mid.visitField({
model,
field: dataModelField,
sdlObjectType,
sdlField,
}));
});
});
return { rootNode, models: (0, lodash_1.values)(models) };
};
exports.parse = parse;