diff --git a/src/index.ts b/src/index.ts index e4b9913..8d1b874 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,14 +5,15 @@ import { buildSchema, printSchema } from './schema' type GraphQLRootType = 'Query' | 'Mutation' | 'Subscription' type GarphType = 'String' | 'Int' | 'Float' | 'Boolean' | 'ID' | 'ObjectType' | 'InterfaceType' | 'InputType' | 'Scalar' | 'Enum' | 'List' | 'PaginatedList' | 'Union' | 'Ref' | 'Internal' | 'Optional' | 'Args' | 'OmitResolver' -export abstract class Type { +export abstract class Type { _name?: string - _is: X + _is: TId _inner?: any _output?: any _args?: Args - _shape: T - typeDef: TypeDefinition + _shape: TShape + _internal: TInternal + typeDef: TypeDefinition description(text: string) { this.typeDef.description = text @@ -25,6 +26,7 @@ export abstract class Type { } } + export type TypeDefinition = { name?: string type: GarphType @@ -37,10 +39,11 @@ export type TypeDefinition = { scalarOptions?: ScalarOptions defaultValue?: any interfaces?: AnyInterface[] - extend?: AnyTypes[] + extend?: AnyExposedTypes[] } -export type AnyType = Type +export type AnyType = Type +export type AnyExposedType = AnyType export type AnyString = Type export type AnyID = Type export type AnyBoolean = Type @@ -48,7 +51,7 @@ export type AnyNumber = Type export type AnyInt = Type export type AnyFloat = Type export type AnyRef = Type -export type AnyInternal = Type +export type AnyInternal = Type export type AnyList = Type export type AnyPaginatedList = Type export type AnyUnion = Type @@ -62,13 +65,15 @@ export type AnyObject = Type export type AnyOmitResolver = Type export type Args = { - [key: string]: AnyType + [key: string]: AnyExposedType } -export type AnyTypes = { - [key: string]: AnyType +export type AnyTypes = { + [key: string]: AnyType } +export type AnyExposedTypes = AnyTypes + export type AnyObjects = { [key: string]: AnyObject } @@ -88,10 +93,11 @@ type InferOptions = { omitResolver?: AnyOmitResolver | never } -type RefType = () => AnyType +type RefType = () => AnyExposedType // TODO: Refactor Args to get rid of this mess export type Infer = ExpandRecursively> + export type InferRaw = T extends AnyInput | AnyObject | AnyInterface ? { __typename?: T['_name'] } & { @@ -119,21 +125,21 @@ export type InferShallow = ExpandRecursively> -export type InferArgsRaw = T extends AnyObject | AnyInterface ? { +export type InferArgs = ExpandRecursively> +export type InferArgsRaw = T extends AnyObject | AnyInterface ? { [K in keyof T['_shape']]: InferArgRaw } : never export type InferArg = ExpandRecursively> export type InferArgRaw = T extends AnyArgs ? { - [K in keyof T['_args'] as T['_args'][K] extends AnyOptional ? never : K]: InferRaw + [K in keyof T['_args']as T['_args'][K] extends AnyOptional ? never : K]: InferRaw } & { - [K in keyof T['_args'] as T['_args'][K] extends AnyOptional ? K : never]?: InferRaw -}: never + [K in keyof T['_args']as T['_args'][K] extends AnyOptional ? K : never]?: InferRaw + } : never export type InferUnionNames = T extends AnyUnion ? ObjectToUnion['_name'] : never -export type InferResolvers = { +export type InferResolvers = { [K in keyof T]: K extends 'Subscription' ? { [G in keyof T[K]['_shape']]?: { subscribe: (parent: {}, args: InferArg, context: X['context'], info: GraphQLResolveInfo) => MaybePromise }>> @@ -145,9 +151,9 @@ export type InferResolvers = [G in keyof T[K]['_shape']]?: { resolve: (parent: K extends GraphQLRootType ? {} : Infer, args: InferArg, context: X['context'], info: GraphQLResolveInfo) => MaybePromise> | AsyncGenerator> } | { - load: (queries: { parent: K extends GraphQLRootType ? {} : Infer, args: InferArg, context: X['context'], info: GraphQLResolveInfo } []) => MaybePromise[]> + load: (queries: { parent: K extends GraphQLRootType ? {} : Infer, args: InferArg, context: X['context'], info: GraphQLResolveInfo }[]) => MaybePromise[]> } | { - loadBatch: (queries: { parent: K extends GraphQLRootType ? {} : Infer, args: InferArg, context: X['context'], info: GraphQLResolveInfo } []) => MaybePromise[]> + loadBatch: (queries: { parent: K extends GraphQLRootType ? {} : Infer, args: InferArg, context: X['context'], info: GraphQLResolveInfo }[]) => MaybePromise[]> } } & { __isTypeOf?: (parent: Infer, context: X['context'], info: GraphQLResolveInfo) => MaybePromise @@ -155,7 +161,7 @@ export type InferResolvers = } } -export type InferResolversStrict = { +export type InferResolversStrict = { [K in keyof T]: K extends 'Subscription' ? { [G in keyof T[K]['_shape']]: { subscribe: (parent: {}, args: InferArg, context: X['context'], info: GraphQLResolveInfo) => MaybePromise }>> @@ -167,9 +173,9 @@ export type InferResolversStrict, args: InferArg, context: X['context'], info: GraphQLResolveInfo) => MaybePromise> | AsyncGenerator> } | { - load: (queries: { parent: K extends GraphQLRootType ? {} : Infer, args: InferArg, context: X['context'], info: GraphQLResolveInfo } []) => MaybePromise>[] + load: (queries: { parent: K extends GraphQLRootType ? {} : Infer, args: InferArg, context: X['context'], info: GraphQLResolveInfo }[]) => MaybePromise>[] } | { - loadBatch: (queries: { parent: K extends GraphQLRootType ? {} : Infer, args: InferArg, context: X['context'], info: GraphQLResolveInfo } []) => MaybePromise>[] + loadBatch: (queries: { parent: K extends GraphQLRootType ? {} : Infer, args: InferArg, context: X['context'], info: GraphQLResolveInfo }[]) => MaybePromise>[] } } & { __isTypeOf?: (parent: Infer, context: X['context'], info: GraphQLResolveInfo) => MaybePromise @@ -180,7 +186,7 @@ export type InferResolversStrict extends Type { declare _name: N - constructor(name: string, shape: T, interfaces?: AnyInterface[], extend?: AnyTypes[]) { + constructor(name: string, shape: T, interfaces?: AnyInterface[], extend?: AnyExposedTypes[]) { super() this.typeDef = { name, @@ -197,17 +203,17 @@ class GType extends Type return new GType>(this.typeDef.name, this.typeDef.shape as any, Array.isArray(ref) ? ref : [ref], this.typeDef.extend) } - extend(ref: D | D[]) { + extend(ref: D | D[]) { // This is temporary construct, until we figure out how to properly manage to shared schema this.typeDef.extend = Array.isArray(ref) ? ref : [ref] return new GType>(this.typeDef.name, this.typeDef.shape as any, this.typeDef.interfaces, Array.isArray(ref) ? ref : [ref]) } } -class GInput extends Type { +class GInput extends Type { declare _name: N - constructor(name: string, shape: T, extend?: AnyTypes[]) { + constructor(name: string, shape: T, extend?: AnyExposedTypes[]) { super() this.typeDef = { name, @@ -217,17 +223,17 @@ class GInput extends Type } } - extend(ref: D | D[]) { + extend(ref: D | D[]) { // This is temporary construct, until we figure out how to properly manage to shared schema this.typeDef.extend = Array.isArray(ref) ? ref : [ref] return new GInput>(this.typeDef.name, this.typeDef.shape as any, Array.isArray(ref) ? ref : [ref]) } } -class GInterface extends Type { +class GInterface extends Type { declare _name: N - constructor(name: string, shape: T, interfaces?: AnyInterface[], extend?: AnyTypes[]) { + constructor(name: string, shape: T, interfaces?: AnyInterface[], extend?: AnyExposedTypes[]) { super() this.typeDef = { name, @@ -241,10 +247,10 @@ class GInterface extends Type(ref: D | D[]) { // This is temporary construct, until we figure out how to properly manage to shared schema this.typeDef.interfaces = Array.isArray(ref) ? ref : [ref] - return new GInterface>(this.typeDef.name, this.typeDef.shape as any, Array.isArray(ref) ? ref : [ref], this.typeDef.extend) + return new GInterface>(this.typeDef.name, this.typeDef.shape as any, Array.isArray(ref) ? ref : [ref], this.typeDef.extend) } - extend(ref: D | D[]) { + extend(ref: D | D[]) { // This is temporary construct, until we figure out how to properly manage to shared schema this.typeDef.extend = Array.isArray(ref) ? ref : [ref] return new GInterface>(this.typeDef.name, this.typeDef.shape as any, this.typeDef.interfaces, Array.isArray(ref) ? ref : [ref]) @@ -434,7 +440,7 @@ class GRef extends Type { } } -class GInternal extends Type { +class GInternal extends Type { constructor() { super() this.typeDef = { @@ -443,17 +449,13 @@ class GInternal extends Type { } optional() { - return new GOptional(this) + return new GOptionalBase(this); } required() { this.typeDef.isRequired = true return this } - - omitResolver () { - return new GOmitResolver(this) - } } class GScalar extends Type { @@ -497,7 +499,7 @@ class GList extends Type { return this } - omitResolver () { + omitResolver() { return new GOmitResolver(this) } @@ -510,7 +512,7 @@ class GList extends Type { } } -class GPaginatedList extends Type { +class GPaginatedList extends Type { declare _inner: { edges: { node: InferRaw @@ -541,7 +543,7 @@ class GPaginatedList extends Type { return this } - omitResolver () { + omitResolver() { return new GOmitResolver(this) } @@ -554,12 +556,13 @@ class GPaginatedList extends Type { // } } -class GOptional extends Type { +class GOptionalBase extends Type { constructor(shape: T) { super() this.typeDef = shape.typeDef this.typeDef.isOptional = true this.typeDef.isRequired = false + this._internal = shape._internal } list() { @@ -570,8 +573,10 @@ class GOptional extends Type { this.typeDef.defaultValue = value return this } +} - omitResolver () { +class GOptional extends GOptionalBase { + omitResolver() { return new GOmitResolver(this) } @@ -580,7 +585,7 @@ class GOptional extends Type { } } -class GOmitResolver extends Type { +class GOmitResolver extends Type { constructor(shape: T) { super() this.typeDef = shape.typeDef @@ -609,7 +614,7 @@ class GOmitResolver extends Type { } } -class GArgs extends Type { +class GArgs extends Type { declare _args: X constructor(shape: T, args: X) { @@ -620,7 +625,7 @@ class GArgs extends Type { } export class GarphSchema { - types: Map = new Map() + types: Map = new Map() nodeType = this.interface('Node', { id: this.id() @@ -640,13 +645,13 @@ export class GarphSchema { after: this.id().optional() } - registerType(type: AnyType) { + registerType(type: AnyExposedType) { const name = type.typeDef.name if (this.types.has(name)) throw new Error(`Type with name "${name}" already exists`) this.types.set(name, type) } - constructor ({ types }: { types: AnyType[] } = { types: [] }) { + constructor({ types }: { types: AnyExposedType[] } = { types: [] }) { types.forEach(t => this.registerType(t)) } @@ -656,7 +661,7 @@ export class GarphSchema { return t } - node(name: N, shape: T) { + node(name: N, shape: T) { const t = new GType(name, shape).implements(this.nodeType) this.registerType(t) return t @@ -685,7 +690,7 @@ export class GarphSchema { return t } - inputType(name: N, shape: T) { + inputType(name: N, shape: T) { const t = new GInput(name, shape) this.registerType(t) return t @@ -709,7 +714,7 @@ export class GarphSchema { return t } - interface(name: N, shape: T) { + interface(name: N, shape: T) { const t = new GInterface(name, shape) this.registerType(t) return t @@ -741,7 +746,7 @@ export class GarphSchema { return new GRef(ref) } - internal(){ + internal() { return new GInternal() }