Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for developers to replace the default esbuild configuration #9235

Merged
merged 9 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/add-custom-esbuild.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@keystone-6/core": minor
---

Add support for developers to add `esbuild.keystone.ts` to the working directory to mutate the default esbuild configuration
7 changes: 7 additions & 0 deletions examples/custom-esbuild/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Base Project - Custom Esbuild

...

## Try it out in CodeSandbox 🧪

You can play with this example online in a web browser using the free [codesandbox.io](https://codesandbox.io/) service. To launch this example, open the URL <https://githubbox.com/keystonejs/keystone/tree/main/examples/custom-id>. You can also fork this sandbox to make your own changes.
8 changes: 8 additions & 0 deletions examples/custom-esbuild/esbuild.keystone.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { type BuildOptions } from 'esbuild'

export default function (defaults: BuildOptions) {
return {
...defaults,
logLevel: 'verbose'
}
}
15 changes: 15 additions & 0 deletions examples/custom-esbuild/keystone.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { config } from '@keystone-6/core'
import { fixPrismaPath } from '../example-utils'
import { lists } from './schema'
import type { TypeInfo } from '.keystone/types'

export default config<TypeInfo>({
db: {
provider: 'sqlite',
url: process.env.DATABASE_URL || 'file:./keystone-example.db',

// WARNING: this is only needed for our monorepo examples, don't do this
...fixPrismaPath,
},
lists,
})
20 changes: 20 additions & 0 deletions examples/custom-esbuild/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "@keystone-6/example-custom-id",
"version": "0.0.1",
"private": true,
"license": "MIT",
"scripts": {
"dev": "keystone dev",
"start": "keystone start",
"build": "keystone build",
"postinstall": "keystone postinstall"
},
"dependencies": {
"@keystone-6/core": "workspace:^",
"@prisma/client": "catalog:"
},
"devDependencies": {
"prisma": "catalog:",
"typescript": "catalog:"
}
}
7 changes: 7 additions & 0 deletions examples/custom-esbuild/sandbox.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"template": "node",
"container": {
"startScript": "keystone dev",
"node": "16"
}
}
214 changes: 214 additions & 0 deletions examples/custom-esbuild/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
# This file is automatically generated by Keystone, do not modify it manually.
# Modify your Keystone config when you want to change this.

type Post {
id: ID!
name: String
content: String
}

input PostWhereUniqueInput {
id: ID
}

input PostWhereInput {
AND: [PostWhereInput!]
OR: [PostWhereInput!]
NOT: [PostWhereInput!]
id: IDFilter
name: StringFilter
content: StringFilter
}

input IDFilter {
equals: ID
in: [ID!]
notIn: [ID!]
lt: ID
lte: ID
gt: ID
gte: ID
not: IDFilter
}

input StringFilter {
equals: String
in: [String!]
notIn: [String!]
lt: String
lte: String
gt: String
gte: String
contains: String
startsWith: String
endsWith: String
not: NestedStringFilter
}

input NestedStringFilter {
equals: String
in: [String!]
notIn: [String!]
lt: String
lte: String
gt: String
gte: String
contains: String
startsWith: String
endsWith: String
not: NestedStringFilter
}

input PostOrderByInput {
id: OrderDirection
name: OrderDirection
content: OrderDirection
}

enum OrderDirection {
asc
desc
}

input PostUpdateInput {
name: String
content: String
}

input PostUpdateArgs {
where: PostWhereUniqueInput!
data: PostUpdateInput!
}

input PostCreateInput {
name: String
content: String
}

