diff --git a/.changeset/old-buttons-wave.md b/.changeset/old-buttons-wave.md new file mode 100644 index 00000000000..e8a544106ad --- /dev/null +++ b/.changeset/old-buttons-wave.md @@ -0,0 +1,5 @@ +--- +"@keystone-6/core": major +--- + +The `Session` type is now set by augmenting the `Session` interface in `.keystone/types` instead of being a generic on various types exported by `.keystone/types` diff --git a/examples/auth-magic-link/keystone.ts b/examples/auth-magic-link/keystone.ts index b18cdd6f264..c1c33816a1b 100644 --- a/examples/auth-magic-link/keystone.ts +++ b/examples/auth-magic-link/keystone.ts @@ -1,7 +1,7 @@ import { config } from '@keystone-6/core' import { statelessSessions } from '@keystone-6/core/session' import { createAuth } from '@keystone-6/auth' -import { type Session, lists, extendGraphqlSchema } from './schema' +import { lists, extendGraphqlSchema } from './schema' import type { TypeInfo } from '.keystone/types' // WARNING: this example is for demonstration purposes only @@ -38,7 +38,7 @@ const { withAuth } = createAuth({ }, }) -export default withAuth>( +export default withAuth( config({ db: { provider: 'sqlite', diff --git a/examples/auth-magic-link/schema.ts b/examples/auth-magic-link/schema.ts index 326d9af7d9e..67a3dda3ccb 100644 --- a/examples/auth-magic-link/schema.ts +++ b/examples/auth-magic-link/schema.ts @@ -1,15 +1,18 @@ import { gWithContext, list } from '@keystone-6/core' import { allowAll, denyAll } from '@keystone-6/core/access' import { password, text, timestamp } from '@keystone-6/core/fields' -import type { Lists, Context } from '.keystone/types' +import type { Lists, Context, Session } from '.keystone/types' import { randomBytes } from 'node:crypto' const g = gWithContext() type g = gWithContext.infer -export type Session = { - itemId: string +declare module '.keystone/types' { + interface Session { + itemId: string + listKey: string + } } function hasSession({ session }: { session?: Session }) { @@ -83,7 +86,7 @@ export const lists = { oneTimeTokenCreatedAt: timestamp({ ...hiddenField }), }, }), -} satisfies Lists +} satisfies Lists // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted @@ -176,7 +179,7 @@ export const extendGraphqlSchema = g.extend(base => { await context.sessionStrategy.start({ context, data: { - listkey: 'User', + listKey: 'User', itemId: userId, }, }) diff --git a/examples/auth/keystone.ts b/examples/auth/keystone.ts index 293b0ec26f6..73ce4c6b3d2 100644 --- a/examples/auth/keystone.ts +++ b/examples/auth/keystone.ts @@ -1,7 +1,7 @@ import { config } from '@keystone-6/core' import { statelessSessions } from '@keystone-6/core/session' import { createAuth } from '@keystone-6/auth' -import { type Session, lists } from './schema' +import { lists } from './schema' import type { TypeInfo } from '.keystone/types' // WARNING: this example is for demonstration purposes only @@ -47,7 +47,7 @@ const { withAuth } = createAuth({ sessionData: 'isAdmin', }) -export default withAuth>( +export default withAuth( config({ db: { provider: 'sqlite', diff --git a/examples/auth/schema.ts b/examples/auth/schema.ts index 5118a36da6b..52d817d0909 100644 --- a/examples/auth/schema.ts +++ b/examples/auth/schema.ts @@ -1,16 +1,17 @@ import { list } from '@keystone-6/core' import { allowAll, denyAll } from '@keystone-6/core/access' import { text, checkbox, password } from '@keystone-6/core/fields' -import type { Lists } from '.keystone/types' +import type { Lists, Session } from '.keystone/types' // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted // or tested for any particular usage - -export type Session = { - itemId: string - data: { - isAdmin: boolean +declare module '.keystone/types' { + interface Session { + itemId: string + data: { + isAdmin: boolean + } } } @@ -156,4 +157,4 @@ export const lists = { }), }, }), -} satisfies Lists +} satisfies Lists diff --git a/examples/custom-output-paths/my-types.ts b/examples/custom-output-paths/my-types.ts index 49f1049e7fc..3e75d829ece 100644 --- a/examples/custom-output-paths/my-types.ts +++ b/examples/custom-output-paths/my-types.ts @@ -135,11 +135,13 @@ type ResolvedPostUpdateInput = { publishDate?: import('./node_modules/myprisma').Prisma.PostUpdateInput['publishDate'] } +export interface Session {} + export declare namespace Lists { - export type Post = import('@keystone-6/core/types').ListConfig> + export type Post = import('@keystone-6/core/types').ListConfig namespace Post { export type Item = import('./node_modules/myprisma').Post - export type TypeInfo = { + export type TypeInfo = { key: 'Post' isSingleton: false fields: 'id' | 'title' | 'content' | 'publishDate' @@ -156,25 +158,25 @@ export declare namespace Lists { create: ResolvedPostCreateInput update: ResolvedPostUpdateInput } - all: __TypeInfo + all: __TypeInfo } } } -export type Context = import('@keystone-6/core/types').KeystoneContext> -export type Config = import('@keystone-6/core/types').KeystoneConfig> +export type Context = import('@keystone-6/core/types').KeystoneContext +export type Config = import('@keystone-6/core/types').KeystoneConfig -export type TypeInfo = { +export type TypeInfo = { lists: { - readonly Post: Lists.Post.TypeInfo + readonly Post: Lists.Post.TypeInfo } prisma: import('./node_modules/myprisma').PrismaClient session: Session } -type __TypeInfo = TypeInfo +type __TypeInfo = TypeInfo -export type Lists = { - [Key in keyof TypeInfo['lists']]?: import('@keystone-6/core/types').ListConfig['lists'][Key]> +export type Lists = { + [Key in keyof TypeInfo['lists']]?: import('@keystone-6/core/types').ListConfig } & Record> export {} diff --git a/examples/custom-session-invalidation/keystone.ts b/examples/custom-session-invalidation/keystone.ts index 3f0a0e54310..698f278c783 100644 --- a/examples/custom-session-invalidation/keystone.ts +++ b/examples/custom-session-invalidation/keystone.ts @@ -1,8 +1,8 @@ import { config } from '@keystone-6/core' import { statelessSessions } from '@keystone-6/core/session' import { createAuth } from '@keystone-6/auth' -import { type Session, lists } from './schema' -import type { Config, Context, TypeInfo } from '.keystone/types' +import { lists } from './schema' +import type { Config, Context, TypeInfo, Session } from '.keystone/types' // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted @@ -32,7 +32,7 @@ const { withAuth } = createAuth({ sessionData: 'passwordChangedAt', }) -function withSessionInvalidation(config: Config): Config { +function withSessionInvalidation(config: Config): Config { const existingSessionStrategy = config.session! return { diff --git a/examples/custom-session-invalidation/schema.ts b/examples/custom-session-invalidation/schema.ts index 380301bbac0..a9c0288352b 100644 --- a/examples/custom-session-invalidation/schema.ts +++ b/examples/custom-session-invalidation/schema.ts @@ -1,20 +1,22 @@ import { list } from '@keystone-6/core' import { denyAll, unfiltered } from '@keystone-6/core/access' import { text, password, timestamp } from '@keystone-6/core/fields' -import type { Lists } from '.keystone/types' +import type { Lists, Session } from '.keystone/types' // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted // or tested for any particular usage // needs to be compatible with withAuth -export type Session = { - listKey: string - itemId: string - data: { - passwordChangedAt: string +declare module '.keystone/types' { + interface Session { + listKey: string + itemId: string + data: { + passwordChangedAt: string + } + startedAt: number } - startedAt: number } function hasSession({ session }: { session?: Session }) { @@ -85,4 +87,4 @@ export const lists = { }, }, }), -} satisfies Lists +} satisfies Lists diff --git a/examples/custom-session-jwt/keystone.ts b/examples/custom-session-jwt/keystone.ts index 15065ea0829..7c83edfac2b 100644 --- a/examples/custom-session-jwt/keystone.ts +++ b/examples/custom-session-jwt/keystone.ts @@ -1,7 +1,7 @@ import jwt from 'jsonwebtoken' import { config } from '@keystone-6/core' -import { lists, type Session } from './schema' -import type { Context, TypeInfo } from '.keystone/types' +import { lists } from './schema' +import type { Context, TypeInfo, Session } from '.keystone/types' // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted diff --git a/examples/custom-session-jwt/schema.ts b/examples/custom-session-jwt/schema.ts index 84f10c2c187..fb7d8e24486 100644 --- a/examples/custom-session-jwt/schema.ts +++ b/examples/custom-session-jwt/schema.ts @@ -1,11 +1,13 @@ import { list } from '@keystone-6/core' import { allowAll, unfiltered, allOperations } from '@keystone-6/core/access' import { checkbox, text } from '@keystone-6/core/fields' -import type { Lists } from '.keystone/types' +import type { Lists, Session } from '.keystone/types' -export type Session = { - id: string - admin: boolean +declare module '.keystone/types' { + interface Session { + id: string + admin: boolean + } } function hasSession({ session }: { session?: Session }) { @@ -61,4 +63,4 @@ export const lists = { admin: checkbox(), }, }), -} satisfies Lists +} satisfies Lists diff --git a/examples/custom-session-next-auth/keystone.ts b/examples/custom-session-next-auth/keystone.ts index 121a2e023d9..8e012d63d0e 100644 --- a/examples/custom-session-next-auth/keystone.ts +++ b/examples/custom-session-next-auth/keystone.ts @@ -1,14 +1,14 @@ import { config } from '@keystone-6/core' import { lists } from './schema' -import { type Session, nextAuthSessionStrategy } from './session' +import { nextAuthSessionStrategy } from './session' import type { TypeInfo } from '.keystone/types' // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted // or tested for any particular usage -export default config>({ +export default config({ db: { provider: 'sqlite', url: process.env.DATABASE_URL || 'file:./keystone-example.db', diff --git a/examples/custom-session-next-auth/schema.ts b/examples/custom-session-next-auth/schema.ts index 15b8a5307c1..a3ee7c8431e 100644 --- a/examples/custom-session-next-auth/schema.ts +++ b/examples/custom-session-next-auth/schema.ts @@ -1,8 +1,7 @@ import { denyAll, allOperations } from '@keystone-6/core/access' import { list } from '@keystone-6/core' import { text, relationship } from '@keystone-6/core/fields' -import type { Session } from './session' -import type { Lists } from '.keystone/types' +import type { Lists, Session } from '.keystone/types' // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted @@ -43,4 +42,4 @@ export const lists = { posts: relationship({ ref: 'Post.author', many: true }), }, }), -} satisfies Lists +} satisfies Lists diff --git a/examples/custom-session-next-auth/session.ts b/examples/custom-session-next-auth/session.ts index 40a0012a6b9..05cf6fa9dea 100644 --- a/examples/custom-session-next-auth/session.ts +++ b/examples/custom-session-next-auth/session.ts @@ -40,8 +40,10 @@ export const nextAuthOptions = { ], } -export type Session = { - id: string +declare module '.keystone/types' { + interface Session { + id: string + } } export const nextAuthSessionStrategy = { diff --git a/examples/custom-session-passport/auth.ts b/examples/custom-session-passport/auth.ts index 12e79367374..cea6643c270 100644 --- a/examples/custom-session-passport/auth.ts +++ b/examples/custom-session-passport/auth.ts @@ -7,10 +7,11 @@ import { type VerifyCallback } from 'passport-oauth2' import { Strategy, type StrategyOptions, type Profile } from 'passport-github2' import { type Author } from 'myprisma' -import { type TypeInfo } from '.keystone/types' - -export type Session = Author +import type { Session, TypeInfo } from '.keystone/types' +declare module '.keystone/types' { + export interface Session extends Author {} +} export const session = statelessSessions({ maxAge: 60 * 60 * 24 * 30, secret: process.env.SESSION_SECRET!, @@ -30,7 +31,7 @@ const options: StrategyOptions = { callbackURL: 'http://localhost:3000/auth/github/callback', } -export function passportMiddleware(commonContext: KeystoneContext>): Router { +export function passportMiddleware(commonContext: KeystoneContext): Router { const router = Router() const instance = new Passport() const strategy = new Strategy( diff --git a/examples/custom-session-passport/keystone.ts b/examples/custom-session-passport/keystone.ts index 7c1cc447aa6..01a20213818 100644 --- a/examples/custom-session-passport/keystone.ts +++ b/examples/custom-session-passport/keystone.ts @@ -3,9 +3,9 @@ import 'dotenv/config' import { config } from '@keystone-6/core' import { type TypeInfo } from '.keystone/types' import { lists } from './schema' -import { type Session, session, passportMiddleware } from './auth' +import { session, passportMiddleware } from './auth' -export default config>({ +export default config({ db: { provider: 'sqlite', url: 'file:./keystone.db', diff --git a/examples/custom-session-passport/schema.ts b/examples/custom-session-passport/schema.ts index f84a7320ea5..cff72ac2764 100644 --- a/examples/custom-session-passport/schema.ts +++ b/examples/custom-session-passport/schema.ts @@ -1,9 +1,7 @@ import { denyAll, allOperations } from '@keystone-6/core/access' import { list } from '@keystone-6/core' import { text, relationship } from '@keystone-6/core/fields' -import type { Lists } from '.keystone/types' - -import type { Session } from './auth' +import type { Lists, Session } from '.keystone/types' // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted @@ -44,4 +42,4 @@ export const lists = { posts: relationship({ ref: 'Post.author', many: true }), }, }), -} satisfies Lists +} satisfies Lists diff --git a/examples/custom-session-redis/keystone.ts b/examples/custom-session-redis/keystone.ts index 236d796f8af..dc37c3954e0 100644 --- a/examples/custom-session-redis/keystone.ts +++ b/examples/custom-session-redis/keystone.ts @@ -2,8 +2,8 @@ import { config } from '@keystone-6/core' import { storedSessions } from '@keystone-6/core/session' import { createAuth } from '@keystone-6/auth' import { createClient } from '@redis/client' -import { lists, type Session } from './schema' -import type { TypeInfo } from '.keystone/types' +import { lists } from './schema' +import type { TypeInfo, Session } from '.keystone/types' // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted @@ -57,7 +57,7 @@ function redisSessionStrategy() { } export default withAuth( - config>({ + config({ db: { provider: 'sqlite', url: process.env.DATABASE_URL || 'file:./keystone-example.db', diff --git a/examples/custom-session-redis/schema.ts b/examples/custom-session-redis/schema.ts index f016db08c4c..6e5a5a4d77c 100644 --- a/examples/custom-session-redis/schema.ts +++ b/examples/custom-session-redis/schema.ts @@ -1,18 +1,20 @@ import { list } from '@keystone-6/core' import { unfiltered } from '@keystone-6/core/access' import { text, password } from '@keystone-6/core/fields' -import type { Lists } from '.keystone/types' +import type { Lists, Session } from '.keystone/types' // WARNING: this example is for demonstration purposes only // as with each of our examples, it has not been vetted // or tested for any particular usage // needs to be compatible with withAuth -export type Session = { - listKey: string - itemId: string - data: { - something: string +declare module '.keystone/types' { + interface Session { + listKey: string + itemId: string + data: { + something: string + } } } @@ -62,4 +64,4 @@ export const lists = { }), }, }), -} satisfies Lists +} satisfies Lists diff --git a/examples/custom-session/keystone.ts b/examples/custom-session/keystone.ts index 7d2b041d4a0..4a78bc0203d 100644 --- a/examples/custom-session/keystone.ts +++ b/examples/custom-session/keystone.ts @@ -1,6 +1,6 @@ import { config } from '@keystone-6/core' -import { lists, type Session } from './schema' -import type { Context, TypeInfo } from '.keystone/types' +import { lists } from './schema' +import type { Context, TypeInfo, Session } from '.keystone/types' const sillySessionStrategy = { async get({ context }: { context: Context }): Promise { diff --git a/examples/custom-session/schema.ts b/examples/custom-session/schema.ts index b857b058934..5dd8245bb83 100644 --- a/examples/custom-session/schema.ts +++ b/examples/custom-session/schema.ts @@ -1,11 +1,13 @@ import { list } from '@keystone-6/core' import { allowAll, unfiltered } from '@keystone-6/core/access' import { checkbox, text } from '@keystone-6/core/fields' -import type { Lists } from '.keystone/types' +import type { Lists, Session } from '.keystone/types' -export type Session = { - id: string - admin: boolean +declare module '.keystone/types' { + interface Session { + id: string + admin: boolean + } } function hasSession({ session }: { session?: Session }) { @@ -63,4 +65,4 @@ export const lists = { admin: checkbox(), }, }), -} satisfies Lists +} satisfies Lists diff --git a/examples/extend-graphql-schema-nexus/keystone-types.ts b/examples/extend-graphql-schema-nexus/keystone-types.ts index 68c2a7d7fca..a90adcb286f 100644 --- a/examples/extend-graphql-schema-nexus/keystone-types.ts +++ b/examples/extend-graphql-schema-nexus/keystone-types.ts @@ -230,11 +230,13 @@ type ResolvedAuthorUpdateInput = { posts?: import('./node_modules/myprisma').Prisma.AuthorUpdateInput['posts'] } +export interface Session {} + export declare namespace Lists { - export type Post = import('@keystone-6/core/types').ListConfig> + export type Post = import('@keystone-6/core/types').ListConfig namespace Post { export type Item = import('./node_modules/myprisma').Post - export type TypeInfo = { + export type TypeInfo = { key: 'Post' isSingleton: false fields: 'id' | 'title' | 'status' | 'content' | 'publishDate' | 'author' @@ -251,13 +253,13 @@ export declare namespace Lists { create: ResolvedPostCreateInput update: ResolvedPostUpdateInput } - all: __TypeInfo + all: __TypeInfo } } - export type Author = import('@keystone-6/core/types').ListConfig> + export type Author = import('@keystone-6/core/types').ListConfig namespace Author { export type Item = import('./node_modules/myprisma').Author - export type TypeInfo = { + export type TypeInfo = { key: 'Author' isSingleton: false fields: 'id' | 'name' | 'posts' @@ -274,26 +276,26 @@ export declare namespace Lists { create: ResolvedAuthorCreateInput update: ResolvedAuthorUpdateInput } - all: __TypeInfo + all: __TypeInfo } } } -export type Context = import('@keystone-6/core/types').KeystoneContext> -export type Config = import('@keystone-6/core/types').KeystoneConfig> +export type Context = import('@keystone-6/core/types').KeystoneContext +export type Config = import('@keystone-6/core/types').KeystoneConfig -export type TypeInfo = { +export type TypeInfo = { lists: { - readonly Post: Lists.Post.TypeInfo - readonly Author: Lists.Author.TypeInfo + readonly Post: Lists.Post.TypeInfo + readonly Author: Lists.Author.TypeInfo } prisma: import('./node_modules/myprisma').PrismaClient session: Session } -type __TypeInfo = TypeInfo +type __TypeInfo = TypeInfo -export type Lists = { - [Key in keyof TypeInfo['lists']]?: import('@keystone-6/core/types').ListConfig['lists'][Key]> +export type Lists = { + [Key in keyof TypeInfo['lists']]?: import('@keystone-6/core/types').ListConfig } & Record> export {} diff --git a/examples/framework-astro/src/keystone/schema.ts b/examples/framework-astro/src/keystone/schema.ts index dc419535a4b..8975a6ea275 100644 --- a/examples/framework-astro/src/keystone/schema.ts +++ b/examples/framework-astro/src/keystone/schema.ts @@ -18,6 +18,13 @@ import { text, select } from '@keystone-6/core/fields' // the generated types from '.keystone/types' import type { Lists } from '.keystone/types' +declare module '.keystone/types' { + interface Session { + user: string + browser: string + } +} + export const lists = { Post: list({ // WARNING diff --git a/examples/testing/keystone.ts b/examples/testing/keystone.ts index 4bc92d7d35f..eb8ac308bdf 100644 --- a/examples/testing/keystone.ts +++ b/examples/testing/keystone.ts @@ -2,7 +2,6 @@ import { config } from '@keystone-6/core' import { statelessSessions } from '@keystone-6/core/session' import { createAuth } from '@keystone-6/auth' import { lists } from './schema' -import type { Session } from './schema' import type { TypeInfo } from '.keystone/types' // WARNING: this example is for TESTING purposes only @@ -32,7 +31,7 @@ const { withAuth } = createAuth({ }) export default withAuth( - config>({ + config({ db: { provider: 'sqlite', url: process.env.DATABASE_URL || 'file:./keystone-example.db', diff --git a/examples/testing/schema.ts b/examples/testing/schema.ts index 17349d8e1ff..313d40ebc9d 100644 --- a/examples/testing/schema.ts +++ b/examples/testing/schema.ts @@ -2,13 +2,15 @@ import { list } from '@keystone-6/core' import { checkbox, password, relationship, text, timestamp } from '@keystone-6/core/fields' import { select } from '@keystone-6/core/fields' import { allowAll } from '@keystone-6/core/access' -import type { Lists } from '.keystone/types' +import type { Lists, Session } from '.keystone/types' // needs to be compatible with withAuth -export type Session = { - listKey: string - itemId: string - data: {} +declare module '.keystone/types' { + interface Session { + listKey: string + itemId: string + data: {} + } } function isAssignedUserFilter({ session }: { session?: Session }) { @@ -56,4 +58,4 @@ export const lists = { tasks: relationship({ ref: 'Task.assignedTo', many: true }), }, }), -} satisfies Lists +} satisfies Lists diff --git a/examples/usecase-blog-moderated/keystone.ts b/examples/usecase-blog-moderated/keystone.ts index db5d9e7f7d1..f2732213f0f 100644 --- a/examples/usecase-blog-moderated/keystone.ts +++ b/examples/usecase-blog-moderated/keystone.ts @@ -1,6 +1,6 @@ import { config } from '@keystone-6/core' -import { lists, type Session } from './schema' -import type { Context, TypeInfo } from '.keystone/types' +import { lists } from './schema' +import type { Context, TypeInfo, Session } from '.keystone/types' const sillySessionStrategy = { async get({ context }: { context: Context }): Promise { diff --git a/examples/usecase-blog-moderated/schema.ts b/examples/usecase-blog-moderated/schema.ts index 934cf1971a0..184530af977 100644 --- a/examples/usecase-blog-moderated/schema.ts +++ b/examples/usecase-blog-moderated/schema.ts @@ -1,4 +1,4 @@ -import type { Context, Lists } from '.keystone/types' +import type { Context, Lists, Session } from '.keystone/types' import { gWithContext, list } from '@keystone-6/core' import { allowAll, denyAll, unfiltered } from '@keystone-6/core/access' import { checkbox, relationship, text, timestamp, virtual } from '@keystone-6/core/fields' @@ -7,11 +7,13 @@ import { checkbox, relationship, text, timestamp, virtual } from '@keystone-6/co // as with each of our examples, it has not been vetted // or tested for any particular usage -export type Session = { - id: string - admin: boolean - moderator: null | { id: string } - contributor: null | { id: string } +declare module '.keystone/types' { + interface Session { + id: string + admin: boolean + moderator: null | { id: string } + contributor: null | { id: string } + } } type Has = { @@ -339,4 +341,4 @@ export const lists = { }), }, }), -} satisfies Lists +} satisfies Lists diff --git a/examples/usecase-roles/access.ts b/examples/usecase-roles/access.ts index 760e1c00d9b..65939202ea8 100644 --- a/examples/usecase-roles/access.ts +++ b/examples/usecase-roles/access.ts @@ -1,22 +1,26 @@ -export type Session = { - itemId: string - listKey: string - data: { - name: string - role: { - id: string +declare module '.keystone/types' { + export interface Session { + itemId: string + listKey: string + data: { name: string - canCreateTodos: boolean - canManageAllTodos: boolean - canSeeOtherPeople: boolean - canEditOtherPeople: boolean - canManagePeople: boolean - canManageRoles: boolean - canUseAdminUI: boolean + role: { + id: string + name: string + canCreateTodos: boolean + canManageAllTodos: boolean + canSeeOtherPeople: boolean + canEditOtherPeople: boolean + canManagePeople: boolean + canManageRoles: boolean + canUseAdminUI: boolean + } } } } +import type { Session } from '.keystone/types' + type AccessArgs = { session?: Session } diff --git a/examples/usecase-roles/schema.ts b/examples/usecase-roles/schema.ts index 57173fbacac..3ecaf79ea09 100644 --- a/examples/usecase-roles/schema.ts +++ b/examples/usecase-roles/schema.ts @@ -3,7 +3,6 @@ import { allOperations, denyAll } from '@keystone-6/core/access' import { checkbox, password, relationship, text } from '@keystone-6/core/fields' import { isSignedIn as hasSession, permissions, rules } from './access' -import type { Session } from './access' import type { Lists } from '.keystone/types' // WARNING: this example is for demonstration purposes only @@ -19,7 +18,7 @@ import type { Lists } from '.keystone/types' - All users can see and manage todo items assigned to themselves */ -export const lists: Lists = { +export const lists: Lists = { Todo: list({ /* SPEC @@ -239,4 +238,4 @@ export const lists: Lists = { }), }, }), -} satisfies Lists +} satisfies Lists diff --git a/packages/core/src/lib/typescript-schema-printer.ts b/packages/core/src/lib/typescript-schema-printer.ts index fa09d223173..cc63e4bb4c0 100644 --- a/packages/core/src/lib/typescript-schema-printer.ts +++ b/packages/core/src/lib/typescript-schema-printer.ts @@ -157,6 +157,8 @@ export function printGeneratedTypes( } })(), '', + 'export interface Session {}', + '', 'export declare namespace Lists {', ...(function* () { for (const [listKey, list] of Object.entries(lists)) { @@ -164,10 +166,10 @@ export function printGeneratedTypes( const listTypeInfoName = `Lists.${listKey}.TypeInfo` yield [ - `export type ${listKey} = import('@keystone-6/core/types').ListConfig<${listTypeInfoName}>`, + `export type ${listKey} = import('@keystone-6/core/types').ListConfig<${listTypeInfoName}>`, `namespace ${listKey} {`, ` export type Item = import('${prismaClientPath}').${listKey}`, - ` export type TypeInfo = {`, + ` export type TypeInfo = {`, ` key: '${listKey}'`, ` isSingleton: ${list.isSingleton}`, ` fields: ${Object.keys(list.fields) @@ -190,7 +192,7 @@ export function printGeneratedTypes( ` create: Resolved${createInputName}`, ` update: Resolved${updateInputName}`, ` }`, - ` all: __TypeInfo`, + ` all: __TypeInfo`, ` }`, `}`, ] @@ -199,14 +201,14 @@ export function printGeneratedTypes( } })(), '}', - `export type Context = import('@keystone-6/core/types').KeystoneContext>`, - `export type Config = import('@keystone-6/core/types').KeystoneConfig>`, + `export type Context = import('@keystone-6/core/types').KeystoneContext`, + `export type Config = import('@keystone-6/core/types').KeystoneConfig`, '', - 'export type TypeInfo = {', + 'export type TypeInfo = {', ` lists: {`, ...(function* () { for (const listKey in lists) { - yield ` readonly ${listKey}: Lists.${listKey}.TypeInfo` + yield ` readonly ${listKey}: Lists.${listKey}.TypeInfo` } })(), ` }`, @@ -215,10 +217,10 @@ export function printGeneratedTypes( `}`, ``, // we need to reference the `TypeInfo` above in another type that is also called `TypeInfo` - `type __TypeInfo = TypeInfo`, + `type __TypeInfo = TypeInfo`, ``, - `export type Lists = {`, - ` [Key in keyof TypeInfo['lists']]?: import('@keystone-6/core/types').ListConfig['lists'][Key]>`, + `export type Lists = {`, + ` [Key in keyof TypeInfo['lists']]?: import('@keystone-6/core/types').ListConfig`, `} & Record>`, ``, `export {}`, diff --git a/tests/cli-tests/__snapshots__/artifacts.test.ts.snap b/tests/cli-tests/__snapshots__/artifacts.test.ts.snap index 415e6a4ac74..c2ba4674559 100644 --- a/tests/cli-tests/__snapshots__/artifacts.test.ts.snap +++ b/tests/cli-tests/__snapshots__/artifacts.test.ts.snap @@ -116,11 +116,13 @@ type ResolvedTodoUpdateInput = { title?: import('@prisma/client').Prisma.TodoUpdateInput['title'] } +export interface Session {} + export declare namespace Lists { - export type Todo = import('@keystone-6/core/types').ListConfig> + export type Todo = import('@keystone-6/core/types').ListConfig namespace Todo { export type Item = import('@prisma/client').Todo - export type TypeInfo = { + export type TypeInfo = { key: 'Todo' isSingleton: false fields: 'id' | 'title' @@ -137,25 +139,25 @@ export declare namespace Lists { create: ResolvedTodoCreateInput update: ResolvedTodoUpdateInput } - all: __TypeInfo + all: __TypeInfo } } } -export type Context = import('@keystone-6/core/types').KeystoneContext> -export type Config = import('@keystone-6/core/types').KeystoneConfig> +export type Context = import('@keystone-6/core/types').KeystoneContext +export type Config = import('@keystone-6/core/types').KeystoneConfig -export type TypeInfo = { +export type TypeInfo = { lists: { - readonly Todo: Lists.Todo.TypeInfo + readonly Todo: Lists.Todo.TypeInfo } prisma: import('@prisma/client').PrismaClient session: Session } -type __TypeInfo = TypeInfo +type __TypeInfo = TypeInfo -export type Lists = { - [Key in keyof TypeInfo['lists']]?: import('@keystone-6/core/types').ListConfig['lists'][Key]> +export type Lists = { + [Key in keyof TypeInfo['lists']]?: import('@keystone-6/core/types').ListConfig } & Record> export {}