Skip to content

Commit 5617898

Browse files
committed
Allow internal properties only in object types
1 parent dce4c14 commit 5617898

File tree

1 file changed

+56
-51
lines changed

1 file changed

+56
-51
lines changed

src/index.ts

+56-51
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import { buildSchema, printSchema } from './schema'
55
type GraphQLRootType = 'Query' | 'Mutation' | 'Subscription'
66
type GarphType = 'String' | 'Int' | 'Float' | 'Boolean' | 'ID' | 'ObjectType' | 'InterfaceType' | 'InputType' | 'Scalar' | 'Enum' | 'List' | 'PaginatedList' | 'Union' | 'Ref' | 'Internal' | 'Optional' | 'Args' | 'OmitResolver'
77

8-
export abstract class Type<T, X extends GarphType> {
8+
export abstract class Type<TShape, TId extends GarphType, TInternal extends boolean = false> {
99
_name?: string
10-
_is: X
10+
_is: TId
1111
_inner?: any
1212
_output?: any
1313
_args?: Args
14-
_shape: T
15-
typeDef: TypeDefinition<T>
14+
_shape: TShape
15+
_internal: TInternal
16+
typeDef: TypeDefinition<TShape>
1617

1718
description(text: string) {
1819
this.typeDef.description = text
@@ -25,6 +26,7 @@ export abstract class Type<T, X extends GarphType> {
2526
}
2627
}
2728

29+
2830
export type TypeDefinition<T> = {
2931
name?: string
3032
type: GarphType
@@ -37,18 +39,19 @@ export type TypeDefinition<T> = {
3739
scalarOptions?: ScalarOptions<any, any>
3840
defaultValue?: any
3941
interfaces?: AnyInterface[]
40-
extend?: AnyTypes[]
42+
extend?: AnyExposedTypes[]
4143
}
4244

43-
export type AnyType = Type<any, any>
45+
export type AnyType<TInternal extends boolean = boolean> = Type<any, any, TInternal>
46+
export type AnyExposedType = AnyType<false>
4447
export type AnyString = Type<string, 'String'>
4548
export type AnyID = Type<string, 'ID'>
4649
export type AnyBoolean = Type<boolean, 'Boolean'>
4750
export type AnyNumber = Type<number, any>
4851
export type AnyInt = Type<number, 'Int'>
4952
export type AnyFloat = Type<number, 'Float'>
5053
export type AnyRef = Type<any, 'Ref'>
51-
export type AnyInternal = Type<any, 'Internal'>
54+
export type AnyInternal = Type<any, 'Internal', true>
5255
export type AnyList = Type<any, 'List'>
5356
export type AnyPaginatedList = Type<any, 'PaginatedList'>
5457
export type AnyUnion = Type<any, 'Union'>
@@ -62,13 +65,15 @@ export type AnyObject = Type<any, 'ObjectType'>
6265
export type AnyOmitResolver = Type<any, 'OmitResolver'>
6366

6467
export type Args = {
65-
[key: string]: AnyType
68+
[key: string]: AnyExposedType
6669
}
6770

68-
export type AnyTypes = {
69-
[key: string]: AnyType
71+
export type AnyTypes<TInternal extends boolean = boolean> = {
72+
[key: string]: AnyType<TInternal>
7073
}
7174

75+
export type AnyExposedTypes = AnyTypes<false>
76+
7277
export type AnyObjects = {
7378
[key: string]: AnyObject
7479
}
@@ -88,10 +93,11 @@ type InferOptions = {
8893
omitResolver?: AnyOmitResolver | never
8994
}
9095

91-
type RefType = () => AnyType
96+
type RefType = () => AnyExposedType
9297

9398
// TODO: Refactor Args to get rid of this mess
9499
export type Infer<T, options extends InferOptions = { omitResolver: never }> = ExpandRecursively<InferRaw<T, options>>
100+
95101
export type InferRaw<T, options extends InferOptions = { omitResolver: never }> = T extends AnyInput | AnyObject | AnyInterface ? {
96102
__typename?: T['_name']
97103
} & {
@@ -119,21 +125,21 @@ export type InferShallow<T, options extends InferOptions = { omitResolver: never
119125
T extends AnyInternal ? T['_shape'] :
120126
T
121127

122-
export type InferArgs<T extends AnyType> = ExpandRecursively<InferArgsRaw<T>>
123-
export type InferArgsRaw<T extends AnyType> = T extends AnyObject | AnyInterface ? {
128+
export type InferArgs<T extends AnyExposedType> = ExpandRecursively<InferArgsRaw<T>>
129+
export type InferArgsRaw<T extends AnyExposedType> = T extends AnyObject | AnyInterface ? {
124130
[K in keyof T['_shape']]: InferArgRaw<T['_shape'][K]>
125131
} : never
126132

127133
export type InferArg<T> = ExpandRecursively<InferArgRaw<T>>
128134
export type InferArgRaw<T> = T extends AnyArgs ? {
129-
[K in keyof T['_args'] as T['_args'][K] extends AnyOptional ? never : K]: InferRaw<T['_args'][K]>
135+
[K in keyof T['_args']as T['_args'][K] extends AnyOptional ? never : K]: InferRaw<T['_args'][K]>
130136
} & {
131-
[K in keyof T['_args'] as T['_args'][K] extends AnyOptional ? K : never]?: InferRaw<T['_args'][K]>
132-
}: never
137+
[K in keyof T['_args']as T['_args'][K] extends AnyOptional ? K : never]?: InferRaw<T['_args'][K]>
138+
} : never
133139

134140
export type InferUnionNames<T> = T extends AnyUnion ? ObjectToUnion<T['_inner']>['_name'] : never
135141

136-
export type InferResolvers<T extends AnyTypes, X extends InferResolverConfig> = {
142+
export type InferResolvers<T extends AnyExposedTypes, X extends InferResolverConfig> = {
137143
[K in keyof T]: K extends 'Subscription' ? {
138144
[G in keyof T[K]['_shape']]?: {
139145
subscribe: (parent: {}, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo) => MaybePromise<AsyncIterator<{ [G in keyof T[K]['_shape']]: Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }> }>>
@@ -145,17 +151,17 @@ export type InferResolvers<T extends AnyTypes, X extends InferResolverConfig> =
145151
[G in keyof T[K]['_shape']]?: {
146152
resolve: (parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>> | AsyncGenerator<Infer<T[K]['_shape'][G]['_shape'], { omitResolver: AnyOmitResolver }>>
147153
} | {
148-
load: (queries: { parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo } []) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>[]>
154+
load: (queries: { parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo }[]) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>[]>
149155
} | {
150-
loadBatch: (queries: { parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo } []) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>[]>
156+
loadBatch: (queries: { parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo }[]) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>[]>
151157
}
152158
} & {
153159
__isTypeOf?: (parent: Infer<T[K]>, context: X['context'], info: GraphQLResolveInfo) => MaybePromise<boolean>
154160
__resolveType?: (parent: Infer<T[K]>, context: X['context'], info: GraphQLResolveInfo) => MaybePromise<InferUnionNames<T[K]>>
155161
}
156162
}
157163

158-
export type InferResolversStrict<T extends AnyTypes, X extends InferResolverConfig> = {
164+
export type InferResolversStrict<T extends AnyExposedTypes, X extends InferResolverConfig> = {
159165
[K in keyof T]: K extends 'Subscription' ? {
160166
[G in keyof T[K]['_shape']]: {
161167
subscribe: (parent: {}, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo) => MaybePromise<AsyncIterator<{ [G in keyof T[K]['_shape']]: Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }> }>>
@@ -167,9 +173,9 @@ export type InferResolversStrict<T extends AnyTypes, X extends InferResolverConf
167173
[G in keyof T[K]['_shape']]: {
168174
resolve: (parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>> | AsyncGenerator<Infer<T[K]['_shape'][G]['_shape'], { omitResolver: AnyOmitResolver }>>
169175
} | {
170-
load: (queries: { parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo } []) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>>[]
176+
load: (queries: { parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo }[]) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>>[]
171177
} | {
172-
loadBatch: (queries: { parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo } []) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>>[]
178+
loadBatch: (queries: { parent: K extends GraphQLRootType ? {} : Infer<T[K]>, args: InferArg<T[K]['_shape'][G]>, context: X['context'], info: GraphQLResolveInfo }[]) => MaybePromise<Infer<T[K]['_shape'][G], { omitResolver: AnyOmitResolver }>>[]
173179
}
174180
} & {
175181
__isTypeOf?: (parent: Infer<T[K]>, context: X['context'], info: GraphQLResolveInfo) => MaybePromise<boolean>
@@ -180,7 +186,7 @@ export type InferResolversStrict<T extends AnyTypes, X extends InferResolverConf
180186
class GType<N extends string, T extends AnyTypes> extends Type<T, 'ObjectType'> {
181187
declare _name: N
182188

183-
constructor(name: string, shape: T, interfaces?: AnyInterface[], extend?: AnyTypes[]) {
189+
constructor(name: string, shape: T, interfaces?: AnyInterface[], extend?: AnyExposedTypes[]) {
184190
super()
185191
this.typeDef = {
186192
name,
@@ -197,17 +203,17 @@ class GType<N extends string, T extends AnyTypes> extends Type<T, 'ObjectType'>
197203
return new GType<N, T & UnionToIntersection<D['_shape']>>(this.typeDef.name, this.typeDef.shape as any, Array.isArray(ref) ? ref : [ref], this.typeDef.extend)
198204
}
199205

200-
extend<D extends AnyTypes>(ref: D | D[]) {
206+
extend<D extends AnyExposedTypes>(ref: D | D[]) {
201207
// This is temporary construct, until we figure out how to properly manage to shared schema
202208
this.typeDef.extend = Array.isArray(ref) ? ref : [ref]
203209
return new GType<N, T & UnionToIntersection<D>>(this.typeDef.name, this.typeDef.shape as any, this.typeDef.interfaces, Array.isArray(ref) ? ref : [ref])
204210
}
205211
}
206212

207-
class GInput<N extends string, T extends AnyTypes> extends Type<T, 'InputType'> {
213+
class GInput<N extends string, T extends AnyExposedTypes> extends Type<T, 'InputType'> {
208214
declare _name: N
209215

210-
constructor(name: string, shape: T, extend?: AnyTypes[]) {
216+
constructor(name: string, shape: T, extend?: AnyExposedTypes[]) {
211217
super()
212218
this.typeDef = {
213219
name,
@@ -217,17 +223,17 @@ class GInput<N extends string, T extends AnyTypes> extends Type<T, 'InputType'>
217223
}
218224
}
219225

220-
extend<D extends AnyTypes>(ref: D | D[]) {
226+
extend<D extends AnyExposedTypes>(ref: D | D[]) {
221227
// This is temporary construct, until we figure out how to properly manage to shared schema
222228
this.typeDef.extend = Array.isArray(ref) ? ref : [ref]
223229
return new GInput<N, T & UnionToIntersection<D>>(this.typeDef.name, this.typeDef.shape as any, Array.isArray(ref) ? ref : [ref])
224230
}
225231
}
226232

227-
class GInterface<N extends string, T extends AnyTypes> extends Type<T, 'InterfaceType'> {
233+
class GInterface<N extends string, T extends AnyExposedTypes> extends Type<T, 'InterfaceType'> {
228234
declare _name: N
229235

230-
constructor(name: string, shape: T, interfaces?: AnyInterface[], extend?: AnyTypes[]) {
236+
constructor(name: string, shape: T, interfaces?: AnyInterface[], extend?: AnyExposedTypes[]) {
231237
super()
232238
this.typeDef = {
233239
name,
@@ -241,10 +247,10 @@ class GInterface<N extends string, T extends AnyTypes> extends Type<T, 'Interfac
241247
implements<D extends AnyInterface>(ref: D | D[]) {
242248
// This is temporary construct, until we figure out how to properly manage to shared schema
243249
this.typeDef.interfaces = Array.isArray(ref) ? ref : [ref]
244-
return new GInterface<N ,T & UnionToIntersection<D['_shape']>>(this.typeDef.name, this.typeDef.shape as any, Array.isArray(ref) ? ref : [ref], this.typeDef.extend)
250+
return new GInterface<N, T & UnionToIntersection<D['_shape']>>(this.typeDef.name, this.typeDef.shape as any, Array.isArray(ref) ? ref : [ref], this.typeDef.extend)
245251
}
246252

247-
extend<D extends AnyTypes>(ref: D | D[]) {
253+
extend<D extends AnyExposedTypes>(ref: D | D[]) {
248254
// This is temporary construct, until we figure out how to properly manage to shared schema
249255
this.typeDef.extend = Array.isArray(ref) ? ref : [ref]
250256
return new GInterface<N, T & UnionToIntersection<D>>(this.typeDef.name, this.typeDef.shape as any, this.typeDef.interfaces, Array.isArray(ref) ? ref : [ref])
@@ -434,7 +440,7 @@ class GRef<T> extends Type<T, 'Ref'> {
434440
}
435441
}
436442

437-
class GInternal<T> extends Type<T, 'Internal'> {
443+
class GInternal<T> extends Type<T, 'Internal', true> {
438444
constructor() {
439445
super()
440446
this.typeDef = {
@@ -443,17 +449,13 @@ class GInternal<T> extends Type<T, 'Internal'> {
443449
}
444450

445451
optional() {
446-
return new GOptional<this>(this)
452+
return new GOptionalBase<this>(this);
447453
}
448454

449455
required() {
450456
this.typeDef.isRequired = true
451457
return this
452458
}
453-
454-
omitResolver () {
455-
return new GOmitResolver<this>(this)
456-
}
457459
}
458460

459461
class GScalar<I, O> extends Type<I, 'Scalar'> {
@@ -497,7 +499,7 @@ class GList<T extends AnyType> extends Type<T, 'List'> {
497499
return this
498500
}
499501

500-
omitResolver () {
502+
omitResolver() {
501503
return new GOmitResolver<this>(this)
502504
}
503505

@@ -510,7 +512,7 @@ class GList<T extends AnyType> extends Type<T, 'List'> {
510512
}
511513
}
512514

513-
class GPaginatedList<T extends AnyType> extends Type<T, 'PaginatedList'> {
515+
class GPaginatedList<T extends AnyExposedType> extends Type<T, 'PaginatedList'> {
514516
declare _inner: {
515517
edges: {
516518
node: InferRaw<T>
@@ -541,7 +543,7 @@ class GPaginatedList<T extends AnyType> extends Type<T, 'PaginatedList'> {
541543
return this
542544
}
543545

544-
omitResolver () {
546+
omitResolver() {
545547
return new GOmitResolver<this>(this)
546548
}
547549

@@ -554,12 +556,13 @@ class GPaginatedList<T extends AnyType> extends Type<T, 'PaginatedList'> {
554556
// }
555557
}
556558

557-
class GOptional<T extends AnyType> extends Type<T, 'Optional'> {
559+
class GOptionalBase<T extends AnyType> extends Type<T, 'Optional', T["_internal"]> {
558560
constructor(shape: T) {
559561
super()
560562
this.typeDef = shape.typeDef
561563
this.typeDef.isOptional = true
562564
this.typeDef.isRequired = false
565+
this._internal = shape._internal
563566
}
564567

565568
list() {
@@ -570,8 +573,10 @@ class GOptional<T extends AnyType> extends Type<T, 'Optional'> {
570573
this.typeDef.defaultValue = value
571574
return this
572575
}
576+
}
573577

574-
omitResolver () {
578+
class GOptional<T extends AnyExposedType> extends GOptionalBase<T> {
579+
omitResolver() {
575580
return new GOmitResolver<this>(this)
576581
}
577582

@@ -580,7 +585,7 @@ class GOptional<T extends AnyType> extends Type<T, 'Optional'> {
580585
}
581586
}
582587

583-
class GOmitResolver<T extends AnyType> extends Type<T, 'OmitResolver'> {
588+
class GOmitResolver<T extends AnyExposedType> extends Type<T, 'OmitResolver'> {
584589
constructor(shape: T) {
585590
super()
586591
this.typeDef = shape.typeDef
@@ -609,7 +614,7 @@ class GOmitResolver<T extends AnyType> extends Type<T, 'OmitResolver'> {
609614
}
610615
}
611616

612-
class GArgs<T extends AnyType, X extends Args> extends Type<T, 'Args'> {
617+
class GArgs<T extends AnyExposedType, X extends Args> extends Type<T, 'Args'> {
613618
declare _args: X
614619

615620
constructor(shape: T, args: X) {
@@ -620,7 +625,7 @@ class GArgs<T extends AnyType, X extends Args> extends Type<T, 'Args'> {
620625
}
621626

622627
export class GarphSchema {
623-
types: Map<string, AnyType> = new Map()
628+
types: Map<string, AnyExposedType> = new Map()
624629

625630
nodeType = this.interface('Node', {
626631
id: this.id()
@@ -640,13 +645,13 @@ export class GarphSchema {
640645
after: this.id().optional()
641646
}
642647

643-
registerType(type: AnyType) {
648+
registerType(type: AnyExposedType) {
644649
const name = type.typeDef.name
645650
if (this.types.has(name)) throw new Error(`Type with name "${name}" already exists`)
646651
this.types.set(name, type)
647652
}
648653

649-
constructor ({ types }: { types: AnyType[] } = { types: [] }) {
654+
constructor({ types }: { types: AnyExposedType[] } = { types: [] }) {
650655
types.forEach(t => this.registerType(t))
651656
}
652657

@@ -656,7 +661,7 @@ export class GarphSchema {
656661
return t
657662
}
658663

659-
node<N extends string, T extends AnyTypes>(name: N, shape: T) {
664+
node<N extends string, T extends AnyExposedTypes>(name: N, shape: T) {
660665
const t = new GType<N, T>(name, shape).implements(this.nodeType)
661666
this.registerType(t)
662667
return t
@@ -685,7 +690,7 @@ export class GarphSchema {
685690
return t
686691
}
687692

688-
inputType<N extends string, T extends AnyTypes>(name: N, shape: T) {
693+
inputType<N extends string, T extends AnyExposedTypes>(name: N, shape: T) {
689694
const t = new GInput<N, T>(name, shape)
690695
this.registerType(t)
691696
return t
@@ -709,7 +714,7 @@ export class GarphSchema {
709714
return t
710715
}
711716

712-
interface<N extends string, T extends AnyTypes>(name: N, shape: T) {
717+
interface<N extends string, T extends AnyExposedTypes>(name: N, shape: T) {
713718
const t = new GInterface<N, T>(name, shape)
714719
this.registerType(t)
715720
return t
@@ -741,7 +746,7 @@ export class GarphSchema {
741746
return new GRef<T>(ref)
742747
}
743748

744-
internal<T>(){
749+
internal<T>() {
745750
return new GInternal<T>()
746751
}
747752

0 commit comments

Comments
 (0)