nexus/tests/integrations/kitchenSink/__app.ts

394 lines
8.4 KiB
TypeScript

import {
arg,
booleanArg,
connectionPlugin,
core,
declarativeWrappingPlugin,
directive,
dynamicInputMethod,
dynamicOutputMethod,
dynamicOutputProperty,
enumType,
extendType,
idArg,
inputObjectType,
interfaceType,
mutationType,
nonNull,
objectType,
queryType,
scalarType,
stringArg,
subscriptionField,
subscriptionType,
addDirective,
} from '../../../src'
import { mockStream } from '../../__helpers'
import './__typegen'
export const Node = interfaceType({
name: 'Node',
definition(t) {
t.nonNull.id('id', {
resolve: (source, args, ctx, info) => `${info.parentType.name}:${source.id}`,
sourceType: 'number',
})
},
resolveType(obj: any) {
return obj.__typename
},
})
export const typeDirective = directive({
name: 'TestTypeDirective',
locations: ['OBJECT', 'INTERFACE', 'ENUM', 'SCALAR'],
description: 'Testing type directives',
args: {
bool: booleanArg(),
},
})
export const fieldDirective = directive({
name: 'TestFieldDirective',
locations: ['FIELD_DEFINITION', 'INPUT_FIELD_DEFINITION'],
description: 'Testing the object directive',
args: {
bool: booleanArg(),
},
})
export const testAllDirective = directive({
name: 'TestAllDirective',
locations: core.SchemaDirectiveLocation,
description: 'Testing directive in all positions',
})
export const testRequiredArgDirective = directive({
name: 'TestRequiredArgDirective',
locations: ['OBJECT'],
description: 'Testing with required arg',
args: {
bool: nonNull(booleanArg()),
},
})
export const testRepeatableDirective = directive({
name: 'TestRepeatableDirective',
locations: core.SchemaDirectiveLocation,
description: 'Testing a repeatable directive',
isRepeatable: true,
})
export const scalar = scalarType({
name: 'MyCustomScalar',
description: 'No-Op scalar for testing purposes only',
asNexusMethod: 'myCustomScalar',
serialize() {},
directives: [testAllDirective],
})
export const query = queryType({
definition(t) {
t.string('foo', { resolve: () => 'bar' })
t.myCustomScalar('customScalar')
},
directives: [testRepeatableDirective, testRepeatableDirective],
})
const mockData = {
posts: [{ title: '', body: '' }],
user: { firstName: '', lastName: '' },
}
export const I = interfaceType({
name: 'I',
resolveType() {
return 'OfI'
},
definition(t) {
t.string('hello', {
extensions: {
extensionAdditionFromFieldConfig: true,
},
directives: [fieldDirective({ bool: true })],
})
},
})
export const i = objectType({
name: 'OfI',
definition(t) {
t.implements('I')
},
directives: [typeDirective],
})
export const i2 = objectType({
name: 'OfI2',
extensions: {
extensionAdditionFromTypeConfig: true,
},
definition(t) {
t.implements(Node)
t.implements('I')
t.modify('hello', {
extensions: {
extensionAdditionFromModifyMethod: true,
},
})
t.string('composite', {
resolve: (source) => `${source.fieldA} ${source.fieldB}`,
sourceType: [
{ name: 'fieldA', type: 'string' },
{ name: 'fieldB', type: 'string' },
],
})
},
})
export const dom = dynamicOutputMethod({
name: 'title',
typeDefinition: '(options: { escape: boolean }): void',
typeDescription: 'Title of the page, optionally escaped',
factory: ({ typeDef: t }) => {
t.string('title')
},
})
export const dim = dynamicInputMethod({
name: 'title',
factory: ({ typeDef: t }) => {
t.string('title')
},
})
export const dop = dynamicOutputProperty({
name: 'body',
typeDescription: 'adds a body (weirdly, as a getter)',
factory: ({ typeDef: t }) => {
t.string('body')
},
})
export const PostSearchInput = inputObjectType({
name: 'PostSearchInput',
definition(t) {
t.title()
t.string('body')
},
})
export const someArg = arg({
type: inputObjectType({
name: 'Something',
definition(t) {
t.nonNull.int('id')
},
}),
default: { id: 1 },
})
export const Post = objectType({
name: 'Post',
definition(t) {
t.title({ escape: true })
// tslint:disable-next-line: no-unused-expression
t.body
},
directives: [testRequiredArgDirective({ bool: true })],
})
export const User = objectType({
name: 'User',
definition(t) {
t.string('firstName', {
sourceType: 'string',
})
t.string('lastName', {
sourceType: 'string',
})
t.connectionField('posts', {
type: Post,
nodes() {
return mockData.posts
},
totalCount(root) {
if (!root.firstName) {
// root.firstName should be the source value here
throw new Error()
}
return 0
},
edgeFields: {
delta(root, args, ctx) {
if (root.cursor) {
// Cursor should be defined here
}
if (args.format === 'ms') {
return '5ms'
}
return '0.005s'
},
},
})
t.string('telephone', {
sourceType: { type: 'string', optional: true },
resolve: (source) => (source.telephone ? `+1 ${source.telephone}` : null),
})
},
})
export const Query = extendType({
type: 'Query',
definition(t) {
t.list.field('searchPosts', {
type: 'Post',
args: { input: PostSearchInput },
resolve: () => mockData.posts,
})
t.field('user', {
type: 'User',
args: {
id: idArg(),
status: enumType({
name: 'UserStatus',
members: [
{ name: 'ACTIVE', value: 'active' },
{ name: 'PENDING', value: 'pending' },
],
}).asArg({ default: 'active', directives: [testAllDirective] }),
},
resolve: () => mockData.user,
})
},
})
export const Mutation = mutationType({
definition(t) {
t.field('createUser', {
type: 'User',
args: { firstName: stringArg(), lastName: stringArg() },
resolve: (_root) => ({ firstName: '', lastName: '' }),
})
},
})
export const Subscription2 = extendType({
type: 'Subscription',
definition(t) {
t.boolean('someBooleanFromExtendType', {
subscribe() {
return mockStream(10, true, (b) => b)
},
resolve: (event: boolean) => {
return event
},
})
},
})
export const Subscription3 = subscriptionField((t) => {
t.boolean('someBooleanFromSubscriptionField', {
subscribe() {
return mockStream(10, true, (b) => b)
},
resolve: (event: boolean) => {
return event
},
})
})
export const Subscription = subscriptionType({
definition(t) {
// lists
t.list.field('someFields', {
type: 'Int',
subscribe() {
return mockStream(10, 0, (int) => int - 1)
},
resolve: (event: number) => {
return [event]
},
})
t.list.int('someInts', {
subscribe() {
return mockStream(10, 0, (int) => int + 1)
},
resolve: (event: number) => {
return [event]
},
})
// singular
t.field('someField', {
type: 'Int',
subscribe() {
return mockStream(10, 0, (int) => int - 1)
},
resolve: (event: number) => {
return event
},
})
t.int('someInt', {
subscribe() {
return mockStream(10, 0, (int) => int + 1)
},
resolve: (event: number) => {
return event
},
directives: [testAllDirective],
})
t.string('someString', {
subscribe() {
return mockStream(10, '', (str) => str + '!')
},
resolve: (event: string) => {
return event
},
directives: [addDirective('TestFieldDirective', { bool: true })],
})
t.float('someFloat', {
subscribe() {
return mockStream(10, 0.5, (f) => f)
},
resolve: (event: number) => {
return event
},
})
t.boolean('someBoolean', {
subscribe() {
return mockStream(10, true, (b) => b)
},
resolve: (event: boolean) => {
return event
},
})
t.id('someID', {
subscribe() {
return mockStream(10, 'abc', (id) => id)
},
resolve: (event: string) => {
return event
},
})
},
})
export const plugins = [
declarativeWrappingPlugin({ disable: true }),
connectionPlugin({
extendEdge: {
delta: {
type: 'String',
args: {
format: 'String',
},
},
},
extendConnection: {
totalCount: {
type: nonNull('Int'),
},
},
}),
]