diff --git a/.changeset/boolean-not-false-2.md b/.changeset/boolean-not-false-2.md new file mode 100644 index 00000000000..3c47acbecd5 --- /dev/null +++ b/.changeset/boolean-not-false-2.md @@ -0,0 +1,5 @@ +---- +'@keystone-6/core': patch +---- + +Fix `config.server.cors` type blocking `false` values diff --git a/.changeset/boolean-not-false.md b/.changeset/boolean-not-false.md index 0a4d619aa1d..3a7a0a78d20 100644 --- a/.changeset/boolean-not-false.md +++ b/.changeset/boolean-not-false.md @@ -1,5 +1,5 @@ ---- -'@keystone-6/auth': core +'@keystone-6/core': patch ---- Fix `defaultIsFilterable` and `defaultIsOrderable` types blocking `true` values diff --git a/.changeset/http-async.md b/.changeset/http-async.md new file mode 100644 index 00000000000..b4ab6555df9 --- /dev/null +++ b/.changeset/http-async.md @@ -0,0 +1,5 @@ +--- +'@keystone-6/core': minor +--- + +Add `async` to `extendHttpServer`, for `await` on startup diff --git a/docs/pages/docs/config/config.md b/docs/pages/docs/config/config.md index 80f37da65cf..fd933484e09 100644 --- a/docs/pages/docs/config/config.md +++ b/docs/pages/docs/config/config.md @@ -226,8 +226,8 @@ export default config({ cors: { origin: ['http://localhost:7777'], credentials: true }, port: 3000, maxFileSize: 200 * 1024 * 1024, - extendExpressApp: (app, commonContext) => { /* ... */ }, - extendHttpServer: (httpServer, commonContext, graphQLSchema) => { /* ... */ }, + extendExpressApp: async (app, commonContext) => { /* ... */ }, + extendHttpServer: async (httpServer, commonContext, graphQLSchema) => { /* ... */ }, }, /* ... */ }); diff --git a/packages/core/src/lib/server/createExpressServer.ts b/packages/core/src/lib/server/createExpressServer.ts index 3f52b8e338a..e8566bc3706 100644 --- a/packages/core/src/lib/server/createExpressServer.ts +++ b/packages/core/src/lib/server/createExpressServer.ts @@ -1,5 +1,5 @@ import { createServer, type Server } from 'http' -import cors, { type CorsOptions } from 'cors' +import cors from 'cors' import { json } from 'body-parser' import { expressMiddleware } from '@apollo/server/express4' import express from 'express' @@ -20,8 +20,6 @@ The Admin UI takes a while to build for dev, and is created separately so the CLI can bring up the dev server early to handle GraphQL requests. */ -const DEFAULT_MAX_FILE_SIZE = 200 * 1024 * 1024 // 200 MiB - function formatError (graphqlConfig: GraphQLConfig | undefined) { return (formattedError: GraphQLFormattedError, error: unknown) => { let debug = graphqlConfig?.debug @@ -56,9 +54,7 @@ export async function createExpressServer ( const httpServer = createServer(expressServer) if (config.server?.cors) { - // Setting config.server.cors = true will provide backwards compatible defaults - // Otherwise, the user can provide their own config object to use - const corsConfig: CorsOptions = + const corsConfig = typeof config.server.cors === 'boolean' ? { origin: true, credentials: true } : config.server.cors @@ -80,13 +76,8 @@ export async function createExpressServer ( }) } - if (config.server?.extendExpressApp) { - await config.server.extendExpressApp(expressServer, context) - } - - if (config.server?.extendHttpServer) { - config.server?.extendHttpServer(httpServer, context, graphQLSchema) - } + await config.server?.extendExpressApp?.(expressServer, context) + await config.server?.extendHttpServer?.(httpServer, context, graphQLSchema) if (config.storage) { for (const val of Object.values(config.storage)) { @@ -129,8 +120,8 @@ export async function createExpressServer ( } as ApolloServerOptions const apolloServer = new ApolloServer({ ...serverConfig }) + const maxFileSize = config.server?.maxFileSize - const maxFileSize = config.server?.maxFileSize ?? DEFAULT_MAX_FILE_SIZE expressServer.use(graphqlUploadExpress({ maxFileSize })) await apolloServer.start() expressServer.use( diff --git a/packages/core/src/system.ts b/packages/core/src/system.ts index 5e02460a32e..65081be4b56 100644 --- a/packages/core/src/system.ts +++ b/packages/core/src/system.ts @@ -25,10 +25,11 @@ export function initConfig (config: KeystoneConfig) { config.db.url ??= 'postgres://' return { + ...config, types: { - path: 'node_modules/.keystone/types.ts' + path: 'node_modules/.keystone/types.ts', + ...config.types, }, - ...config, db: { prismaSchemaPath: 'schema.prisma', ...config.db, @@ -38,6 +39,13 @@ export function initConfig (config: KeystoneConfig) { ...config.graphql, }, lists: applyIdFieldDefaults(config), + server: { + cors: false, + maxFileSize: 200 * 1024 * 1024, // 200 MiB + extendExpressApp: async () => {}, + extendHttpServer: async () => {}, + ...config.server, + }, } } diff --git a/packages/core/src/types/config/index.ts b/packages/core/src/types/config/index.ts index cb5684a7d40..8e6916585e2 100644 --- a/packages/core/src/types/config/index.ts +++ b/packages/core/src/types/config/index.ts @@ -193,8 +193,8 @@ export type AdminFileToWrite = // config.server export type ServerConfig = { - /** Configuration options for the cors middleware. Set to `true` to use core Keystone defaults */ - cors?: CorsOptions | true + /** Configuration options for the cors middleware. Set to `true` to use Keystone's defaults */ + cors?: boolean | CorsOptions /** Maximum upload file size allowed (in bytes) */ maxFileSize?: number @@ -210,14 +210,14 @@ export type ServerConfig = { extendExpressApp?: ( app: express.Express, context: KeystoneContext - ) => void | Promise + ) => MaybePromise /** extend the node:http server used by Keystone */ extendHttpServer?: ( server: Server, context: KeystoneContext, graphqlSchema: GraphQLSchema - ) => void + ) => MaybePromise } & ( | { /** Port number to start the server on. Defaults to process.env.PORT || 3000 */