Skip to content

Commit

Permalink
Fix changes to some config not being updated in live reloads (keyston…
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown authored Oct 24, 2022
1 parent 4ec75f3 commit 4542c1f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 33 deletions.
5 changes: 5 additions & 0 deletions .changeset/mean-guests-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystone-6/core': patch
---

Fixes changes to `session`/`ui.publicPages`/`ui.isValidSession`/`ui.pageMiddleware` not being updated in live reloads
47 changes: 31 additions & 16 deletions packages/core/src/lib/server/createAdminUIMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,33 @@ const adminErrorHTMLFilepath = path.join(
'admin-error.html'
);

export const createAdminUIMiddleware = async (
config: KeystoneConfig,
createContext: CreateContext,
dev: boolean,
projectAdminPath: string
) => {
type NextApp = {
prepare(): Promise<void>;
getRequestHandler(): express.Application;
render(req: express.Request, res: express.Response, url: string): void;
};

export async function getNextApp(dev: boolean, projectAdminPath: string): Promise<NextApp> {
/** We do this to stop webpack from bundling next inside of next */
const { ui, graphql, session } = config;
const _next = 'next';
const next = require(_next);
const app = next({ dev, dir: projectAdminPath });
const handle = app.getRequestHandler();
const app = next({ dev, dir: projectAdminPath }) as NextApp;
await app.prepare();
return app;
}

export function createAdminUIMiddlewareWithNextApp(
config: KeystoneConfig,
createContext: CreateContext,
nextApp: NextApp
) {
const handle = nextApp.getRequestHandler();

const { ui, session } = config;
const publicPages = ui?.publicPages ?? [];
return async (req: express.Request, res: express.Response) => {
const { pathname } = url.parse(req.url);
if (
pathname?.startsWith('/_next') ||
pathname === (graphql?.path || '/api/graphql') ||
pathname === '/api/__keystone_api_build'
) {
if (pathname?.startsWith('/_next')) {
handle(req, res);
return;
}
Expand All @@ -56,7 +61,7 @@ export const createAdminUIMiddleware = async (
return;
}
if (!isValidSession && !publicPages.includes(url.parse(req.url).pathname!)) {
app.render(req, res, '/no-access');
nextApp.render(req, res, '/no-access');
} else {
handle(req, res);
}
Expand All @@ -76,4 +81,14 @@ export const createAdminUIMiddleware = async (
});
}
};
};
}

export async function createAdminUIMiddleware(
config: KeystoneConfig,
createContext: CreateContext,
dev: boolean,
projectAdminPath: string
) {
const nextApp = await getNextApp(dev, projectAdminPath);
return createAdminUIMiddlewareWithNextApp(config, createContext, nextApp);
}
35 changes: 18 additions & 17 deletions packages/core/src/scripts/run/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import { createSystem } from '../../lib/createSystem';
import { getEsbuildConfig, loadBuiltConfig } from '../../lib/config/loadConfig';
import { defaults } from '../../lib/config/defaults';
import { createExpressServer } from '../../lib/server/createExpressServer';
import { createAdminUIMiddleware } from '../../lib/server/createAdminUIMiddleware';
import {
createAdminUIMiddlewareWithNextApp,
getNextApp,
} from '../../lib/server/createAdminUIMiddleware';
import {
generateCommittedArtifacts,
generateNodeModulesArtifacts,
Expand All @@ -23,7 +26,7 @@ import {
requirePrismaClient,
} from '../../artifacts';
import { ExitError, getAdminPath, getBuiltConfigPath } from '../utils';
import { CreateContext, KeystoneConfig } from '../../types';
import { KeystoneConfig } from '../../types';
import { initialiseLists } from '../../lib/core/types-for-lists';
import { printPrismaSchema } from '../../lib/core/prisma-schema';
import { createSessionContext } from '../../lib/context/session';
Expand Down Expand Up @@ -135,14 +138,10 @@ export const dev = async (cwd: string, shouldDropDatabase: boolean) => {

const prismaClient = createContext().prisma;
({ disconnect, expressServer } = rest);
const adminUIMiddleware = await initAdminUI(
config,
graphQLSchema,
adminMeta,
cwd,
createContext
);
expressServer.use(adminUIMiddleware);
const nextApp = await initAdminUI(config, graphQLSchema, adminMeta, cwd);
if (nextApp) {
expressServer.use(createAdminUIMiddlewareWithNextApp(config, createContext, nextApp));
}
hasAddedAdminUIMiddleware = true;
initKeystonePromiseResolve();
const originalPrismaSchema = printPrismaSchema(
Expand Down Expand Up @@ -209,8 +208,11 @@ export const dev = async (cwd: string, shouldDropDatabase: boolean) => {
Prisma: prismaClientModule.Prisma,
});
const servers = await createExpressServer(newConfig, graphQLSchema, keystone.createContext);

servers.expressServer.use(adminUIMiddleware);
if (nextApp) {
servers.expressServer.use(
createAdminUIMiddlewareWithNextApp(newConfig, keystone.createContext, nextApp)
);
}
expressServer = servers.expressServer;
let prevApolloServer = lastApolloServer;
lastApolloServer = servers.apolloServer;
Expand Down Expand Up @@ -408,17 +410,16 @@ async function initAdminUI(
config: KeystoneConfig,
graphQLSchema: GraphQLSchema,
adminMeta: AdminMetaRootVal,
cwd: string,
createContext: CreateContext
cwd: string
) {
if (config.ui?.isDisabled) {
return express();
return;
}
console.log('✨ Generating Admin UI code');
await generateAdminUI(config, graphQLSchema, adminMeta, getAdminPath(cwd), false);

console.log('✨ Preparing Admin UI app');
const middleware = await createAdminUIMiddleware(config, createContext, true, getAdminPath(cwd));
const nextApp = await getNextApp(true, getAdminPath(cwd));
console.log(`✅ Admin UI ready`);
return middleware;
return nextApp;
}

0 comments on commit 4542c1f

Please sign in to comment.