Skip to content

Commit

Permalink
refactor(ts-client): schema module (#770)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt committed Apr 12, 2024
1 parent 33a0278 commit 1287eda
Show file tree
Hide file tree
Showing 55 changed files with 694 additions and 656 deletions.
40 changes: 19 additions & 21 deletions src/ResultSet/ResultSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import type { Simplify } from 'type-fest'
import type { GetKeyOr, SimplifyDeep } from '../lib/prelude.js'
import type { TSError } from '../lib/TSError.js'
import type { Schema } from '../Schema/__.js'
import type { Schema, SomeField } from '../Schema/__.js'
import type { PickScalarFields } from '../Schema/Output/Output.js'
import type { SelectionSet } from '../SelectionSet/__.js'

// dprint-ignore
Expand All @@ -19,18 +20,15 @@ export type Subscription<$SelectionSetSubscription extends object, $Index extend
SimplifyDeep<Object$<$SelectionSetSubscription, Exclude<$Index['Root']['Subscription'], null>, $Index>>

// dprint-ignore
export type Object$<$SelectionSet, $Node extends Schema.Named.Object$2, $Index extends Schema.Index> =
export type Object$<$SelectionSet, $Node extends Schema.Output.Object$2, $Index extends Schema.Index> =
SelectionSet.IsSelectScalarsWildcard<$SelectionSet> extends true

/**
* Handle Scalars Wildcard
*/
?
{
[$Key in keyof $Node['fields'] as $Node['fields'][$Key] extends Schema.Field.Field<Schema.Field.Type.Output.__typename> | {'typeUnwrapped':{kind:'Scalar'}} ? $Key : never]:
// eslint-disable-next-line
// @ts-ignore infinite depth issue, can this be fixed?
Field<$SelectionSet, Schema.Field.As<$Node['fields'][$Key]>, $Index>
[$Key in keyof PickScalarFields<$Node>]: Field<$SelectionSet, $Node['fields'][$Key], $Index>
}
/**
* Handle fields in regular way.
Expand All @@ -44,15 +42,15 @@ export type Object$<$SelectionSet, $Node extends Schema.Named.Object$2, $Index e
}>

// dprint-ignore
type Union<$SelectionSet, $Node extends Schema.Named.Union, $Index extends Schema.Index> =
type Union<$SelectionSet, $Node extends Schema.Output.Union, $Index extends Schema.Index> =
OnTypeFragment<$SelectionSet,$Node['members'][number], $Index>

// dprint-ignore
type Interface<$SelectionSet, $Node extends Schema.Named.Interface, $Index extends Schema.Index> =
type Interface<$SelectionSet, $Node extends Schema.Output.Interface, $Index extends Schema.Index> =
OnTypeFragment<$SelectionSet, $Node['implementors'][number], $Index>

// dprint-ignore
type OnTypeFragment<$SelectionSet, $Node extends Schema.Named.Object$2, $Index extends Schema.Index> =
type OnTypeFragment<$SelectionSet, $Node extends Schema.Output.Object$2, $Index extends Schema.Index> =
$Node extends any // force distribution
? Object$<
GetKeyOr<$SelectionSet, `on${Capitalize<$Node['fields']['__typename']['type']['type']>}`, {}> & SelectionSet.OmitOnTypeFragments<$SelectionSet>,
Expand All @@ -62,7 +60,7 @@ type OnTypeFragment<$SelectionSet, $Node extends Schema.Named.Object$2, $Index e
: never

// dprint-ignore
type Field<$SelectionSet, $Field extends Schema.Field.Field, $Index extends Schema.Index> =
type Field<$SelectionSet, $Field extends SomeField, $Index extends Schema.Index> =
$SelectionSet extends SelectionSet.Directive.Include.Negative | SelectionSet.Directive.Skip.Positive ?
null :
(
Expand All @@ -74,18 +72,18 @@ type Field<$SelectionSet, $Field extends Schema.Field.Field, $Index extends Sche
// dprint-ignore
type FieldType<
$SelectionSet,
$Type extends Schema.Field.Type.Output.Any,
$Type extends Schema.Output.Any,
$Index extends Schema.Index
> =Simplify<
$Type extends Schema.Field.Type.Output.__typename<infer $Value> ? $Value :
$Type extends Schema.Field.Type.Output.Nullable<infer $InnerType> ? null | FieldType<$SelectionSet, $InnerType, $Index> :
$Type extends Schema.Field.Type.Output.List<infer $InnerType> ? Array<FieldType<$SelectionSet, $InnerType, $Index>> :
$Type extends Schema.Named.Enum<infer _, infer $Members> ? $Members[number] :
$Type extends Schema.Named.Scalar.Any ? ReturnType<$Type['codec']['decode']> :
$Type extends Schema.Named.Object$2 ? Object$<$SelectionSet,$Type,$Index> :
$Type extends Schema.Named.Interface ? Interface<$SelectionSet,$Type,$Index> :
$Type extends Schema.Named.Union ? Union<$SelectionSet,$Type,$Index> :
TSError<'FieldType', `Unknown type`, { $Type: $Type }>
$Type extends Schema.__typename<infer $Value> ? $Value :
$Type extends Schema.Output.Nullable<infer $InnerType> ? null | FieldType<$SelectionSet, $InnerType, $Index> :
$Type extends Schema.Output.List<infer $InnerType> ? Array<FieldType<$SelectionSet, $InnerType, $Index>> :
$Type extends Schema.Enum<infer _, infer $Members> ? $Members[number] :
$Type extends Schema.Scalar.Any ? ReturnType<$Type['codec']['decode']> :
$Type extends Schema.Object$2 ? Object$<$SelectionSet,$Type,$Index> :
$Type extends Schema.Interface ? Interface<$SelectionSet,$Type,$Index> :
$Type extends Schema.Union ? Union<$SelectionSet,$Type,$Index> :
TSError<'FieldType', `Unknown type`, { $Type: $Type }>
>

// dprint-ignore
Expand All @@ -104,5 +102,5 @@ type FieldDirectiveSkip<$SelectionSet> =

// dprint-ignore
export namespace Errors {
export type UnknownFieldName<$FieldName extends string, $Object extends Schema.Named.Object$2> = TSError<'Object', `field "${$FieldName}" does not exist on object "${$Object['fields']['__typename']['type']['type']}"`>
export type UnknownFieldName<$FieldName extends string, $Object extends Schema.Object$2> = TSError<'Object', `field "${$FieldName}" does not exist on object "${$Object['fields']['__typename']['type']['type']}"`>
}
26 changes: 26 additions & 0 deletions src/Schema/Args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Input } from './_.js'
import type { Nullable } from './Input/types/Nullable.js'

type InputFields = Record<string, any>

// dprint-ignore
export type InputFieldsAllNullable<$Fields extends InputFields> =
Exclude<$Fields[keyof $Fields], Nullable<any>> extends never ? true : false

export interface Args<$Fields extends InputFields> {
fields: $Fields
}

export const Args = <F extends InputFields>(fields: F): Args<F> => {
return {
fields,
}
}

export type OmitNullableFields<$Fields extends InputFields> = {
[Key in keyof $Fields as $Fields[Key] extends Input.Nullable<any> ? never : Key]: $Fields[Key]
}

export type PickNullableFields<$Fields extends InputFields> = {
[Key in keyof $Fields as $Fields[Key] extends Input.Nullable<any> ? Key : never]: $Fields[Key]
}
31 changes: 31 additions & 0 deletions src/Schema/Field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Args } from './Args.js'
import type { MaybeThunk } from './core/helpers.js'
import type { Hybrid } from './Hybrid/__.js'
import type { Output } from './Output/__.js'

export type Field<$Type extends Output.Any, $Args extends Args<any> | null> = {
type: $Type
args: $Args
}

export const field = <$Type extends Output.Any, $Args extends null | Args<any> = null>(
type: MaybeThunk<$Type>,
args: $Args = null as $Args,
): Field<$Type, $Args> => {
return {
// At type level "type" is not a thunk
type: type as any, // eslint-disable-line
args,
}
}

// todo test non null union and non null interface fields
export type SomeField = Field<
Hybrid.Enum | Hybrid.Scalar.Any | Output.List<any> | Output.Nullable<any> | Output.Object$2<any, any>,
Args<any> | null
>

export type SomeFields<$Keys extends string | number | symbol = string | number | symbol> = Record<
$Keys,
SomeField
>
38 changes: 0 additions & 38 deletions src/Schema/Field/Field.ts

This file was deleted.

133 changes: 0 additions & 133 deletions src/Schema/Field/Type.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/Schema/Field/_.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/Schema/Field/__.ts

This file was deleted.

2 changes: 2 additions & 0 deletions src/Schema/Hybrid/_.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './types/Enum.js'
export * from './types/Scalar/__.js'
1 change: 1 addition & 0 deletions src/Schema/Hybrid/__.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * as Hybrid from './_.js'
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 0 additions & 11 deletions src/Schema/Index.ts

This file was deleted.

16 changes: 16 additions & 0 deletions src/Schema/Input/Input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Any } from './typeGroups.js'

export * from './typeGroups.js'
export * from './types/InputObject.js'
export * from './types/List.js'
export * from './types/Nullable.js'

export const field = <$Type extends Any>(type: $Type): Field<$Type> => {
return {
type: type,
}
}

export type Field<$Type extends any = any> = {
type: $Type
}
1 change: 1 addition & 0 deletions src/Schema/Input/__.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * as Input from './Input.js'
8 changes: 8 additions & 0 deletions src/Schema/Input/typeGroups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Hybrid } from '../Hybrid/__.js'
import type { InputObject } from './types/InputObject.js'
import type { List } from './types/List.js'
import type { Nullable } from './types/Nullable.js'

export type Named = Hybrid.Enum | Hybrid.Scalar.Any | InputObject

export type Any = List<any> | Nullable<any> | Named
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
type Fields = Record<string, any>
export type InputFields = Record<string, any>

export interface InputObject<
$Name extends string = string,
$Fields extends Fields = Fields,
$Fields extends InputFields = InputFields,
> {
kind: 'InputObject'
name: $Name
Expand Down
9 changes: 9 additions & 0 deletions src/Schema/Input/types/List.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Base } from '../../core/helpers.js'
import type { Any } from '../typeGroups.js'

export type List<$InnerType extends Any> = Base.List<$InnerType>

export const List = <$InnerType extends Any>(type: $InnerType): List<$InnerType> => ({
kind: `list`,
type,
})

0 comments on commit 1287eda

Please sign in to comment.