Skip to content

Commit 8f78882

Browse files
authored
improve(document-builder): simplification of all output cases! (#1269)
1 parent 7fd4449 commit 8f78882

File tree

20 files changed

+1106
-1501
lines changed

20 files changed

+1106
-1501
lines changed

src/client/handleOutput.ts

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import type { GraphQLError } from 'graphql'
2+
import type { Simplify } from 'type-fest'
3+
import type { SimplifyDeepExcept } from '../documentBuilder/Simplify.js'
24
import type { RunTypeHookOnRequestResult } from '../extension/extension.js'
35
import { Errors } from '../lib/errors/__.js'
46
import type { Grafaid } from '../lib/grafaid/__.js'
@@ -109,7 +111,15 @@ export const handleOutput = (
109111

110112
// dprint-ignore
111113
export type HandleOutputGraffleRootField<$Context extends Context, $Data extends SomeObjectData, $RootFieldName extends string> =
112-
HandleOutputGraffleRootField_Data<ExcludeNull<HandleOutput<$Context, $Data>>, $RootFieldName>
114+
HandleOutputGraffleRootField_Data<
115+
ExcludeNull<
116+
HandleOutput<
117+
$Context,
118+
SimplifyDeepExcept<$Context['scalars']['typesDecoded'], $Data>
119+
>
120+
>,
121+
$RootFieldName
122+
>
113123

114124
// dprint-ignore
115125
type HandleOutputGraffleRootField_Data<$Output extends Error | SomeObjectData | GraffleExecutionResultEnvelope, $RootFieldName extends string> =
@@ -119,7 +129,13 @@ type HandleOutputGraffleRootField_Data<$Output extends Error | SomeObjectData |
119129

120130
// dprint-ignore
121131
export type HandleOutput<$Context extends Context, $Data extends SomeObjectData> =
122-
HandleOutput_Extensions<$Context, Envelope<$Context, $Data>>
132+
HandleOutput_Extensions<
133+
$Context,
134+
Envelope<
135+
$Context,
136+
SimplifyDeepExcept<$Context['scalars']['typesDecoded'], $Data>
137+
>
138+
>
123139

124140
type HandleOutput_Extensions<$Context extends Context, $Envelope extends GraffleExecutionResultEnvelope> =
125141
HandleOutput_ErrorsReturn<
@@ -168,26 +184,32 @@ type ConfigResolveOutputErrorChannel<$Context extends Context, $Channel extends
168184

169185
// dprint-ignore
170186
// todo use ObjMap for $Data
171-
export type Envelope<$Context extends Context, $Data = unknown, $Errors extends ReadonlyArray<Error> = ReadonlyArray<GraphQLError>> =
172-
& {
173-
data?: $Data | null
174-
extensions?: ObjMap
175-
}
176-
& (
177-
$Context['config']['transport']['type'] extends 'http'
178-
? { response: Response }
179-
: {}
180-
)
181-
// todo remove use of errors type variable. Rely only on $Config.
182-
& (
183-
$Errors extends []
184-
? {}
185-
: IsEnvelopeWithoutErrors<$Context> extends true
186-
? {}
187-
: {
188-
errors?: ReadonlyArray<GraphQLError>
189-
}
190-
)
187+
export type Envelope<
188+
$Context extends Context,
189+
$Data = unknown,
190+
$Errors extends ReadonlyArray<Error> = ReadonlyArray<GraphQLError>,
191+
> =
192+
Simplify<
193+
& {
194+
data?: $Data | null
195+
extensions?: ObjMap
196+
}
197+
& (
198+
$Context['config']['transport']['type'] extends 'http'
199+
? { response: Response }
200+
: {}
201+
)
202+
// todo remove use of errors type variable. Rely only on $Config.
203+
& (
204+
$Errors extends []
205+
? {}
206+
: IsEnvelopeWithoutErrors<$Context> extends true
207+
? {}
208+
: {
209+
errors?: ReadonlyArray<GraphQLError>
210+
}
211+
)
212+
>
191213

192214
type ObjMap<T = unknown> = {
193215
[key: string]: T

src/documentBuilder/InferResult/__.test-d.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import type { db } from '../../../tests/_/schemas/db.js'
33
import type { Schema } from '../../../tests/_/schemas/kitchen-sink/graffle/modules/schema.js'
44
import type * as SelectionSets from '../../../tests/_/schemas/kitchen-sink/graffle/modules/selection-sets.js'
55
import { assertEqual } from '../../lib/assert-equal.js'
6-
import type { SimplifyDeep } from '../../lib/prelude.js'
76
import type { Registry } from '../../types/Schema/nodes/Scalar/helpers.js'
7+
import type { DocumentBuilder } from '../__.js'
88
import type { InferResult } from './__.js'
99

10-
type $<$SelectionSet extends SelectionSets.Query> = SimplifyDeep<InferResult.OperationQuery<$SelectionSet, Schema>>
10+
type $<$SelectionSet extends SelectionSets.Query> = DocumentBuilder.SimplifyDeep<
11+
InferResult.OperationQuery<$SelectionSet, Schema>
12+
>
1113

1214
type $Registry = Registry.AddScalar<Registry.Empty, typeof DateScalar>
1315

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { assertEqual } from '../lib/assert-equal.js'
2+
import type { SimplifyDeep, SimplifyDeepExcept } from './Simplify.js'
3+
4+
// dprint-ignore
5+
{
6+
7+
assertEqual<SimplifyDeep<{x:1|null}> , {x:1|null}>()
8+
assertEqual<SimplifyDeep<null | {x:1}> , null | {x:1}>()
9+
assertEqual<SimplifyDeep<null | {x?:1}> , null | {x?:1}>()
10+
assertEqual<SimplifyDeep<null | {x?:1|null}> , null | {x?:1|null}>()
11+
12+
assertEqual<SimplifyDeepExcept<Date, null | Date> , null | Date>()
13+
assertEqual<SimplifyDeepExcept<Date, {}> , {}>()
14+
assertEqual<SimplifyDeepExcept<Date, { a: Date }> , { a: Date }>()
15+
assertEqual<SimplifyDeepExcept<Date, { a: 1 }> , { a: 1 }>()
16+
assertEqual<SimplifyDeepExcept<Date, { a: { b: Date } }> , { a: { b: Date } }>()
17+
assertEqual<SimplifyDeepExcept<Date, { a: { b: Date } }> , { a: { b: Date } }>()
18+
assertEqual<SimplifyDeepExcept<Date, { a: null | { b: Date } }> , { a: null | { b: Date } }>()
19+
20+
}

src/documentBuilder/Simplify.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { IntrospectionQuery } from 'graphql'
2+
import type { AnyAndUnknownToNever } from '../lib/prelude.js'
3+
4+
export type SimplifyDeep<T> = SimplifyDeepExcept<never, T>
5+
6+
// dprint-ignore
7+
export type SimplifyDeepExcept<$ExcludeType, $Type> =
8+
$Type extends any ? // distribute execution over $Type members
9+
10+
// todo allow extensions to augment this list, with arbitrary types, not just custom scalars.
11+
$Type extends AnyAndUnknownToNever<$ExcludeType> | IntrospectionQuery
12+
? $Type
13+
: {
14+
[$Key in keyof $Type]:
15+
& SimplifyDeepExcept<$ExcludeType, $Type[$Key]>
16+
& ({} | null)
17+
}
18+
: never

src/documentBuilder/_.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Simplify.js'

src/documentBuilder/__.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * as DocumentBuilder from './_.js'

src/documentBuilder/requestMethods/document.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { type HandleOutput } from '../../client/handleOutput.js'
44
import type { InferResult } from '../../documentBuilder/InferResult/__.js'
55
import type { Select } from '../../documentBuilder/Select/__.js'
66
import type { Schema } from '../../entrypoints/schema.js'
7-
import type { IsTupleMultiple, SimplifyDeepExcept } from '../../lib/prelude.js'
7+
import type { IsTupleMultiple } from '../../lib/prelude.js'
88

99
// dprint-ignore
1010
export type DocumentRunner<
@@ -18,17 +18,15 @@ export type DocumentRunner<
1818
const $Name extends string = $Params extends [] ? $$Name : $Params[0],
1919
>(...params: $Params) =>
2020
Promise<
21-
SimplifyDeepExcept<
22-
$$Context['scalars']['typesDecoded'],
23-
HandleOutput<
21+
& ({} | null)
22+
& HandleOutput<
2423
$$Context,
2524
InferResult.Operation<
2625
Select.Document.GetOperation<$$Document, $Name>,
2726
$$Schema,
2827
Select.Document.GetOperationType<$$Document, $Name>
2928
>
3029
>
31-
>
3230
>
3331
}
3432

src/documentBuilder/requestMethods/requestMethods.test-d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ test(`query`, async () => {
2121
// scalar with required arguments
2222
expectTypeOf<Parameters<typeof graffle.query.stringWithRequiredArg>>().toEqualTypeOf<[input: Graffle.SelectionSets.Query.stringWithRequiredArg]>()
2323
// scalar custom
24+
const result = await graffle.query.date()
2425
expectTypeOf(await graffle.query.date()).toMatchTypeOf<Date | null>()
2526
// scalar with explicit indicators
2627
// positive indicator

src/entrypoints/utilities-for-generated.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,8 @@ export type { ConfigGetOutputError, HandleOutput, HandleOutputGraffleRootField }
44
export type { Config } from '../client/Settings/Config.js'
55
export { type DocumentRunner } from '../documentBuilder/requestMethods/document.js'
66
export * from '../documentBuilder/Select/__.js'
7-
export {
8-
type AssertExtendsObject,
9-
type Exact,
10-
type ExactNonEmpty,
11-
type SimplifyDeep,
12-
type SimplifyDeepExcept,
13-
type SimplifyExcept,
14-
type UnionExpanded,
15-
} from '../lib/prelude.js'
7+
export { type SimplifyDeep, type SimplifyDeepExcept } from '../documentBuilder/Simplify.js'
8+
export { type AssertExtendsObject, type Exact, type ExactNonEmpty, type UnionExpanded } from '../lib/prelude.js'
169
export { TypeFunction } from '../lib/type-function/__.js'
1710
export { type GlobalRegistry } from '../types/GlobalRegistry/GlobalRegistry.js'
1811
export { Schema } from '../types/Schema/__.js'

src/extensions/Introspection/Introspection.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { getIntrospectionQuery, type IntrospectionQuery } from 'graphql'
22
import type { Context } from '../../client/context.js'
33
import type { HandleOutput } from '../../client/handleOutput.js'
44
import { createBuilderExtension, createExtension } from '../../entrypoints/extensionkit.js'
5-
import type { SimplifyNullable } from '../../entrypoints/main.js'
65
import type { Builder } from '../../lib/builder/__.js'
76
import { type ConfigInput, createConfig } from './config.js'
87

@@ -73,7 +72,7 @@ interface BuilderExtension extends Builder.Extension {
7372
}
7473

7574
interface BuilderExtension_<$Args extends Builder.Extension.Parameters<BuilderExtension>> {
76-
introspect: () => Promise<SimplifyNullable<HandleOutput<$Args['context'], IntrospectionQuery>>>
75+
introspect: () => Promise<(null | {}) & HandleOutput<$Args['context'], IntrospectionQuery>>
7776
}
7877

7978
const knownPotentiallyUnsupportedFeatures = [`inputValueDeprecation`, `oneOf`] as const

0 commit comments

Comments
 (0)