diff --git a/src/Schema/core/Index.ts b/src/Schema/core/Index.ts index dc166a149..1982368d7 100644 --- a/src/Schema/core/Index.ts +++ b/src/Schema/core/Index.ts @@ -7,6 +7,6 @@ export interface Index { Subscription: null | Output.Object$2 } objects: Record - // todo unused? unions: Record + interfaces: Record } diff --git a/src/client/SelectionSet/SelectionSet.ts b/src/client/SelectionSet/SelectionSet.ts index f010aee58..68aa90ba8 100644 --- a/src/client/SelectionSet/SelectionSet.ts +++ b/src/client/SelectionSet/SelectionSet.ts @@ -89,7 +89,7 @@ type Arguments<$Field extends SomeField> = {} // dprint-ignore -type Interface<$Node extends Schema.Interface, $Index extends Schema.Index> = +export type Interface<$Node extends Schema.Interface, $Index extends Schema.Index> = & InterfaceDistributed<$Node['implementors'][number], $Index> & Fields< & $Node['fields'] @@ -109,7 +109,7 @@ type InterfaceDistributed<$Node extends Schema.Object$2, $Index extends Schema.I : never // dprint-ignore -type Union<$Node extends Schema.Union, $Index extends Schema.Index> = +export type Union<$Node extends Schema.Union, $Index extends Schema.Index> = & UnionDistributed<$Node['members'][number], $Index> & { __typename?: NoArgsIndicator } diff --git a/src/client/client.test.ts b/src/client/client.test.ts index d8317cbe6..8c1f0dc50 100644 --- a/src/client/client.test.ts +++ b/src/client/client.test.ts @@ -1,5 +1,5 @@ /* eslint-disable */ -import { beforeEach, describe, expect, test } from 'vitest' +import { expect, test } from 'vitest' import { setupMockServer } from '../../tests/raw/__helpers.js' import type { Index } from '../../tests/ts/_/schema/generated/Index.js' import { $Index as schemaIndex } from '../../tests/ts/_/schema/generated/SchemaRuntime.js' diff --git a/src/entrypoints/alpha/client.ts b/src/entrypoints/alpha/client.ts index 048d4632e..a36e224ab 100644 --- a/src/entrypoints/alpha/client.ts +++ b/src/entrypoints/alpha/client.ts @@ -1 +1,3 @@ export * from '../../client/client.js' +// todo need to export a generated version +export { create as createSelect } from '../../select.js' diff --git a/src/generator/code/index.ts b/src/generator/code/index.ts index 578539335..1960a56e6 100644 --- a/src/generator/code/index.ts +++ b/src/generator/code/index.ts @@ -23,6 +23,9 @@ export const generateIndex = (config: Config) => { unions: Code.objectFromEntries( config.typeMapByKind.GraphQLUnionType.map(_ => [_.name, `${namespace}.Union.${_.name}`]), ), + interfaces: Code.objectFromEntries( + config.typeMapByKind.GraphQLInterfaceType.map(_ => [_.name, `${namespace}.Interface.${_.name}`]), + ), }), ), ) diff --git a/src/select.test.ts b/src/select.test.ts new file mode 100644 index 000000000..3801c71e2 --- /dev/null +++ b/src/select.test.ts @@ -0,0 +1,13 @@ +import { expect, it } from 'vitest' +import type { Index } from '../tests/ts/_/schema/generated/Index.js' +import { create } from './select.js' + +it(`returns the input for any method name`, () => { + const select = create() as any // eslint-disable-line + expect(select.anything(1)).toEqual(1) // eslint-disable-line +}) + +it(`has type safe methods`, () => { + const select = create() + expect(select.Bar({ ___: { $defer: true, int: true } })).toEqual({ ___: { $defer: true, int: true } }) +}) diff --git a/src/select.ts b/src/select.ts new file mode 100644 index 000000000..72b1609e5 --- /dev/null +++ b/src/select.ts @@ -0,0 +1,35 @@ +import type { SelectionSet } from './client/SelectionSet/__.js' +import type { Exact } from './lib/prelude.js' +import type { Schema } from './Schema/__.js' + +// todo test +// dprint-ignore +export type Select<$Index extends Schema.Index> = +& { + [$RootTypeName in Schema.RootTypeName]: + <$SelectionSet extends object>(selectionSet: Exact<$SelectionSet, SelectionSet.Root<$Index, $RootTypeName>>) => + $SelectionSet + } +& { + [$Name in keyof $Index['objects']]: + <$SelectionSet extends object>(selectionSet: Exact<$SelectionSet, SelectionSet.Object<$Index['objects'][$Name], $Index>>) => + $SelectionSet + } +& { + [$Name in keyof $Index['unions']]: + <$SelectionSet extends object>(selectionSet: Exact<$SelectionSet, SelectionSet.Union<$Index['unions'][$Name], $Index>>) => + $SelectionSet + } +& { + [$Name in keyof Schema.Index['interfaces']]: + <$SelectionSet extends object>(selectionSet: Exact<$SelectionSet, SelectionSet.Interface<$Index['interfaces'][$Name], $Index>>) => + $SelectionSet + } + +export const create = <$Index extends Schema.Index>(): Select<$Index> => { + return idProxy as any +} + +const idProxy = new Proxy({}, { + get: () => (value: unknown) => value, +}) diff --git a/tests/ts/_/schema/generated/Index.ts b/tests/ts/_/schema/generated/Index.ts index e7f2c235d..cb0a235a4 100644 --- a/tests/ts/_/schema/generated/Index.ts +++ b/tests/ts/_/schema/generated/Index.ts @@ -24,4 +24,8 @@ export interface Index { FooBarUnion: Schema.Union.FooBarUnion lowerCaseUnion: Schema.Union.lowerCaseUnion } + interfaces: { + DateInterface1: Schema.Interface.DateInterface1 + Interface: Schema.Interface.Interface + } }