import { SchemaDirectiveVisitor } from 'graphql-tools' ; import { GraphQLSchema , GraphQLObjectType , GraphQLField , GraphQLDirective , DirectiveLocation , GraphQLString , GraphQLBoolean , } from 'graphql' ; import { addTable , addColumn , ITable , IColumn } from './makeSqlSchema' ; export interface IGetSchemaDirectivesInput { directiveName ? : string ; } export interface IGetSchemaDirectivesOutput { [ directiveName ] : typeof SchemaDirectiveVisitor ; } export function getSchemaDirectives ( { directiveName = 'sql' , } = { } ) { class SqlDirective extends SchemaDirectiveVisitor { public static getDirectiveDeclaration ( name , schema ) { return new GraphQLDirective ( { name , locations : [ DirectiveLocation . OBJECT , DirectiveLocation . FIELD_DEFINITION , ] , args : { unicode : { type : GraphQLBoolean , } , constraints : { type : GraphQLString , } , auto : { type : GraphQLBoolean , } , default : { type : GraphQLString , } , hide : { type : GraphQLBoolean , } , index : { type : GraphQLBoolean , } , nullable : { type : GraphQLBoolean , } , primary : { type : GraphQLBoolean , } , type : { type : GraphQLString , } , unique : { type : GraphQLBoolean , } , generated : { type : GraphQLString , } , } , } ) ; } public visitObject ( object ) { const tableName = object . name ; const sqlTable = { name : tableName , columns : { } , ... this . args , } ; addTable ( sqlTable ) ; } public visitFieldDefinition ( field , details ) { if ( ! this . args . hide ) { const tableName = details . objectType . name ; const columnName = field . name ; const sqlColumn = { name : columnName , graphQLType : field . type . toString ( ) , ... this . args , } ; addColumn ( tableName , sqlColumn ) ; } } } return { [ directiveName ] : SqlDirective , } ; } export function customDirectiveDeclaration ( customDirectiveName ) { return `directive @${ customDirectiveName }(
    unicode: Boolean
    auto: Boolean
    default: String
    hide: Boolean
    index: Boolean
    nullable: Boolean
    primary: Boolean
    type: String
    unique: Boolean
    generated: String
  ) on OBJECT | FIELD_DEFINITION` ; } export const sqlDirectiveDeclaration = customDirectiveDeclaration ( 'sql' ) ;