Skip to content

Commit

Permalink
improve(custom-scalars): no expand inferred result type (#1211)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonkuhrt authored Oct 23, 2024
1 parent 245a10a commit 2705620
Show file tree
Hide file tree
Showing 53 changed files with 3,733 additions and 2,714 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
headers: Headers {
accept: 'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8',
'content-type': 'application/json',
'x-sent-at-time': '1729654429348'
'x-sent-at-time': '1729695636061'
},
signal: undefined,
method: 'post',
Expand Down
2 changes: 1 addition & 1 deletion examples/__outputs__/20_output/output_envelope.output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
headers: Headers {
'content-type': 'application/graphql-response+json; charset=utf-8',
'content-length': '142',
date: 'Wed, 23 Oct 2024 03:33:49 GMT',
date: 'Wed, 23 Oct 2024 15:00:36 GMT',
connection: 'keep-alive',
'keep-alive': 'timeout=5'
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---------------------------------------- SHOW ----------------------------------------
pokemons[0].birthday instanceof Date = true
true
---------------------------------------- SHOW ----------------------------------------
[
{ name: 'Pikachu', birthday: 1850-01-01T00:00:00.000Z },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
}
},
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
traceId: '4db92619c2c83794eea58ac3b0f81739',
parentId: '0441c81c457852b2',
traceId: 'a06cc237fb19a0f3f72a6b58c7a1c197',
parentId: '996dbc7722cae52f',
traceState: undefined,
name: 'encode',
id: '0fed2ea32096273f',
id: '013ccc636ba5ab5a',
kind: 0,
timestamp: 1729654429675000,
duration: 2681.792,
timestamp: 1729695637401000,
duration: 1347.708,
attributes: {},
status: { code: 0 },
events: [],
Expand All @@ -33,14 +33,14 @@
}
},
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
traceId: '4db92619c2c83794eea58ac3b0f81739',
parentId: '0441c81c457852b2',
traceId: 'a06cc237fb19a0f3f72a6b58c7a1c197',
parentId: '996dbc7722cae52f',
traceState: undefined,
name: 'pack',
id: 'ca490dca8e6606c9',
id: '9f77c7eb28b781b8',
kind: 0,
timestamp: 1729654429680000,
duration: 48326.792,
timestamp: 1729695637404000,
duration: 11403.833,
attributes: {},
status: { code: 0 },
events: [],
Expand All @@ -57,14 +57,14 @@
}
},
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
traceId: '4db92619c2c83794eea58ac3b0f81739',
parentId: '0441c81c457852b2',
traceId: 'a06cc237fb19a0f3f72a6b58c7a1c197',
parentId: '996dbc7722cae52f',
traceState: undefined,
name: 'exchange',
id: '11066eaa0e07c122',
id: '37e8810021b4127d',
kind: 0,
timestamp: 1729654429729000,
duration: 47351.292,
timestamp: 1729695637416000,
duration: 28133.5,
attributes: {},
status: { code: 0 },
events: [],
Expand All @@ -81,14 +81,14 @@
}
},
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
traceId: '4db92619c2c83794eea58ac3b0f81739',
parentId: '0441c81c457852b2',
traceId: 'a06cc237fb19a0f3f72a6b58c7a1c197',
parentId: '996dbc7722cae52f',
traceState: undefined,
name: 'unpack',
id: 'c527bbb4b62958fa',
id: '87bd4d2329beb31f',
kind: 0,
timestamp: 1729654429777000,
duration: 1775.75,
timestamp: 1729695637445000,
duration: 1657.667,
attributes: {},
status: { code: 0 },
events: [],
Expand All @@ -105,14 +105,14 @@
}
},
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
traceId: '4db92619c2c83794eea58ac3b0f81739',
parentId: '0441c81c457852b2',
traceId: 'a06cc237fb19a0f3f72a6b58c7a1c197',
parentId: '996dbc7722cae52f',
traceState: undefined,
name: 'decode',
id: '20eb54a71997e91e',
id: 'e8b9d88dc53ff408',
kind: 0,
timestamp: 1729654429779000,
duration: 669.25,
timestamp: 1729695637447000,
duration: 214.875,
attributes: {},
status: { code: 0 },
events: [],
Expand All @@ -129,14 +129,14 @@
}
},
instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined },
traceId: '4db92619c2c83794eea58ac3b0f81739',
traceId: 'a06cc237fb19a0f3f72a6b58c7a1c197',
parentId: undefined,
traceState: undefined,
name: 'request',
id: '0441c81c457852b2',
id: '996dbc7722cae52f',
kind: 0,
timestamp: 1729654429631000,
duration: 148602.75,
timestamp: 1729695637401000,
duration: 46241.5,
attributes: {},
status: { code: 0 },
events: [],
Expand Down
4 changes: 2 additions & 2 deletions src/documentBuilder/InferResult/InlineFragment.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { type GetKeyOr } from '../../lib/prelude.js'
import type { Schema } from '../../types/Schema/__.js'
import type { Select } from '../Select/__.js'
import type { Object } from './OutputObject.js'
import type { OutputObject } from './OutputObject.js'

