Skip to content

Commit 4262e50

Browse files
fix(deps): update prisma monorepo to v5.15.1 (#9164)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel Cousens <[email protected]>
1 parent 295d401 commit 4262e50

File tree

20 files changed

+526
-423
lines changed

20 files changed

+526
-423
lines changed

.changeset/fix-keystone-prisma.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@keystone-6/core': patch
3+
---
4+
5+
Fix `keystone prisma ...` not returning the same error code as the Prisma engine

packages/core/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@
204204
"@keystone-ui/toast": "workspace:^",
205205
"@keystone-ui/tooltip": "workspace:^",
206206
"@nodelib/fs.walk": "^2.0.0",
207-
"@prisma/client": "5.14.0",
208-
"@prisma/internals": "5.14.0",
209-
"@prisma/migrate": "5.14.0",
207+
"@prisma/client": "5.15.1",
208+
"@prisma/internals": "5.15.1",
209+
"@prisma/migrate": "5.15.1",
210210
"@sindresorhus/slugify": "^1.1.2",
211211
"apollo-upload-client": "^17.0.0",
212212
"bcryptjs": "^2.4.3",
@@ -235,7 +235,7 @@
235235
"meow": "^9.0.0",
236236
"next": "^14.2.0",
237237
"pluralize": "^8.0.0",
238-
"prisma": "5.14.0",
238+
"prisma": "5.15.1",
239239
"prompts": "^2.4.2",
240240
"react": "^18.2.0",
241241
"react-dom": "^18.2.0",

packages/core/src/___internal-do-not-use-will-break-in-patch/artifacts.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ export {
55
createSystem,
66
} from '../lib/createSystem'
77
export {
8-
pushPrismaSchemaToDatabase,
8+
withMigrate
99
} from '../lib/migrations'
1010
export {
1111
generateArtifacts,
1212
getArtifacts,
1313
} from '../artifacts'
14+
export {
15+
ExitError
16+
} from '../scripts/utils'

packages/core/src/artifacts.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises'
22
import path from 'node:path'
33
import { type ChildProcess } from 'node:child_process'
44

5-
import { printSchema, type GraphQLSchema } from 'graphql'
5+
import { printSchema } from 'graphql'
66
import { getGenerators, formatSchema } from '@prisma/internals'
77
import { ExitError } from './scripts/utils'
88
import { type __ResolvedKeystoneConfig } from './types'
@@ -39,7 +39,7 @@ export async function validateArtifacts (
3939
system: System,
4040
) {
4141
const paths = system.getPaths(cwd)
42-
const artifacts = await getCommittedArtifacts(system.config, system.graphQLSchema)
42+
const artifacts = await getArtifacts(system)
4343
const [writtenGraphQLSchema, writtenPrismaSchema] = await Promise.all([
4444
readFileButReturnNothingIfDoesNotExist(paths.schema.graphql),
4545
readFileButReturnNothingIfDoesNotExist(paths.schema.prisma),
@@ -67,22 +67,23 @@ export async function validateArtifacts (
6767
throw new ExitError(1)
6868
}
6969

70-
async function getCommittedArtifacts (config: __ResolvedKeystoneConfig, graphQLSchema: GraphQLSchema) {
71-
const lists = initialiseLists(config)
72-
const prismaSchema = printPrismaSchema(config, lists)
70+
export async function getArtifacts (system: System) {
71+
const lists = initialiseLists(system.config)
72+
const prismaSchema = await formatSchema({
73+
schemas: [
74+
[system.config.db.prismaSchemaPath, printPrismaSchema(system.config, lists)]
75+
]
76+
})
77+
7378
return {
74-
graphql: getFormattedGraphQLSchema(printSchema(graphQLSchema)),
75-
prisma: (await formatSchema({ schemas: [[config.db.prismaSchemaPath, prismaSchema]] }))[0][1],
79+
graphql: getFormattedGraphQLSchema(printSchema(system.graphQLSchema)),
80+
prisma: prismaSchema[0][1],
7681
}
7782
}
7883

79-
export async function getArtifacts (system: System) {
80-
return await getCommittedArtifacts(system.config, system.graphQLSchema)
81-
}
82-
8384
export async function generateArtifacts (cwd: string, system: System) {
8485
const paths = getSystemPaths(cwd, system.config)
85-
const artifacts = await getCommittedArtifacts(system.config, system.graphQLSchema)
86+
const artifacts = await getArtifacts(system)
8687
await fs.writeFile(paths.schema.graphql, artifacts.graphql)
8788
await fs.writeFile(paths.schema.prisma, artifacts.prisma)
8889
return artifacts

packages/core/src/lib/createSystem.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,16 @@ import { resolveDefaults } from './defaults'
1212
import { createAdminMeta } from './create-admin-meta'
1313
import { createGraphQLSchema } from './createGraphQLSchema'
1414
import { createContext } from './context/createContext'
15-
import { initialiseLists, type InitialisedList } from './core/initialise-lists'
15+
import {
16+
type InitialisedList,
17+
initialiseLists,
18+
} from './core/initialise-lists'
1619

1720
// TODO: this cannot be changed for now, circular dependency with getSystemPaths, getEsbuildConfig
1821
export function getBuiltKeystoneConfigurationPath (cwd: string) {
1922
return path.join(cwd, '.keystone/config.js')
2023
}
2124

22-
export function getBuiltKeystoneConfiguration (cwd: string) {
23-
return require(getBuiltKeystoneConfigurationPath(cwd)).default
24-
}
25-
2625
function posixify (s: string) {
2726
return s.split(path.sep).join('/')
2827
}
Lines changed: 49 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -1,190 +1,72 @@
11
import { type ChildProcess } from 'node:child_process'
2-
import path from 'node:path'
2+
import { toSchemasContainer } from '@prisma/internals'
33

4-
import chalk from 'chalk'
5-
import { createDatabase, uriToCredentials, type DatabaseCredentials } from '@prisma/internals'
4+
// @ts-expect-error
65
import { Migrate } from '@prisma/migrate'
76

87
import { type System } from './createSystem'
98

10-
import { ExitError } from '../scripts/utils'
11-
import { confirmPrompt } from './prompts'
12-
13-
// we don't want to pollute process.env.DATABASE_URL so we're
14-
// setting the env variable _just_ long enough for Migrate to
15-
// read it and then we reset it immediately after.
16-
// Migrate reads the env variables a single time when it starts the child process that it talks to
17-
18-
// note that we could only run this once per Migrate instance but we're going to do it consistently for all migrate calls
19-
// so that calls can moved around freely without implictly relying on some other migrate command being called before it
9+
function setOrRemoveEnvVariable (name: string, value: string | undefined) {
10+
if (value === undefined) {
11+
delete process.env[name]
12+
return
13+
}
14+
process.env[name] = value
15+
}
2016

21-
// We also want to silence messages from Prisma about available updates, since the developer is
22-
// not in control of their Prisma version.
23-
// https://www.prisma.io/docs/reference/api-reference/environment-variables-reference#prisma_hide_update_message
24-
function runMigrateWithDbUrl<T> (
17+
export async function withMigrate<T> (
18+
prismaSchemaPath: string,
2519
system: {
2620
config: {
2721
db: Pick<System['config']['db'], 'url' | 'shadowDatabaseUrl'>
2822
}
2923
},
30-
cb: () => T
31-
): T {
32-
const prevDBURLFromEnv = process.env.DATABASE_URL
33-
const prevShadowDBURLFromEnv = process.env.SHADOW_DATABASE_URL
34-
const prevHiddenUpdateMessage = process.env.PRISMA_HIDE_UPDATE_MESSAGE
35-
try {
36-
process.env.DATABASE_URL = system.config.db.url
37-
setOrRemoveEnvVariable('SHADOW_DATABASE_URL', system.config.db.shadowDatabaseUrl)
38-
process.env.PRISMA_HIDE_UPDATE_MESSAGE = '1'
39-
return cb()
40-
} finally {
41-
setOrRemoveEnvVariable('DATABASE_URL', prevDBURLFromEnv)
42-
setOrRemoveEnvVariable('SHADOW_DATABASE_URL', prevShadowDBURLFromEnv)
43-
setOrRemoveEnvVariable('PRISMA_HIDE_UPDATE_MESSAGE', prevHiddenUpdateMessage)
44-
}
45-
}
46-
47-
function setOrRemoveEnvVariable (name: string, value: string | undefined) {
48-
if (value === undefined) {
49-
delete process.env[name]
50-
} else {
51-
process.env[name] = value
24+
cb: (operations: {
25+
apply: () => Promise<any>
26+
diagnostic: () => Promise<any>
27+
push: (force: boolean) => Promise<any>
28+
reset: () => Promise<any>
29+
schema: (_: string, force: boolean) => Promise<any>
30+
}) => Promise<T>
31+
) {
32+
const migrate = new Migrate(prismaSchemaPath)
33+
function run <T> (f: () => T): T {
34+
// only required once - on child process start - but easiest to do this always
35+
const prevDBURLFromEnv = process.env.DATABASE_URL
36+
const prevShadowDBURLFromEnv = process.env.SHADOW_DATABASE_URL
37+
const prevHiddenUpdateMessage = process.env.PRISMA_HIDE_UPDATE_MESSAGE
38+
try {
39+
process.env.DATABASE_URL = system.config.db.url
40+
setOrRemoveEnvVariable('SHADOW_DATABASE_URL', system.config.db.shadowDatabaseUrl)
41+
process.env.PRISMA_HIDE_UPDATE_MESSAGE = '1' // temporarily silence
42+
return f()
43+
} finally {
44+
setOrRemoveEnvVariable('DATABASE_URL', prevDBURLFromEnv)
45+
setOrRemoveEnvVariable('SHADOW_DATABASE_URL', prevShadowDBURLFromEnv)
46+
setOrRemoveEnvVariable('PRISMA_HIDE_UPDATE_MESSAGE', prevHiddenUpdateMessage)
47+
}
5248
}
53-
}
5449

55-
async function withMigrate<T> (schemaPath: string, cb: (migrate: Migrate) => Promise<T>) {
56-
const migrate = new Migrate(schemaPath)
5750
try {
58-
return await cb(migrate)
51+
return await cb({
52+
async apply () { return run(() => migrate.applyMigrations()) },
53+
async diagnostic () { return run(() => migrate.devDiagnostic()) },
54+
async push (force) { return run(() => migrate.push({ force })) },
55+
async reset () { return run(() => migrate.reset()) },
56+
async schema (schema, force) {
57+
const schemaContainer = toSchemasContainer([
58+
[prismaSchemaPath, schema]
59+
])
60+
61+
return run(() => migrate.engine.schemaPush({ force, schema: schemaContainer }))
62+
}
63+
})
5964
} finally {
6065
const closePromise = new Promise<void>(resolve => {
61-
const child = (migrate.engine as any).child as ChildProcess
66+
const { child } = migrate.engine as { child: ChildProcess }
6267
child.once('exit', () => resolve())
6368
})
6469
migrate.stop()
6570
await closePromise
6671
}
6772
}
68-
69-
export async function runMigrationsOnDatabase (cwd: string, system: System) {
70-
const paths = system.getPaths(cwd)
71-
return await withMigrate(paths.schema.prisma, async (migrate) => {
72-
const { appliedMigrationNames } = await runMigrateWithDbUrl(system, () => migrate.applyMigrations())
73-
return appliedMigrationNames
74-
})
75-
}
76-
77-
export async function runMigrationsOnDatabaseMaybeReset (cwd: string, system: System) {
78-
const paths = system.getPaths(cwd)
79-
80-
return await withMigrate(paths.schema.prisma, async (migrate) => {
81-
const diagnostic = await runMigrateWithDbUrl(system, () => migrate.devDiagnostic())
82-
83-
if (diagnostic.action.tag === 'reset') {
84-
console.log(diagnostic.action.reason)
85-
const consent = await confirmPrompt(`Do you want to continue? ${chalk.red('All data will be lost')}`)
86-
if (!consent) throw new ExitError(1)
87-
88-
await runMigrateWithDbUrl(system, () => migrate.reset())
89-
}
90-
91-
const { appliedMigrationNames } = await runMigrateWithDbUrl(system, () => migrate.applyMigrations())
92-
return appliedMigrationNames
93-
})
94-
}
95-
96-
export async function resetDatabase (dbUrl: string, prismaSchemaPath: string) {
97-
await createDatabase(dbUrl, path.dirname(prismaSchemaPath))
98-
const config = {
99-
db: {
100-
url: dbUrl,
101-
shadowDatabaseUrl: ''
102-
}
103-
}
104-
105-
await withMigrate(prismaSchemaPath, async (migrate) => {
106-
await runMigrateWithDbUrl({ config }, () => migrate.reset())
107-
await runMigrateWithDbUrl({ config }, () => migrate.push({ force: true }))
108-
})
109-
}
110-
111-
export async function pushPrismaSchemaToDatabase (
112-
cwd: string,
113-
system: System,
114-
prismaSchema: string, // already exists
115-
interactive: boolean = false
116-
) {
117-
const paths = system.getPaths(cwd)
118-
119-
const created = await createDatabase(system.config.db.url, path.dirname(paths.schema.prisma))
120-
if (interactive && created) {
121-
const credentials = uriToCredentials(system.config.db.url)
122-
console.log(`✨ ${credentials.type} database "${credentials.database}" created at ${getDbLocation(credentials)}`)
123-
}
124-
125-
const migration = await withMigrate(paths.schema.prisma, async migrate => {
126-
// what does force on migrate.engine.schemaPush mean?
127-
// - true: ignore warnings, but unexecutable steps will block
128-
// - false: warnings or unexecutable steps will block
129-
const migration = await runMigrateWithDbUrl(system, () => migrate.engine.schemaPush({ force: false, schema: prismaSchema }))
130-
131-
// if there are unexecutable steps, we need to reset the database [or the user can use migrations]
132-
if (migration.unexecutable.length) {
133-
if (!interactive) throw new ExitError(1)
134-
135-
logUnexecutableSteps(migration.unexecutable)
136-
if (migration.warnings.length) logWarnings(migration.warnings)
137-
138-
console.log('\nTo apply this migration, we need to reset the database')
139-
if (!(await confirmPrompt(`Do you want to continue? ${chalk.red('All data will be lost')}`, false))) {
140-
console.log('Reset cancelled')
141-
throw new ExitError(0)
142-
}
143-
144-
await runMigrateWithDbUrl(system, () => migrate.reset())
145-
return runMigrateWithDbUrl(system, () => migrate.engine.schemaPush({ force: false, schema: prismaSchema }))
146-
}
147-
148-
if (migration.warnings.length) {
149-
if (!interactive) throw new ExitError(1)
150-
151-
logWarnings(migration.warnings)
152-
if (!(await confirmPrompt(`Do you want to continue? ${chalk.red('Some data will be lost')}`, false))) {
153-
console.log('Push cancelled')
154-
throw new ExitError(0)
155-
}
156-
return runMigrateWithDbUrl(system, () => migrate.engine.schemaPush({ force: true, schema: prismaSchema }))
157-
}
158-
159-
return migration
160-
})
161-
162-
if (!interactive) return
163-
if (migration.warnings.length === 0 && migration.executedSteps === 0) {
164-
console.log(`✨ Database unchanged`)
165-
} else {
166-
console.log(`✨ Database synchronized with Prisma schema`)
167-
}
168-
}
169-
170-
function logUnexecutableSteps (unexecutableSteps: string[]) {
171-
console.log(`${chalk.bold.red('\n⚠️ We found changes that cannot be executed:\n')}`)
172-
for (const item of unexecutableSteps) {
173-
console.log(` • ${item}`)
174-
}
175-
}
176-
177-
function logWarnings (warnings: string[]) {
178-
console.warn(chalk.bold(`\n⚠️ Warnings:\n`))
179-
for (const warning of warnings) {
180-
console.warn(` • ${warning}`)
181-
}
182-
}
183-
184-
function getDbLocation (credentials: DatabaseCredentials): string {
185-
if (credentials.type === 'sqlite') {
186-
return credentials.uri!
187-
}
188-
189-
return `${credentials.host}${credentials.port === undefined ? '' : `:${credentials.port}`}`
190-
}

packages/core/src/scripts/build.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import nextBuild from 'next/dist/build'
33
import { generateAdminUI } from '../admin-ui/system'
44
import {
55
createSystem,
6-
getBuiltKeystoneConfiguration
76
} from '../lib/createSystem'
87
import {
98
generateArtifacts,
@@ -13,16 +12,16 @@ import {
1312
} from '../artifacts'
1413
import { getEsbuildConfig } from '../lib/esbuild'
1514
import type { Flags } from './cli'
15+
import { importBuiltKeystoneConfiguration } from './utils'
1616

1717
export async function build (
1818
cwd: string,
1919
{ frozen, prisma, ui }: Pick<Flags, 'frozen' | 'prisma' | 'ui'>
2020
) {
21+
// TODO: should this happen if frozen?
2122
await esbuild.build(getEsbuildConfig(cwd))
2223

23-
// TODO: this cannot be changed for now, circular dependency with getSystemPaths, getEsbuildConfig
24-
const system = createSystem(getBuiltKeystoneConfiguration(cwd))
25-
24+
const system = createSystem(await importBuiltKeystoneConfiguration(cwd))
2625
if (prisma) {
2726
if (frozen) {
2827
await validateArtifacts(cwd, system)

0 commit comments

Comments
 (0)