diff --git a/examples/custom-admin-ui-logo/app/(admin)/.admin/index.tsx b/examples/custom-admin-ui-logo/app/(admin)/.admin/index.tsx
new file mode 100644
index 00000000000..5dd11446daf
--- /dev/null
+++ b/examples/custom-admin-ui-logo/app/(admin)/.admin/index.tsx
@@ -0,0 +1,18 @@
+/* eslint-disable */
+import * as view0 from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view'
+import * as view1 from '@keystone-6/core/fields/types/text/views'
+import * as view2 from '@keystone-6/core/fields/types/select/views'
+import * as view3 from '@keystone-6/core/fields/types/checkbox/views'
+import * as view4 from '@keystone-6/core/fields/types/relationship/views'
+import * as view5 from '@keystone-6/core/fields/types/timestamp/views'
+
+import * as adminConfig from '../config'
+
+export const config = {
+ lazyMetadataQuery: {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"keystone","loc":{"start":22,"end":30}},"arguments":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"adminMeta","loc":{"start":39,"end":48}},"arguments":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lists","loc":{"start":59,"end":64}},"arguments":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key","loc":{"start":77,"end":80}},"arguments":[],"directives":[],"loc":{"start":77,"end":80}},{"kind":"Field","name":{"kind":"Name","value":"isHidden","loc":{"start":91,"end":99}},"arguments":[],"directives":[],"loc":{"start":91,"end":99}},{"kind":"Field","name":{"kind":"Name","value":"fields","loc":{"start":110,"end":116}},"arguments":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"path","loc":{"start":131,"end":135}},"arguments":[],"directives":[],"loc":{"start":131,"end":135}},{"kind":"Field","name":{"kind":"Name","value":"createView","loc":{"start":148,"end":158}},"arguments":[],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fieldMode","loc":{"start":175,"end":184}},"arguments":[],"directives":[],"loc":{"start":175,"end":184}}],"loc":{"start":159,"end":198}},"loc":{"start":148,"end":198}}],"loc":{"start":117,"end":210}},"loc":{"start":110,"end":210}}],"loc":{"start":65,"end":220}},"loc":{"start":59,"end":220}}],"loc":{"start":49,"end":228}},"loc":{"start":39,"end":228}}],"loc":{"start":31,"end":234}},"loc":{"start":22,"end":234}}]}}]},
+ fieldViews: [view0,view1,view2,view3,view4,view5],
+ adminMetaHash: '1mrsjib',
+ adminConfig,
+ apiPath: '/api/graphql',
+ adminPath: '',
+};
diff --git a/examples/custom-admin-ui-logo/app/(admin)/[listKey]/[id]/page.tsx b/examples/custom-admin-ui-logo/app/(admin)/[listKey]/[id]/page.tsx
new file mode 100644
index 00000000000..c5d7ea2be62
--- /dev/null
+++ b/examples/custom-admin-ui-logo/app/(admin)/[listKey]/[id]/page.tsx
@@ -0,0 +1,4 @@
+'use client'
+import { ItemPage } from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage'
+
+export default ItemPage
diff --git a/examples/custom-admin-ui-logo/app/(admin)/[listKey]/create/page.tsx b/examples/custom-admin-ui-logo/app/(admin)/[listKey]/create/page.tsx
new file mode 100644
index 00000000000..d6042acaa96
--- /dev/null
+++ b/examples/custom-admin-ui-logo/app/(admin)/[listKey]/create/page.tsx
@@ -0,0 +1,4 @@
+'use client'
+import { CreateItemPage } from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage'
+
+export default CreateItemPage
diff --git a/examples/custom-admin-ui-logo/app/(admin)/[listKey]/page.tsx b/examples/custom-admin-ui-logo/app/(admin)/[listKey]/page.tsx
new file mode 100644
index 00000000000..f6e75f8cfab
--- /dev/null
+++ b/examples/custom-admin-ui-logo/app/(admin)/[listKey]/page.tsx
@@ -0,0 +1,4 @@
+'use client'
+import { ListPage } from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage'
+
+export default ListPage
diff --git a/examples/custom-admin-ui-logo/app/(admin)/config.tsx b/examples/custom-admin-ui-logo/app/(admin)/config.tsx
new file mode 100644
index 00000000000..53be6083334
--- /dev/null
+++ b/examples/custom-admin-ui-logo/app/(admin)/config.tsx
@@ -0,0 +1 @@
+export { components } from '../admin/config'
\ No newline at end of file
diff --git a/examples/custom-admin-ui-logo/app/(admin)/layout.tsx b/examples/custom-admin-ui-logo/app/(admin)/layout.tsx
new file mode 100644
index 00000000000..abb5a0f3b2c
--- /dev/null
+++ b/examples/custom-admin-ui-logo/app/(admin)/layout.tsx
@@ -0,0 +1,16 @@
+'use client'
+import { Layout } from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App'
+import { config } from './.admin'
+
+
+export default function AdminLayout ({
+ children,
+}: {
+ children: React.ReactNode
+}) {
+ return (
+
+ {children}
+
+ )
+}
\ No newline at end of file
diff --git a/examples/custom-admin-ui-logo/app/(admin)/no-access/page.tsx b/examples/custom-admin-ui-logo/app/(admin)/no-access/page.tsx
new file mode 100644
index 00000000000..70877231fee
--- /dev/null
+++ b/examples/custom-admin-ui-logo/app/(admin)/no-access/page.tsx
@@ -0,0 +1,4 @@
+'use client'
+import { getNoAccessPage } from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage'
+
+export default getNoAccessPage({ sessionsEnabled: false })
diff --git a/examples/custom-admin-ui-logo/app/(admin)/page.tsx b/examples/custom-admin-ui-logo/app/(admin)/page.tsx
new file mode 100644
index 00000000000..5c268390b0f
--- /dev/null
+++ b/examples/custom-admin-ui-logo/app/(admin)/page.tsx
@@ -0,0 +1,2 @@
+'use client'
+export { HomePage as default } from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage'
diff --git a/examples/custom-admin-ui-logo/admin/components/CustomLogo.tsx b/examples/custom-admin-ui-logo/app/admin/components/CustomLogo.tsx
similarity index 100%
rename from examples/custom-admin-ui-logo/admin/components/CustomLogo.tsx
rename to examples/custom-admin-ui-logo/app/admin/components/CustomLogo.tsx
diff --git a/examples/custom-admin-ui-logo/admin/config.tsx b/examples/custom-admin-ui-logo/app/admin/config.tsx
similarity index 100%
rename from examples/custom-admin-ui-logo/admin/config.tsx
rename to examples/custom-admin-ui-logo/app/admin/config.tsx
diff --git a/examples/custom-admin-ui-logo/app/layout.tsx b/examples/custom-admin-ui-logo/app/layout.tsx
new file mode 100644
index 00000000000..38a4853e3a5
--- /dev/null
+++ b/examples/custom-admin-ui-logo/app/layout.tsx
@@ -0,0 +1,11 @@
+export default function RootLayout ({
+ children,
+}: {
+ children: React.ReactNode
+}) {
+ return (
+
+
{children}
+
+ )
+}
diff --git a/examples/custom-admin-ui-logo/next-env.d.ts b/examples/custom-admin-ui-logo/next-env.d.ts
new file mode 100644
index 00000000000..4f11a03dc6c
--- /dev/null
+++ b/examples/custom-admin-ui-logo/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/examples/custom-admin-ui-logo/next.config.mjs b/examples/custom-admin-ui-logo/next.config.mjs
new file mode 100644
index 00000000000..bec106de70d
--- /dev/null
+++ b/examples/custom-admin-ui-logo/next.config.mjs
@@ -0,0 +1,14 @@
+// you don't need this if you're building something outside of the Keystone repo
+
+export default {
+ experimental: {
+ // without this, 'Error: Expected Upload to be a GraphQL nullable type.'
+ serverComponentsExternalPackages: ['graphql'],
+ },
+ eslint: {
+ ignoreDuringBuilds: true,
+ },
+ typescript: {
+ ignoreBuildErrors: true,
+ },
+}
diff --git a/examples/custom-admin-ui-logo/tsconfig.json b/examples/custom-admin-ui-logo/tsconfig.json
new file mode 100644
index 00000000000..ccb2ed95d83
--- /dev/null
+++ b/examples/custom-admin-ui-logo/tsconfig.json
@@ -0,0 +1,34 @@
+{
+ "compilerOptions": {
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "noEmit": true,
+ "incremental": true,
+ "module": "esnext",
+ "esModuleInterop": true,
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
+ },
+ "include": [
+ "next-env.d.ts",
+ ".next/types/**/*.ts",
+ "**/*.ts",
+ "**/*.tsx"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/packages/core/src/admin-ui/system/generateAdminUI.ts b/packages/core/src/admin-ui/system/generateAdminUI.ts
index bbe21cdd403..2c45c93a297 100644
--- a/packages/core/src/admin-ui/system/generateAdminUI.ts
+++ b/packages/core/src/admin-ui/system/generateAdminUI.ts
@@ -29,6 +29,12 @@ function getDoesAdminConfigExist (adminPath: string) {
export async function writeAdminFile (file: AdminFileToWrite, projectAdminPath: string) {
const outputFilename = Path.join(projectAdminPath, file.outputPath)
+ const overwrite = file.overwrite || !(await fse.exists(outputFilename))
+
+ if (!overwrite) {
+ return Path.normalize(outputFilename)
+ }
+
if (file.mode === 'copy') {
if (!Path.isAbsolute(file.inputPath)) {
throw new Error(
@@ -36,10 +42,8 @@ export async function writeAdminFile (file: AdminFileToWrite, projectAdminPath:
)
}
await fse.ensureDir(Path.dirname(outputFilename))
- if (file.overwrite && !(await fse.exists(outputFilename))) {
- // TODO: should we use copyFile or copy?
- await fs.copyFile(file.inputPath, outputFilename)
- }
+ // TODO: should we use copyFile or copy?
+ await fs.copyFile(file.inputPath, outputFilename)
}
let content: undefined | string
try {
@@ -86,22 +90,22 @@ export async function generateAdminUI (
// this won't clear out empty directories, this is fine since:
// - they won't create pages in Admin UI which is really what this deleting is about avoiding
// - we'll remove them when the user restarts the process
- if (isLiveReload) {
- const ignoredDir = Path.resolve(projectAdminPath, '.next')
- const ignoredFiles = new Set(
- [
- ...adminFiles.map(x => x.outputPath),
- ...uniqueFiles,
- 'next-env.d.ts',
- 'pages/api/__keystone_api_build.js',
- ].map(x => Path.resolve(projectAdminPath, x))
- )
+ // if (isLiveReload) {
+ // const ignoredDir = Path.resolve(projectAdminPath, '.next')
+ // const ignoredFiles = new Set(
+ // [
+ // ...adminFiles.map(x => x.outputPath),
+ // ...uniqueFiles,
+ // 'next-env.d.ts',
+ // 'pages/api/__keystone_api_build.js',
+ // ].map(x => Path.resolve(projectAdminPath, x))
+ // )
- const entries = await walk(projectAdminPath, {
- deepFilter: entry => entry.path !== ignoredDir,
- entryFilter: entry => entry.dirent.isFile() && !ignoredFiles.has(entry.path),
- })
+ // const entries = await walk(projectAdminPath, {
+ // deepFilter: entry => entry.path !== ignoredDir,
+ // entryFilter: entry => entry.dirent.isFile() && !ignoredFiles.has(entry.path),
+ // })
- await Promise.all(entries.map(entry => fs.rm(entry.path, { recursive: true })))
- }
+ // await Promise.all(entries.map(entry => fs.rm(entry.path, { recursive: true })))
+ // }
}
diff --git a/packages/core/src/scripts/cli.ts b/packages/core/src/scripts/cli.ts
index 45920da7a6b..035fb6c5dea 100644
--- a/packages/core/src/scripts/cli.ts
+++ b/packages/core/src/scripts/cli.ts
@@ -15,6 +15,7 @@ export type Flags = {
server: boolean
ui: boolean
withMigrations: boolean
+ resetAdmin: boolean
}
function defaultFlags (flags: Partial, defaults: Partial) {
@@ -66,6 +67,9 @@ export async function cli (cwd: string, argv: string[]) {
--no-db-push (dev)
don't push any updates of your Prisma schema to your database
+
+ --reset-admin (dev)
+ reset generated admin files
--no-prisma (build, dev)
don't build or validate the prisma schema
@@ -87,7 +91,7 @@ export async function cli (cwd: string, argv: string[]) {
const command = input.join(' ') || 'dev'
if (command === 'dev') {
- return dev(cwd, defaultFlags(flags, { dbPush: true, prisma: true, server: true, ui: true }))
+ return dev(cwd, defaultFlags(flags, { dbPush: true, prisma: true, server: true, ui: true, resetAdmin: false }))
}
if (command === 'migrate create') {
diff --git a/packages/core/src/scripts/dev.ts b/packages/core/src/scripts/dev.ts
index ccddf69881f..1d472bc65b9 100644
--- a/packages/core/src/scripts/dev.ts
+++ b/packages/core/src/scripts/dev.ts
@@ -56,7 +56,7 @@ function resolvablePromise () {
export async function dev (
cwd: string,
- { dbPush, prisma, server, ui }: Pick
+ { dbPush, prisma, server, ui, resetAdmin }: Pick
) {
console.log('✨ Starting Keystone')
let lastPromise = resolvablePromise>()
@@ -264,7 +264,9 @@ export async function dev (
let nextApp
if (!system.config.ui?.isDisabled && ui) {
const paths = system.getPaths(cwd)
- await fsp.rm(paths.admin, { recursive: true, force: true })
+ if (resetAdmin) {
+ await fsp.rm(paths.admin, { recursive: true, force: true })
+ }
console.log('✨ Generating Admin UI code')
await generateAdminUI(system.config, system.graphQLSchema, system.adminMeta, paths.admin, false)