// dprint-ignore
export type InlineFragmentTypeConditional<$SelectionSet, $Node extends Schema.OutputObject, $Schema extends Schema> =
$Node extends any // force distribution
? Object<
? OutputObject<
& GetKeyOr<
$SelectionSet,
`${Select.InlineFragment.TypeConditionalKeyPrefix}${$Node['name']}`,
Expand Down
48 changes: 24 additions & 24 deletions src/documentBuilder/InferResult/OutputField.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
import type { Simplify } from 'type-fest'
import type { SimplifyNullable } from '../../lib/prelude.js'
import type { TSErrorDescriptive } from '../../lib/ts-error.js'
import type { Schema } from '../../types/Schema/__.js'
import type { InlineType } from '../../types/SchemaDrivenDataMap/InlineType.js'
import type { Select } from '../Select/__.js'
import type { Interface } from './Interface.js'
import type { Object } from './OutputObject.js'
import type { OutputObject } from './OutputObject.js'
import type { Union } from './Union.js'

// dprint-ignore
export type OutputField<$SelectionSet, $Field extends Schema.OutputField, $Schema extends Schema> =
Simplify<
$SelectionSet extends Select.Directive.Include.FieldStates.Negative | Select.Directive.Skip.FieldStates.Positive ?
null :
(
| FieldDirectiveInclude<$SelectionSet>
| FieldDirectiveSkip<$SelectionSet>
| InlineType.Infer<
$SelectionSet extends Select.Directive.Include.FieldStates.Negative | Select.Directive.Skip.FieldStates.Positive ?
null :
(
| FieldDirectiveInclude<$SelectionSet>
| FieldDirectiveSkip<$SelectionSet>
| SimplifyNullable<
InlineType.Infer<
$Field['inlineType'],
FieldType<$Schema, Omit<$SelectionSet, '$'>, $Field['namedType']>
>
)
>
>
)

// dprint-ignore
type FieldType<
$Schema extends Schema,
$SelectionSet,
$Type extends Schema.NamedOutputTypes,
$Node extends Schema.NamedOutputTypes,
> =
$Type extends Schema.OutputObject ? Object<$SelectionSet, $Schema, $Type> :
$Type extends Schema.Scalar ? ReturnType<$Type['codec']['decode']> : // TODO use TS compiler API to extract this type at build time.
$Type extends Schema.Scalar.ScalarCodecless ? ReturnType<GetCodecForCodecless<$Type, $Schema>['codec']['decode']> :
$Type extends Schema.__typename ? $Type['value'] :
$Type extends Schema.Enum ? $Type['membersUnion'] :
$Type extends Schema.Interface ? Interface<$SelectionSet, $Schema, $Type> :
$Type extends Schema.Union ? Union<$SelectionSet, $Schema, $Type> :
TSErrorDescriptive<'FieldType', `Unknown type`, { $Type: $Type; $SelectionSet: $SelectionSet; $Schema:$Schema }>
$Node extends Schema.OutputObject ? OutputObject<$SelectionSet, $Schema, $Node> :
$Node extends Schema.Scalar ? Schema.Scalar.GetDecoded<$Node> : // TODO use TS compiler API to extract this type at build time.
$Node extends Schema.Scalar.ScalarCodecless ? Schema.Scalar.GetDecoded<GetCodecForCodecless<$Schema, $Node>> :
$Node extends Schema.__typename ? $Node['value'] :
$Node extends Schema.Enum ? $Node['membersUnion'] :
$Node extends Schema.Interface ? Interface<$SelectionSet, $Schema, $Node> :
$Node extends Schema.Union ? Union<$SelectionSet, $Schema, $Node> :
TSErrorDescriptive<'FieldType', `Unknown type`, { $Type: $Node; $SelectionSet: $SelectionSet; $Schema:$Schema }>

