Skip to content

Commit

Permalink
Switch to using GraphQL 15's extensions for join-monster config in a …
Browse files Browse the repository at this point in the history
…schema

GraphQL 15 doesn't let schema authors attach arbitrary properties to schema objects anymore, so join-monster's config style has to change. There's an `extensions` property that works great for this, let's use that!
  • Loading branch information
airhorns committed Jun 19, 2020
1 parent 7d4e7fb commit 6a410e9
Show file tree
Hide file tree
Showing 21 changed files with 1,313 additions and 862 deletions.
17 changes: 4 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
},
"homepage": "https://github.com/join-monster/join-monster#readme",
"peerDependencies": {
"graphql": "0.6 || 0.7 || 0.8 || 0.9 || 0.10 || 0.11 || 0.12 || 0.13"
"graphql": "15"
},
"devDependencies": {
"@ava/babel": "^1.0.1",
Expand All @@ -93,7 +93,7 @@
"eslint-config-airbnb-base": "^14.1.0",
"eslint-config-prettier": "^6.11.0",
"faker": "^4.1.0",
"graphql": "^0.13.0",
"graphql": "^15.1.0",
"graphsiql": "0.2.0",
"idx": "^2.5.6",
"jsdoc-to-markdown": "^5.0.0",
Expand Down
151 changes: 101 additions & 50 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,139 @@

import * as graphql from 'graphql'
export type Maybe<T> = null | undefined | T

// Extend graphql objects and fields

declare module 'graphql/type/definition' {
type SqlJoin<TContext, TArgs> = (table1: string, table2: string, args: TArgs, context: TContext, sqlASTNode: any) => string
type Where<TContext, TArgs> = (usersTable: string, args: TArgs, context: TContext, sqlASTNode: any) => string | void
type SqlJoin<TContext, TArgs> = (
table1: string,
table2: string,
args: TArgs,
context: TContext,
sqlASTNode: any
) => string
type Where<TContext, TArgs> = (
usersTable: string,
args: TArgs,
context: TContext,
sqlASTNode: any
) => string | void
type Order = 'ASC' | 'asc' | 'DESC' | 'desc'
type OrderBy = string | { [key: string]: Order }
type ThunkWithArgsCtx<T, TContext, TArgs> = ((args: TArgs, context: TContext) => T) | T;
type ThunkWithArgsCtx<T, TContext, TArgs> =
| ((args: TArgs, context: TContext) => T)
| T

export interface GraphQLObjectTypeConfig<TSource, TContext> {
alwaysFetch?: string
sqlTable?: ThunkWithArgsCtx<string, any, TContext>
uniqueKey?: string | string[]
extensions?: Maybe<Readonly<Record<string, any>>> & {
alwaysFetch?: string
sqlTable?: ThunkWithArgsCtx<string, any, TContext>
uniqueKey?: string | string[]
}
}

export interface GraphQLFieldConfig<TSource, TContext, TArgs> {
jmIgnoreAll?: boolean
jmIgnoreTable?: boolean
junction?: {
include?: ThunkWithArgsCtx<{
sqlColumn?: string
sqlExpr?: string
sqlDeps?: string | string[]
}, TContext, TArgs>
extensions?: Maybe<Readonly<Record<string, any>>> & {
ignoreAll?: boolean
ignoreTable?: boolean
junction?: {
include?: ThunkWithArgsCtx<
{
sqlColumn?: string
sqlExpr?: string
sqlDeps?: string | string[]
},
TContext,
TArgs
>
orderBy?: ThunkWithArgsCtx<OrderBy, TContext, TArgs>
sortKey?: ThunkWithArgsCtx<
{
order: Order
key: string | string[]
},
TContext,
TArgs
>
sqlBatch?: {
thisKey: string
parentKey: string
sqlJoin: SqlJoin<TContext, TArgs>
}
sqlJoins?: [SqlJoin<TContext, TArgs>, SqlJoin<TContext, TArgs>]
sqlTable: ThunkWithArgsCtx<string, TContext, TArgs>
uniqueKey?: string | string[]
where?: Where<TContext, TArgs>
}
limit?: ThunkWithArgsCtx<number, any, TContext>
orderBy?: ThunkWithArgsCtx<OrderBy, TContext, TArgs>
sortKey?: ThunkWithArgsCtx<{
order: Order
key: string | string[]
}, TContext, TArgs>
sortKey?: ThunkWithArgsCtx<
{
order: Order
key: string | string[]
},
TContext,
TArgs
>
sqlBatch?: {
thisKey: string
parentKey: string
sqlJoin: SqlJoin<TContext, TArgs>
}
sqlJoins?: [SqlJoin<TContext, TArgs>, SqlJoin<TContext, TArgs>]
sqlTable: ThunkWithArgsCtx<string, TContext, TArgs>
uniqueKey?: string | string[]
sqlColumn?: string
sqlDeps?: string[]
sqlExpr?: (
table: string,
args: TArgs,
context: TContext,
sqlASTNode: any
) => string
sqlJoin?: SqlJoin<TContext, TArgs>
sqlPaginate?: boolean
where?: Where<TContext, TArgs>
}
limit?: ThunkWithArgsCtx<number, any, TContext>
orderBy?: ThunkWithArgsCtx<OrderBy, TContext, TArgs>
sortKey?: ThunkWithArgsCtx<{
order: Order
key: string | string[]
}, TContext, TArgs>
sqlBatch?: {
thisKey: string
parentKey: string
}
sqlColumn?: string
sqlDeps?: string[]
sqlExpr?: (table: string, args: TArgs, context: TContext, sqlASTNode: any) => string
sqlJoin?: SqlJoin<TContext, TArgs>
sqlPaginate?: boolean
where?: Where<TContext, TArgs>
}
}

export interface GraphQLUnionTypeConfig<TSource, TContext> {
sqlTable?: string
uniqueKey?: string | string[]
alwaysFetch?: string
extensions?: Maybe<Readonly<Record<string, any>>> & {
sqlTable?: string
uniqueKey?: string | string[]
alwaysFetch?: string
}
}

export interface GraphQLInterfaceTypeConfig<TSource, TContext> {
sqlTable?: string
uniqueKey?: string | string[]
alwaysFetch?: string
extensions: Maybe<Readonly<Record<string, any>>> & {
sqlTable?: string
uniqueKey?: string | string[]
alwaysFetch?: string
}
}

// JoinMonster lib interface

interface DialectModule { name: string }
interface DialectModule {
name: string
}

type Dialect = 'pg' | 'oracle' | 'mariadb' | 'mysql' | 'mysql8' | 'sqlite3'
type JoinMonsterOptions = { minify?: boolean, dialect?: Dialect, dialectModule?: DialectModule }
type JoinMonsterOptions = {
minify?: boolean
dialect?: Dialect
dialectModule?: DialectModule
}

type Rows = any
type DbCallCallback = (sql:string, done: (err?: any, rows?: Rows) => void) => void
type DbCallCallback = (
sql: string,
done: (err?: any, rows?: Rows) => void
) => void
type DbCallPromise = (sql: string) => Promise<Rows>
type DbCall = DbCallCallback | DbCallPromise

declare function joinMonster(resolveInfo: any, context: any, dbCall: DbCallCallback | DbCallPromise, options?: JoinMonsterOptions) : Promise<any>
declare function joinMonster(
resolveInfo: any,
context: any,
dbCall: DbCallCallback | DbCallPromise,
options?: JoinMonsterOptions
): Promise<any>

export default joinMonster
16 changes: 13 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import * as queryAST from './query-ast-to-sql-ast'
import arrToConnection from './array-to-connection'
import AliasNamespace from './alias-namespace'
import nextBatch from './batch-planner'
import { buildWhereFunction, handleUserDbCall, compileSqlAST } from './util'
import {
buildWhereFunction,
handleUserDbCall,
compileSqlAST,
getConfigFromSchemaObject
} from './util'

/* _ _ _ _
___ __ _| | | |__ __ _ ___| | __
Expand Down Expand Up @@ -135,7 +140,7 @@ async function getNode(
const type = resolveInfo.schema._typeMap[typeName]
assert(type, `Type "${typeName}" not found in your schema.`)
assert(
type._typeConfig.sqlTable,
getConfigFromSchemaObject(type).sqlTable,
`joinMonster can't fetch a ${typeName} as a Node unless it has "sqlTable" tagged.`
)

Expand All @@ -148,7 +153,12 @@ async function getNode(
node: {
type,
name: type.name.toLowerCase(),
where
args: {},
extensions: {
joinMonster: {
where
}
}
}
}
}
Expand Down

0 comments on commit 6a410e9

Please sign in to comment.