"""
The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
"""
scalar JSON @specifiedBy(url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf")

type Mutation {
createPost(data: PostCreateInput!): Post
createPosts(data: [PostCreateInput!]!): [Post]
updatePost(where: PostWhereUniqueInput!, data: PostUpdateInput!): Post
updatePosts(data: [PostUpdateArgs!]!): [Post]
deletePost(where: PostWhereUniqueInput!): Post
deletePosts(where: [PostWhereUniqueInput!]!): [Post]
}

type Query {
posts(where: PostWhereInput! = {}, orderBy: [PostOrderByInput!]! = [], take: Int, skip: Int! = 0, cursor: PostWhereUniqueInput): [Post!]
post(where: PostWhereUniqueInput!): Post
postsCount(where: PostWhereInput! = {}): Int
keystone: KeystoneMeta!
}

type KeystoneMeta {
adminMeta: KeystoneAdminMeta!
}

type KeystoneAdminMeta {
lists: [KeystoneAdminUIListMeta!]!
list(key: String!): KeystoneAdminUIListMeta
}

type KeystoneAdminUIListMeta {
key: String!
itemQueryName: String!
listQueryName: String!
hideCreate: Boolean!
hideDelete: Boolean!
path: String!
label: String!
singular: String!
plural: String!
description: String
initialColumns: [String!]!
pageSize: Int!
labelField: String!
fields: [KeystoneAdminUIFieldMeta!]!
groups: [KeystoneAdminUIFieldGroupMeta!]!
initialSort: KeystoneAdminUISort
isHidden: Boolean!
isSingleton: Boolean!
}

type KeystoneAdminUIFieldMeta {
path: String!
label: String!
description: String
isOrderable: Boolean!
isFilterable: Boolean!
isNonNull: [KeystoneAdminUIFieldMetaIsNonNull!]
fieldMeta: JSON
viewsIndex: Int!
customViewsIndex: Int
createView: KeystoneAdminUIFieldMetaCreateView!
listView: KeystoneAdminUIFieldMetaListView!
itemView(id: ID): KeystoneAdminUIFieldMetaItemView
search: QueryMode
}

enum KeystoneAdminUIFieldMetaIsNonNull {
read
create
update
}

type KeystoneAdminUIFieldMetaCreateView {
fieldMode: KeystoneAdminUIFieldMetaCreateViewFieldMode!
}

enum KeystoneAdminUIFieldMetaCreateViewFieldMode {
edit
hidden
}

type KeystoneAdminUIFieldMetaListView {
fieldMode: KeystoneAdminUIFieldMetaListViewFieldMode!
}

enum KeystoneAdminUIFieldMetaListViewFieldMode {
read
hidden
}

type KeystoneAdminUIFieldMetaItemView {
fieldMode: KeystoneAdminUIFieldMetaItemViewFieldMode
fieldPosition: KeystoneAdminUIFieldMetaItemViewFieldPosition
}

enum KeystoneAdminUIFieldMetaItemViewFieldMode {
edit
read
hidden
}

enum KeystoneAdminUIFieldMetaItemViewFieldPosition {
form
sidebar
}

enum QueryMode {
default
insensitive
}

type KeystoneAdminUIFieldGroupMeta {
label: String!
description: String
fields: [KeystoneAdminUIFieldMeta!]!
}

type KeystoneAdminUISort {
field: String!
direction: KeystoneAdminUISortDirection!
}

enum KeystoneAdminUISortDirection {
ASC
DESC
}
19 changes: 19 additions & 0 deletions examples/custom-esbuild/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// This file is automatically generated by Keystone, do not modify it manually.
// Modify your Keystone config when you want to change this.

datasource sqlite {
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
provider = "sqlite"
}

generator client {
provider = "prisma-client-js"
output = "node_modules/.myprisma/client"
}

model Post {
id String @id @default(cuid())
name String @default("")
content String @default("")
}
14 changes: 14 additions & 0 deletions examples/custom-esbuild/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { list } from '@keystone-6/core'
import { allowAll } from '@keystone-6/core/access'
import { text } from '@keystone-6/core/fields'
import type { Lists } from '.keystone/types'

export const lists = {
Post: list({
access: allowAll,
fields: {
name: text(),
content: text(),
},
}),
} satisfies Lists
36 changes: 0 additions & 36 deletions packages/core/src/lib/esbuild.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/core/src/scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
generateTypes,
validateArtifacts,
} from '../artifacts'
import { getEsbuildConfig } from '../lib/esbuild'
import { getEsbuildConfig } from './esbuild'
import type { Flags } from './cli'
import { importBuiltKeystoneConfiguration } from './utils'

Expand All @@ -19,7 +19,7 @@ export async function build (
{ frozen, prisma, ui }: Pick<Flags, 'frozen' | 'prisma' | 'ui'>
) {
// TODO: should this happen if frozen?
await esbuild.build(getEsbuildConfig(cwd))
await esbuild.build(await getEsbuildConfig(cwd))

const system = createSystem(await importBuiltKeystoneConfiguration(cwd))
if (prisma) {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/scripts/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { generateAdminUI } from '../admin-ui/system'
import { withMigrate } from '../lib/migrations'
import { confirmPrompt } from '../lib/prompts'
import { createSystem, } from '../lib/createSystem'
import { getEsbuildConfig } from '../lib/esbuild'
import { getEsbuildConfig } from './esbuild'
import { createExpressServer } from '../lib/createExpressServer'
import { createAdminUIMiddlewareWithNextApp } from '../lib/createAdminUIMiddleware'
import { runTelemetry } from '../lib/telemetry'
Expand Down Expand Up @@ -71,7 +71,7 @@ export async function dev (
prev.resolve({ value: build, done: false })
}

const esbuildConfig = getEsbuildConfig(cwd)
const esbuildConfig = await getEsbuildConfig(cwd)
const esbuildContext = await esbuild.context({
...esbuildConfig,
plugins: [
Expand Down
Loading
Loading