// dprint-ignore
type GetCodecForCodecless<
$Type extends Schema.Scalar.ScalarCodecless,
$Schema extends Schema
$Schema extends Schema,
$Node extends Schema.Scalar.ScalarCodecless
> =
$Type['name'] extends keyof $Schema['scalars']
? $Schema['scalars'][$Type['name']]
$Node['name'] extends keyof $Schema['scalars']['map']
? $Schema['scalars']['map'][$Node['name']]
: Schema.Scalar.String

// dprint-ignore
Expand Down
9 changes: 5 additions & 4 deletions src/documentBuilder/InferResult/OutputObject.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Simplify } from 'type-fest'
import type { ConditionalSimplify } from 'type-fest/source/conditional-simplify.js'
import type { StringKeyof } from '../../lib/prelude.js'
import type { TSErrorDescriptive } from '../../lib/ts-error.js'
import type { Schema } from '../../types/Schema/__.js'
Expand All @@ -7,13 +7,14 @@ import type { Alias } from './Alias.js'
import type { OutputField } from './OutputField.js'
import type { ScalarsWildcard } from './ScalarsWildcard.js'

export type Object<$SelectionSet, $Schema extends Schema, $Node extends Schema.OutputObject> =
export type OutputObject<$SelectionSet, $Schema extends Schema, $Node extends Schema.OutputObject> =
Select.SelectScalarsWildcard.IsSelectScalarsWildcard<$SelectionSet> extends true
// todo what about when scalars wildcard is combined with other fields like relations?
? ScalarsWildcard<$SelectionSet, $Schema, $Node>
: Simplify<
: ConditionalSimplify<
& SelectionNonSelectAlias<$SelectionSet, $Schema, $Node>
& Alias<$Schema, $Node, $SelectionSet>
& Alias<$Schema, $Node, $SelectionSet>,
$Schema['scalars']['typesDecoded']
>

type SelectionNonSelectAlias<$SelectionSet, $Schema extends Schema, $Node extends Schema.OutputObject> = {
Expand Down
7 changes: 5 additions & 2 deletions src/documentBuilder/InferResult/__.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import type { db } from '../../../tests/_/schemas/db.js'
import type { Schema } from '../../../tests/_/schemas/kitchen-sink/graffle/modules/Schema.js'
import type * as SelectionSets from '../../../tests/_/schemas/kitchen-sink/graffle/modules/SelectionSets.js'
import { assertEqual } from '../../lib/assert-equal.js'
import type { Registry } from '../../types/Schema/nodes/Scalar/helpers.js'
import type { InferResult } from './__.js'
import type { PickSelectsPositiveIndicatorAndNotSelectAlias } from './OutputObject.js'

type $<$SelectionSet extends SelectionSets.Query> = InferResult.Query<$SelectionSet, Schema>

type $WithDate<$SelectionSet extends SelectionSets.Query<{ Date: typeof Date }>> = InferResult.Query<
type $Registry = Registry.AddScalar<Registry.Empty, typeof Date>

type $WithDate<$SelectionSet extends SelectionSets.Query<$Registry>> = InferResult.Query<
$SelectionSet,
Schema<{ Date: typeof Date }>
Schema<$Registry>
>

// dprint-ignore
Expand Down
4 changes: 2 additions & 2 deletions src/documentBuilder/InferResult/root.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Grafaid } from '../../lib/grafaid/__.js'
import { type ExcludeNull } from '../../lib/prelude.js'
import type { Schema } from '../../types/Schema/__.js'
import type { Object } from './OutputObject.js'
import type { OutputObject } from './OutputObject.js'

export type RootViaObject<
$SelectionSet,
Expand Down Expand Up @@ -29,4 +29,4 @@ export type Root<
$SelectionSet,
$Schema extends Schema,
$RootTypeName extends Grafaid.Schema.RootTypeName,
> = Object<$SelectionSet, $Schema, ExcludeNull<$Schema['Root'][$RootTypeName]>>
> = OutputObject<$SelectionSet, $Schema, ExcludeNull<$Schema['Root'][$RootTypeName]>>
4 changes: 3 additions & 1 deletion src/documentBuilder/SelectGraphQLMapper/toGraphQL.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ type CasesDescriptiveQuery = [
]
const testEachQueryWithDescription = test.for.bind(test)<CasesDescriptiveQuery>

type QueryWithDate = SelectionSets.Query<Schema.Scalar.Registry.AddScalar<Schema.Scalar.Registry.Empty, typeof Date>>

