Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

[WIP] Implicit relationships #1873

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* eslint-disable max-lines */
import { GraphQLInputObjectType, GraphQLList, GraphQLBoolean, GraphQLInt, GraphQLString, GraphQLID, GraphQLEnumType, GraphQLObjectType, GraphQLNonNull, GraphQLField, getNamedType, isScalarType, GraphQLInputFieldMap, GraphQLScalarType, GraphQLNamedType, GraphQLInputField, isEnumType, isObjectType, isInputObjectType, GraphQLInputType, getNullableType } from "graphql";
import { GraphbackOperationType, getInputTypeName, getInputFieldName, getInputFieldTypeName, isOneToManyField, getPrimaryKey, metadataMap, ModelDefinition, GraphbackDateTime } from '@graphback/core';
import { GraphbackOperationType, getInputTypeName, copyWrappingType, getInputFieldName, getInputFieldTypeName, isOneToManyField, getPrimaryKey, metadataMap, ModelDefinition } from '@graphback/core';
import { SchemaComposer } from 'graphql-compose';
import { copyWrappingType } from './copyWrappingType';

const PageRequestTypeName = 'PageRequest';
const SortDirectionEnumName = 'SortDirectionEnum';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable max-lines */
import { readFileSync } from 'fs';
import { buildSchema, printSchema, GraphQLObjectType } from 'graphql';
import { GraphbackCoreMetadata, printSchemaWithDirectives, GraphbackPluginEngine } from '@graphback/core';
import { buildSchema, printSchema, GraphQLObjectType, GraphQLID } from 'graphql';
import { GraphbackCoreMetadata, printSchemaWithDirectives, GraphbackPluginEngine, ModelDefinition, FieldRelationshipMetadata } from '@graphback/core';
import { SchemaCRUDPlugin } from '../src/SchemaCRUDPlugin';

const schemaText = readFileSync(`${__dirname}/mock.graphql`, 'utf8')
Expand Down Expand Up @@ -112,74 +113,6 @@ test('Test one side relationship schema query type generation', async () => {
expect(printSchema(transformedSchema)).toMatchSnapshot()
});


test('Model has missing relationship annotations', async () => {
const defautConfig = {
"create": false,
"update": false,
"findOne": true,
"find": true,
"delete": false,
"subCreate": false,
"subUpdate": false,
"subDelete": false
};

let modelText = `
""" @model """
type Note {
id: ID!
tests: [Test]!
}

"""
@model
"""
type Test {
id: ID!
name: String
}
`;

let schema = buildSchema(modelText);
let schemaGenerator = new SchemaCRUDPlugin();
let metadata = new GraphbackCoreMetadata({ crudMethods: defautConfig }, schema);

try {
schemaGenerator.transformSchema(metadata);
expect(true).toBeFalsy(); // should not reach here
} catch (error) {
expect(error.message).toEqual(`Missing relationship definition on: "Note.tests". Visit https://graphback.dev/docs/model/datamodel#relationships to see how you can define relationship in your business model.`);
}

modelText = `
""" @model """
type Note {
id: ID!
test: Test
}

"""
@model
"""
type Test {
id: ID!
name: String
}
`;

schema = buildSchema(modelText);
schemaGenerator = new SchemaCRUDPlugin();
metadata = new GraphbackCoreMetadata({ crudMethods: defautConfig }, schema);

try {
schemaGenerator.transformSchema(metadata);
expect(true).toBeFalsy(); // should not reach here
} catch (error) {
expect(error.message).toEqual(`Missing relationship definition on: "Note.test". Visit https://graphback.dev/docs/model/datamodel#relationships to see how you can define relationship in your business model.`);
}
});

test('Non-model type has model-type field', () => {
const defautConfig = {
"create": true,
Expand Down Expand Up @@ -277,4 +210,4 @@ type Comment {
expect(note.astNode?.directives[0].name.value).toBe('test')

expect(printSchemaWithDirectives(schema)).toMatchSnapshot()
})
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GraphQLNonNull, GraphQLString, GraphQLBoolean, GraphQLList, GraphQLFloat, GraphQLInt, GraphQLObjectType } from 'graphql'
import { copyWrappingType } from '../src/definitions/copyWrappingType'
import { copyWrappingType } from '@graphback/core'

describe('copyWrappingType', () => {
test('Boolean should become Boolean!', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/graphback-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export * from './annotations/DefaultValueAnnotation';
export * from './utils/printSchemaWithDirectives';
export * from './utils/metadataAnnotations';
export * from './utils/fieldTransformHelpers';
export * from './utils/copyWrappingType';

export * from './runtime';
export * from './db';
Expand Down
22 changes: 16 additions & 6 deletions packages/graphback-core/src/plugin/GraphbackCoreMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,24 @@ export class GraphbackCoreMetadata {
//Get actual user types
const modelTypes = this.getGraphQLTypesWithModel();

const relationshipBuilder = new RelationshipMetadataBuilder(modelTypes);
relationshipBuilder.build();

for (const modelType of modelTypes) {
const model = this.buildModel(modelType, relationshipBuilder.getModelRelationships(modelType.name));
const model = this.buildModel(modelType);
this.models.push(model);
}

const relationshipBuilder = new RelationshipMetadataBuilder(this.models);
const meta = relationshipBuilder.build()

for (const model of this.models) {
const modelRelationshipMetadata = meta[model.graphqlType.name]
if (modelRelationshipMetadata) {
const modelFieldRelationshipMetadata = Object.values(modelRelationshipMetadata)
if (modelFieldRelationshipMetadata) {
model.relationships.push(...modelFieldRelationshipMetadata)
}
}
}

return this.models;
}

Expand All @@ -90,7 +100,7 @@ export class GraphbackCoreMetadata {
return types.filter((modelType: GraphQLObjectType) => parseMetadata('model', modelType))
}

private buildModel(modelType: GraphQLObjectType, relationships: FieldRelationshipMetadata[]): ModelDefinition {
private buildModel(modelType: GraphQLObjectType): ModelDefinition {
let crudOptions = parseMetadata('model', modelType)
//Merge CRUD options from type with global ones
crudOptions = Object.assign({}, this.supportedCrudMethods, crudOptions)
Expand All @@ -99,7 +109,7 @@ export class GraphbackCoreMetadata {
const primaryKeyField = getPrimaryKey(modelType);

return {
relationships,
relationships: [],
crudOptions,
graphqlType: modelType,
config: { deltaSync },
Expand Down
Loading