import { ModelDefinition, getPrimaryKey } from "@graphback/core"; import { isNonNullType, GraphQLOutputType, getNullableType } from "graphql"; import { convertToTsType } from "../utils"; const getFieldParameters = (fieldName: string, type: GraphQLOutputType): any => { const options: any = {}; options.key = fieldName; if (isNonNullType(type)) { type = getNullableType(type); options.isRequired = true; } return { type: convertToTsType(type), ...options }; }; const getModelProperties = (model: ModelDefinition, primaryKey: string) => { const fieldMap = model.graphqlType.getFields(); const keys = Object.keys(fieldMap); // get a list of relationships const relNames = model.relationships.map(r => r.ownerField.name); // loop through graphback relationship types const relationships = model.relationships // filter out oneToMany relationships .filter(r => r.kind !== "oneToMany") // generate key/value pair with foreign key as key .map(r => { const fieldOptions = getFieldParameters( r.relationForeignKey!, r.relationType ); fieldOptions.relationship = r.relationType; return { [r.relationForeignKey!]: fieldOptions }; }); const generatedProperties = keys // filter out autogenerated relationship properties .filter(fieldName => !relNames.includes(fieldName)) .map(fieldName => { const fieldOptions = getFieldParameters( fieldName, fieldMap[fieldName].type ); if (fieldName === primaryKey) { fieldOptions.primary = true; } return { [fieldName]: fieldOptions }; }) // add previously created relationship key/values .concat(relationships) .reduce((prev, current) => ({ ...prev, ...current }), {}); generatedProperties._version = { type: "string", key: "_version", isRequired: true }; generatedProperties._lastUpdatedAt = { type: "number", key: "_lastUpdatedAt", isRequired: true }; return generatedProperties; }; export const createJsonSchema = (model: ModelDefinition) => { const primaryKey = getPrimaryKey(model.graphqlType).name; return { name: model.graphqlType.name, version: 1, type: "object", primaryKey: primaryKey, properties: getModelProperties(model, primaryKey) }; };