type CasesDescriptiveQueryWithCustomScalars = [
description: string,
selectionSet: SelectionSets.Query<{ Date: typeof Date }>,
selectionSet: QueryWithDate,
options?: { operationName?: string },
]
const testEachQueryWithDescriptionWithCustomScalars = test.for.bind(test)<CasesDescriptiveQueryWithCustomScalars>
Expand Down
2 changes: 1 addition & 1 deletion src/extensions/CustomScalars/CustomScalars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const CustomScalars = () =>
// documentNode: true,
onRequest: (async ({ pack }) => {
const sddm = pack.input.state.config.schemaMap
const scalars = pack.input.state.scalars
const scalars = pack.input.state.scalars.map
if (!sddm) return pack()

const request = normalizeRequestToNode(pack.input.request)
Expand Down
7 changes: 6 additions & 1 deletion src/extensions/CustomScalars/decode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ import type { Graffle } from '../../../tests/_/schemas/kitchen-sink/graffle/__.j
import { Select } from '../../documentBuilder/Select/__.js'
import { SelectionSetGraphqlMapper } from '../../documentBuilder/SelectGraphQLMapper/__.js'
import { Grafaid } from '../../lib/grafaid/__.js'
import type { Schema } from '../../types/Schema/__.js'

type QueryWithDate = Graffle.SelectionSets.Query<
Schema.Scalar.Registry.AddScalar<Schema.Scalar.Registry.Empty, typeof Date>
>

type TestCase = [
describe: string,
query: Graffle.SelectionSets.Query<{ Date: typeof Date }>,
query: QueryWithDate,
responseData: object,
expectedData: object,
]
Expand Down
5 changes: 2 additions & 3 deletions src/extensions/CustomScalars/decode.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Kind } from 'graphql'
import { Schema } from '../../entrypoints/schema.js'
import type { RegisteredScalars } from '../../layers/6_client/fluent.js'
import type { Grafaid } from '../../lib/grafaid/__.js'
import { SchemaDrivenDataMap } from '../../types/SchemaDrivenDataMap/__.js'

Expand All @@ -23,7 +22,7 @@ export const decodeResultData = ({ request, data, sddm, scalars }: {
/**
* Registered custom scalars.
*/
scalars: RegisteredScalars
scalars: Schema.Scalar.ScalarMap
}) => {
const sddmOutputObject = sddm.roots[request.rootType]
if (!sddmOutputObject) return
Expand Down Expand Up @@ -54,7 +53,7 @@ const decodeResultValue = (input: {
value: Value
sddmNode: SchemaDrivenDataMap.OutputNodes
documentPart: null | Grafaid.Document.SelectionSetNode
scalars: RegisteredScalars
scalars: Schema.Scalar.ScalarMap
}): void => {
const { parentContext, value, sddmNode, documentPart, scalars } = input

Expand Down
7 changes: 6 additions & 1 deletion src/extensions/CustomScalars/encode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ import { Spy } from '../../../tests/_/SpyExtension.js'
import { Select } from '../../documentBuilder/Select/__.js'
import { SelectionSetGraphqlMapper } from '../../documentBuilder/SelectGraphQLMapper/__.js'
import { Grafaid } from '../../lib/grafaid/__.js'
import type { Schema } from '../../types/Schema/__.js'

type QueryWithDate = Graffle.SelectionSets.Query<
Schema.Scalar.Registry.AddScalar<Schema.Scalar.Registry.Empty, typeof Date>
>

type TestCase = [
description: string,
query: Graffle.SelectionSets.Query<{ Date: typeof Date }>,
query: QueryWithDate,
expectedVariables: object,
]

Expand Down
5 changes: 2 additions & 3 deletions src/extensions/CustomScalars/encode.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Schema } from '../../entrypoints/schema.js'
import type { RegisteredScalars } from '../../layers/6_client/fluent.js'
import { Grafaid } from '../../lib/grafaid/__.js'
import { SchemaDrivenDataMap } from '../../types/SchemaDrivenDataMap/__.js'

export const encodeRequestVariables = ({ sddm, request, scalars }: {
sddm: SchemaDrivenDataMap
scalars: RegisteredScalars
scalars: Schema.Scalar.ScalarMap
request: Grafaid.RequestAnalyzedDocumentNodeInput
}): void => {
const variableDefinitions = request.operation.variableDefinitions
Expand Down Expand Up @@ -36,7 +35,7 @@ const encodeInputFieldLike = (
argName: any,
argValue: any,
sddmNode: SchemaDrivenDataMap.InputNodes,
scalars: RegisteredScalars,
scalars: Schema.Scalar.ScalarMap,
) => {
/**
* The SDDM for custom scalars can take two forms:
Expand Down
Loading

0 comments on commit 2705620

Please sign in to comment.