Commit 3d3a0bcd authored by aleclofabbro's avatar aleclofabbro
Browse files

funziona !

parent 68cdbf0f
import { inspect } from 'util' import { inspect } from 'util'
import { typeInfo } from '../helpers/info'
import { DirectiveResolvers } from '../types' import { DirectiveResolvers } from '../types'
export const graphEntry: DirectiveResolvers['graphEntry'] = async ( export const graphEntry: DirectiveResolvers['graphEntry'] = async (
...@@ -8,10 +9,10 @@ export const graphEntry: DirectiveResolvers['graphEntry'] = async ( ...@@ -8,10 +9,10 @@ export const graphEntry: DirectiveResolvers['graphEntry'] = async (
context, context,
info info
) => { ) => {
const { returnType } = info // const { returnType } = info
context.skipNonNullValueChecks = true context.skipNonNullValueChecks = true
context.currStages = [{ match: { __typename: 'User' } }] // context.currStages = [{ match: { __typename: 'User' } }]
context.stages = context.currStages // context.stages = context.currStages
const result = await next() const result = await next()
......
import {
GraphQLOutputType,
GraphQLObjectType,
GraphQLScalarType,
GraphQLList,
GraphQLNonNull,
GraphQLUnionType,
} from 'graphql'
export const typeInfo = (
_: GraphQLOutputType,
isList = false,
isNullable = true
): { objs: (GraphQLObjectType | GraphQLScalarType)[]; isList: boolean; isNullable: boolean } => {
let name: string
if (_ instanceof GraphQLObjectType || _ instanceof GraphQLScalarType) {
return {
objs: [_],
isList,
isNullable,
}
} else if (_ instanceof GraphQLList) {
return typeInfo(_.ofType, true, isNullable)
} else if (_ instanceof GraphQLNonNull) {
return typeInfo(_.ofType, isList, false)
} else if (_ instanceof GraphQLUnionType) {
const objs = _.getTypes()
return {
objs,
isList,
isNullable,
}
} else {
console.error(_)
throw new Error(`can't typeInfo on ${_.name}`)
}
}
...@@ -5,11 +5,11 @@ import { applyMiddleware } from 'graphql-middleware' ...@@ -5,11 +5,11 @@ import { applyMiddleware } from 'graphql-middleware'
import { resolvers } from './resolvers' import { resolvers } from './resolvers'
import { directiveResolvers } from './directives' import { directiveResolvers } from './directives'
import { middlewares } from './middlewares' import { middlewares } from './middlewares'
import { GraphQuery } from '../mongo/types'
export type Context = { export type Context = {
skipNonNullValueChecks?: boolean skipNonNullValueChecks?: boolean
stages?: any[] $graph?: GraphQuery
currStages?: any[]
} }
export type RootValue = {} export type RootValue = {}
......
...@@ -11,12 +11,23 @@ type BaseQueryType<QN extends keyof QueryType> = Exclude< ...@@ -11,12 +11,23 @@ type BaseQueryType<QN extends keyof QueryType> = Exclude<
null | undefined | void null | undefined | void
> >
function defaultGraphEntry< function defaultGraphEntry<
QN extends keyof QueryType, QN extends Exclude<keyof QueryType, '__typename'>,
T extends { __typename: string } = BaseQueryType<QN> & { __typename: string } T extends { __typename: string } = BaseQueryType<QN> & { __typename: string }
>(__typename: T['__typename']) { >(__typename: T['__typename']) {
return (/* parent, args, context, info */) => { const resolverFn: QueryResolvers[QN] = (parent, args, context, info) => {
context.$graph = {
q: {
__typename,
$limit: 10,
$project: [],
$match: [],
$lookup: [],
},
}
return { return {
__typename, __typename,
} as any } as any
} }
return resolverFn
} }
import { GraphQLFieldResolver } from 'graphql' import {
GraphQLFieldResolver,
GraphQLList,
GraphQLNonNull,
GraphQLObjectType,
GraphQLOutputType,
GraphQLScalarType,
GraphQLUnionType,
} from 'graphql'
import { Context } from '../..'
import { getParent } from '../../../mongo/helpers/graphQuery'
import { typeInfo } from '../../helpers/info'
import { ResolverFn, Resolvers, TypeResolveFn } from '../../types' import { ResolverFn, Resolvers, TypeResolveFn } from '../../types'
export const Types = { export const Types = {
User: { User: {
...@@ -13,29 +24,40 @@ export const Types = { ...@@ -13,29 +24,40 @@ export const Types = {
}, },
} }
function defaultFieldResolver(): ResolverFn<any, any, any, any> { function defaultFieldResolver(): ResolverFn<any, any, Context, any> {
return (parent, args, context, { fieldName, parentType }) => { return (parent, args, context, info) => {
// console.log('defaultFieldResolver', parent, parentType.name, fieldName) const { fieldName, parentType, returnType } = info
const base = { if (!context.$graph) {
_fieldName: fieldName, throw new Error(`defaultFieldResolver no context.$graph`)
_args: args,
} }
if (parent._types) { const { isList, isNullable, objs } = typeInfo(returnType)
parent._types[fieldName] = base
console.log(`defaultFieldResolver `, parent, parentType.name, fieldName)
const parentQ = getParent(info, context)
if (!parentQ) {
throw new Error('defaultFieldResolver no parentQ')
} }
if (['_rel', '_subj', '_obj'].includes(fieldName)) { if (['_rel', '_subj', '_obj'].includes(fieldName)) {
const isRel = '_rel' === fieldName const isRel = '_rel' === fieldName
const __typename = isRel ? 'Knows' : 'User'
parentQ.$lookup.push({
$limit: 10,
$lookup: [],
$match: [],
$project: [],
__typename,
as: `${info.path.key}`,
})
const obj = { const obj = {
...base, __typename,
_types: {},
_stages: [],
__typename: isRel ? 'Knows' : 'User',
} }
context.currStages.push(obj)
context.currStages = obj._stages
return isRel ? [obj] : obj return isRel ? [obj] : obj
} else { } else {
context.currStages.push(base) parentQ.$match.push({ [fieldName]: args })
return null return null
} }
} }
......
...@@ -16,7 +16,8 @@ export const start = ({ httpPort, schema }: Cfg) => { ...@@ -16,7 +16,8 @@ export const start = ({ httpPort, schema }: Cfg) => {
} }
const formatResponse: GraphQLServerOptions['formatResponse'] = (response, context) => { const formatResponse: GraphQLServerOptions['formatResponse'] = (response, context) => {
console.log('formatResponse response', inspect(context.context.stages, true, 8, true)) console.log('formatResponse response', inspect(response, true, 8, true))
console.log('formatResponse q', inspect(context.context.$graph, true, 8, true))
return response || {} return response || {}
} }
// const executor: GraphQLServerOptions['executor'] = async (requestContext) => { // const executor: GraphQLServerOptions['executor'] = async (requestContext) => {
......
import { GraphQLResolveInfo } from 'graphql'
import { Path } from 'graphql/jsutils/Path'
import { ObjectID } from 'mongodb'
import { Context } from '../../gql'
import { GqlNode, MongoNode } from '../types'
export const getParent = (info: GraphQLResolveInfo, context: Context) => {
if (!context.$graph) {
return null
}
const root = context.$graph.q
const revPath = headlessReversePath(info.path)
console.log(revPath)
const found = revPath.reduce((curr, key) => {
return curr.$lookup.find((l) => l.as === key)! //BEWARE the !
}, root)
return found
}
const headlessReversePath = (_path: Path) => {
let path: Path | undefined = _path
const result = []
while ((path = path.prev)) {
'string' === typeof path.key && result.unshift(path.key)
}
result.shift()
return result
}
import { ObjectID } from 'mongodb' import { ObjectID } from 'mongodb'
// Types
export type GqlType = { _id: string; __typename: string } export type GqlType = { _id: string; __typename: string }
export type GqlNode = GqlType & { _rel: any[] } export type GqlNode = GqlType & { _rel: any[] }
export type GqlRelation = GqlType & { _obj: any; _subj: any } export type GqlRelation = GqlType & { _obj: any; _subj: any }
...@@ -9,3 +11,26 @@ export type MongoRelation<T extends GqlRelation> = Omit<T, '_id' | '_subj' | '_o ...@@ -9,3 +11,26 @@ export type MongoRelation<T extends GqlRelation> = Omit<T, '_id' | '_subj' | '_o
_obj: ObjectID _obj: ObjectID
_subj: ObjectID _subj: ObjectID
} }
// GraphQuery
export type GraphQuery = {
q: GraphQueryObj
}
export type GraphQueryObj = {
__typename: string
$match: Match[]
$limit: Limit
$project: Alias[]
$lookup: Lookup[]
}
export type Lookup = GraphQueryObj & {
as: string
}
export type Alias = {
field: string
as: string
}
export type Match = any
export type Limit = any
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment