Skip to content

Commit ad17018

Browse files
committed
Easier context binding
1 parent 9cc3cf0 commit ad17018

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+883
-852
lines changed

examples/auth-magic-link/schema.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { g, list } from '@keystone-6/core'
1+
import { gWithContext, list } from '@keystone-6/core'
22
import { allowAll, denyAll } from '@keystone-6/core/access'
33
import { password, text, timestamp } from '@keystone-6/core/fields'
44
import type { Lists, Context } from '.keystone/types'
55

66
import { randomBytes } from 'node:crypto'
77

8+
const g = gWithContext<Context>()
9+
type g<T> = gWithContext.infer<T>
10+
811
export type Session = {
912
itemId: string
1013
}
@@ -107,7 +110,7 @@ export const extendGraphqlSchema = g.extend(base => {
107110
type: g.nonNull(g.Boolean), // always true
108111
args: { userId: g.arg({ type: g.nonNull(g.String) }) },
109112

110-
async resolve(args, { userId }, context: Context) {
113+
async resolve(args, { userId }, context) {
111114
// run asynchronously to reduce timing attacks
112115
;(async function () {
113116
const ott = randomBytes(16).toString('base64url')
@@ -141,7 +144,7 @@ export const extendGraphqlSchema = g.extend(base => {
141144
token: g.arg({ type: g.nonNull(g.String) }),
142145
},
143146

144-
async resolve(args, { userId, token }, context: Context) {
147+
async resolve(args, { userId, token }, context) {
145148
if (!context.sessionStrategy)
146149
throw new Error('No session implementation available on context')
147150

examples/extend-graphql-schema-graphql-ts/schema.ts

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { g, list } from '@keystone-6/core'
1+
import { gWithContext, list } from '@keystone-6/core'
22
import { allowAll } from '@keystone-6/core/access'
33
import { select, relationship, text, timestamp } from '@keystone-6/core/fields'
4-
import { type Context, type Lists } from '.keystone/types'
4+
import type { Context, Lists } from '.keystone/types'
5+
6+
const g = gWithContext<Context>()
7+
type g<T> = gWithContext.infer<T>
58

69
export const lists = {
710
Post: list({
@@ -37,23 +40,23 @@ export const extendGraphqlSchema = g.extend(base => {
3740
fields: {
3841
draft: g.field({
3942
type: g.Int,
40-
resolve({ authorId }, args, context: Context) {
43+
resolve({ authorId }, args, context) {
4144
return context.query.Post.count({
4245
where: { author: { id: { equals: authorId } }, status: { equals: 'draft' } },
4346
})
4447
},
4548
}),
4649
published: g.field({
4750
type: g.Int,
48-
resolve({ authorId }, args, context: Context) {
51+
resolve({ authorId }, args, context) {
4952
return context.query.Post.count({
5053
where: { author: { id: { equals: authorId } }, status: { equals: 'published' } },
5154
})
5255
},
5356
}),
5457
latest: g.field({
5558
type: base.object('Post'),
56-
async resolve({ authorId }, args, context: Context) {
59+
async resolve({ authorId }, args, context) {
5760
const [post] = await context.db.Post.findMany({
5861
take: 1,
5962
orderBy: { publishDate: 'desc' },
@@ -72,7 +75,7 @@ export const extendGraphqlSchema = g.extend(base => {
7275
// with the name provided or throw if it doesn't exist
7376
type: base.object('Post'),
7477
args: { id: g.arg({ type: g.nonNull(g.ID) }) },
75-
resolve(source, { id }, context: Context) {
78+
resolve(source, { id }, context) {
7679
// Note we use `context.db.Post` here as we have a return type
7780
// of Post, and this API provides results in the correct format.
7881
// If you accidentally use `context.query.Post` here you can expect problems
@@ -90,7 +93,7 @@ export const extendGraphqlSchema = g.extend(base => {
9093
banPost: g.field({
9194
type: base.object('Post'),
9295
args: { id: g.arg({ type: g.nonNull(g.ID) }) },
93-
resolve(source, { id }, context: Context) {
96+
resolve(source, { id }, context) {
9497
return context.db.Post.updateOne({
9598
where: { id },
9699
data: { status: 'banned' },
@@ -107,7 +110,7 @@ export const extendGraphqlSchema = g.extend(base => {
107110
id: g.arg({ type: g.nonNull(g.ID) }),
108111
seconds: g.arg({ type: g.nonNull(g.Int), defaultValue: 600 }),
109112
},
110-
resolve(source, { id, seconds }, context: Context) {
113+
resolve(source, { id, seconds }, context) {
111114
const cutoff = new Date(Date.now() - seconds * 1000)
112115

113116
// Note we use `context.db.Post` here as we have a return type

examples/graphql-codegen/schema.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
/* eslint-disable @typescript-eslint/consistent-type-imports */
2-
import { list, g } from '@keystone-6/core'
2+
import { list, gWithContext } from '@keystone-6/core'
33
import { relationship, text, timestamp, virtual } from '@keystone-6/core/fields'
44
import { allowAll } from '@keystone-6/core/access'
55
import { graphql } from './gql'
66

7-
import type { Lists } from '.keystone/types'
7+
import type { Lists, Context } from '.keystone/types'
8+
9+
const g = gWithContext<Context>()
10+
type g<T> = gWithContext.infer<T>
811

912
const LatestPostQuery = graphql(/* GraphQL */ `
1013
query LastestPostQuery($id: ID!) {

examples/graphql-gql.tada/schema.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { list, g } from '@keystone-6/core'
1+
import { list, gWithContext } from '@keystone-6/core'
22
import { relationship, text, timestamp, virtual } from '@keystone-6/core/fields'
33
import { allowAll } from '@keystone-6/core/access'
44
import { graphql } from './tada'
5-
import type { Lists } from '.keystone/types'
5+
import type { Lists, Context } from '.keystone/types'
66

77
const LatestPostQuery = graphql(`
88
query LastestPostQuery($id: ID!) {
@@ -15,6 +15,9 @@ const LatestPostQuery = graphql(`
1515
}
1616
`)
1717

18+
const g = gWithContext<Context>()
19+
type g<T> = gWithContext.infer<T>
20+
1821
export const lists: Lists = {
1922
Post: list({
2023
access: allowAll,

examples/graphql-ts-gql/schema.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/* eslint-disable @typescript-eslint/consistent-type-imports */
2-
import { list, g } from '@keystone-6/core'
2+
import { list, gWithContext } from '@keystone-6/core'
33
import { relationship, text, timestamp, virtual } from '@keystone-6/core/fields'
44
import { allowAll } from '@keystone-6/core/access'
55
import { gql } from '@ts-gql/tag/no-transform'
66

7-
import type { Lists } from '.keystone/types'
7+
import type { Lists, Context } from '.keystone/types'
88

99
const LatestPostQuery = gql`
1010
query LastestPostQuery($id: ID!) {
@@ -18,6 +18,9 @@ const LatestPostQuery = gql`
1818
}
1919
` as import('./__generated__/ts-gql/LastestPostQuery').type
2020

21+
const g = gWithContext<Context>()
22+
type g<T> = gWithContext.infer<T>
23+
2124
export const lists = {
2225
Post: list({
2326
access: allowAll,

examples/number-fields/schema.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { list, g } from '@keystone-6/core'
1+
import { list, gWithContext } from '@keystone-6/core'
22
import { bigInt, float, integer, virtual } from '@keystone-6/core/fields'
33
import { allowAll } from '@keystone-6/core/access'
4-
import type { Lists } from '.keystone/types'
4+
import type { Lists, Context } from '.keystone/types'
5+
6+
const g = gWithContext<Context>()
7+
type g<T> = gWithContext.infer<T>
58

69
export const lists = {
710
Example: list({

examples/transactions/schema.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
import { g, list } from '@keystone-6/core'
1+
import { gWithContext, list } from '@keystone-6/core'
22
import { allowAll } from '@keystone-6/core/access'
33
import { text, integer, relationship, timestamp, virtual } from '@keystone-6/core/fields'
4-
import { type Context, type Lists } from '.keystone/types'
4+
import type { Lists, Context } from '.keystone/types'
5+
6+
const g = gWithContext<Context>()
7+
type g<T> = gWithContext.infer<T>
58

69
export const extendGraphqlSchema = g.extend(base => {
710
return {
811
mutation: {
912
submitOrder: g.field({
1013
type: base.object('Order'),
1114
args: {},
12-
async resolve(source, {}, context: Context) {
15+
async resolve(source, {}, context) {
1316
// TODO: this should come from GraphQL arguments
1417
const orderInput = [
1518
{ sku: '123', count: 1 },

examples/usecase-relationship-union/schema.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { list, group, g } from '@keystone-6/core'
1+
import { list, group, gWithContext } from '@keystone-6/core'
22
import { allowAll } from '@keystone-6/core/access'
33
import { text, relationship, virtual } from '@keystone-6/core/fields'
4-
import type { Lists } from '.keystone/types'
4+
import type { Lists, Context } from '.keystone/types'
55

66
function ifUnsetHideUI<Key extends string>(field: Key) {
77
return {
@@ -15,6 +15,9 @@ function ifUnsetHideUI<Key extends string>(field: Key) {
1515
}
1616
}
1717

18+
const g = gWithContext<Context>()
19+
type g<T> = gWithContext.infer<T>
20+
1821
export const lists: Lists = {
1922
Post: list({
2023
access: allowAll,

examples/virtual-field/schema.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
import { list, g } from '@keystone-6/core'
1+
import { list, gWithContext } from '@keystone-6/core'
22
import { text, checkbox, virtual } from '@keystone-6/core/fields'
33
import { allowAll } from '@keystone-6/core/access'
44

5-
import type { Lists } from '.keystone/types'
5+
import type { Lists, Context } from '.keystone/types'
6+
7+
const g = gWithContext<Context>()
8+
type g<T> = gWithContext.infer<T>
69

710
export const lists = {
811
Post: list({

packages/auth/src/gql/getBaseAuthSchema.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { BaseItem, KeystoneContext } from '@keystone-6/core/types'
22
import { g } from '@keystone-6/core'
33
import { getPasswordFieldKDF } from '@keystone-6/core/fields/types/password'
44
import type { AuthGqlNames } from '../types'
5+
import type { BaseSchemaMeta } from '@keystone-6/core/graphql-ts'
56

67
const AUTHENTICATION_FAILURE = {
78
code: 'FAILURE',
@@ -19,7 +20,7 @@ export function getBaseAuthSchema<I extends string, S extends string>({
1920
identityField: I
2021
secretField: S
2122
gqlNames: AuthGqlNames
22-
base: g.BaseSchemaMeta
23+
base: BaseSchemaMeta
2324
}) {
2425
const kdf = getPasswordFieldKDF(base.schema, listKey, secretField)
2526
if (!kdf) {

packages/auth/src/gql/getInitFirstItemSchema.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { BaseItem, KeystoneContext } from '@keystone-6/core/types'
22
import { g } from '@keystone-6/core'
33
import { assertInputObjectType, GraphQLInputObjectType, type GraphQLSchema } from 'graphql'
44
import { type AuthGqlNames, type InitFirstItemConfig } from '../types'
5+
import type { Extension } from '@keystone-6/core/graphql-ts'
56

67
const AUTHENTICATION_FAILURE = 'Authentication failed.' as const
78

@@ -18,12 +19,14 @@ export function getInitFirstItemSchema({
1819
defaultItemData: InitFirstItemConfig<any>['itemData']
1920
gqlNames: AuthGqlNames
2021
graphQLSchema: GraphQLSchema
21-
ItemAuthenticationWithPasswordSuccess: g.ObjectType<{
22-
item: BaseItem
23-
sessionToken: string
24-
}>
22+
ItemAuthenticationWithPasswordSuccess: g<
23+
typeof g.object<{
24+
item: BaseItem
25+
sessionToken: string
26+
}>
27+
>
2528
// TODO: return type required by pnpm :(
26-
}): g.Extension {
29+
}): Extension {
2730
const createInputConfig = assertInputObjectType(
2831
graphQLSchema.getType(`${listKey}CreateInput`)
2932
).toConfig()

packages/cloudinary/src/index.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { jsonFieldTypePolyfilledForSQLite } from '@keystone-6/core/types'
44
import { g } from '@keystone-6/core'
55
import type Cloudinary from 'cloudinary'
66
import { v2 as cloudinary } from 'cloudinary'
7+
import type { GArg, InferValueFromArg } from '@keystone-6/core/graphql-ts'
78

89
type StoredFile = {
910
id: string
@@ -74,7 +75,7 @@ type CloudinaryImage_File = {
7475
encoding: string
7576
publicUrl: string
7677
publicUrlTransformed: (args: {
77-
transformation: g.InferValueFromArg<g.Arg<typeof CloudinaryImageFormat>>
78+
transformation: InferValueFromArg<GArg<typeof CloudinaryImageFormat>>
7879
}) => string
7980
filesize: number
8081
width: number
@@ -119,7 +120,7 @@ export function cloudinaryImage<ListTypeInfo extends BaseListTypeInfo>({
119120

120121
const inputArg = g.arg({ type: g.Upload })
121122
async function resolveInput(
122-
uploadData: g.InferValueFromArg<typeof inputArg>
123+
uploadData: InferValueFromArg<typeof inputArg>
123124
): Promise<StoredFile | undefined | null> {
124125
if (uploadData === null) return null
125126
if (uploadData === undefined) return
@@ -181,7 +182,7 @@ export function cloudinaryImage<ListTypeInfo extends BaseListTypeInfo>({
181182
publicUrlTransformed: ({
182183
transformation,
183184
}: {
184-
transformation: g.InferValueFromArg<g.Arg<typeof CloudinaryImageFormat>>
185+
transformation: InferValueFromArg<GArg<typeof CloudinaryImageFormat>>
185186
}) => {
186187
if (!val._meta) return null
187188

packages/core/graphql-ts/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"main": "dist/keystone-6-core-graphql-ts.cjs.js",
3+
"module": "dist/keystone-6-core-graphql-ts.esm.js"
4+
}

packages/core/package.json

+8-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
"module": "./testing/dist/keystone-6-core-testing.esm.js",
3232
"default": "./testing/dist/keystone-6-core-testing.cjs.js"
3333
},
34+
"./graphql-ts": {
35+
"types": "./graphql-ts/dist/keystone-6-core-graphql-ts.cjs.js",
36+
"module": "./graphql-ts/dist/keystone-6-core-graphql-ts.esm.js",
37+
"default": "./graphql-ts/dist/keystone-6-core-graphql-ts.cjs.js"
38+
},
3439
"./scripts/cli": {
3540
"types": "./scripts/cli/dist/keystone-6-core-scripts-cli.cjs.js",
3641
"module": "./scripts/cli/dist/keystone-6-core-scripts-cli.esm.js",
@@ -235,8 +240,8 @@
235240
"@aws-sdk/lib-storage": "^3.83.0",
236241
"@aws-sdk/s3-request-presigner": "^3.83.0",
237242
"@babel/runtime": "^7.24.7",
238-
"@graphql-ts/extend": "https://pkg.pr.new/Thinkmill/graphql-ts/@graphql-ts/extend@5eafeea",
239-
"@graphql-ts/schema": "https://pkg.pr.new/Thinkmill/graphql-ts/@graphql-ts/schema@5eafeea",
243+
"@graphql-ts/extend": "https://pkg.pr.new/Thinkmill/graphql-ts/@graphql-ts/extend@fc1c43b",
244+
"@graphql-ts/schema": "https://pkg.pr.new/Thinkmill/graphql-ts/@graphql-ts/schema@fc1c43b",
240245
"@graphql-typed-document-node/core": "^3.1.2",
241246
"@hapi/iron": "^7.0.0",
242247
"@internationalized/date": "^3.5.5",
@@ -311,6 +316,7 @@
311316
"context.ts",
312317
"testing.ts",
313318
"session.ts",
319+
"graphql-ts.ts",
314320
"scripts/index.ts",
315321
"scripts/cli.ts",
316322
"admin-ui/components/index.ts",

0 commit comments

Comments
 (0)