UNPKG

@grapi/server

Version:

Grapi Schema Generator For GraphQL Server

177 lines (176 loc) 7.87 kB
"use strict"; 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;