feat(cpa): update existing payload installation (#6193)
Updates create-payload-app to update an existing payload installation - Detects existing Payload installation. Fixes #6517 - If not latest, will install latest and grab the `(payload)` directory structure (ripped from `templates/blank-3.0`
This commit is contained in:
@@ -6,24 +6,24 @@ import execa from 'execa'
|
||||
import fs from 'fs'
|
||||
import fse from 'fs-extra'
|
||||
import globby from 'globby'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import path from 'path'
|
||||
import { promisify } from 'util'
|
||||
|
||||
import type { CliArgs, DbType, NextAppDetails, NextConfigType, PackageManager } from '../types.js'
|
||||
|
||||
import { copyRecursiveSync } from '../utils/copy-recursive-sync.js'
|
||||
import { debug as origDebug, warning } from '../utils/log.js'
|
||||
import { moveMessage } from '../utils/messages.js'
|
||||
import { installPackages } from './install-packages.js'
|
||||
import { wrapNextConfig } from './wrap-next-config.js'
|
||||
|
||||
const readFile = promisify(fs.readFile)
|
||||
const writeFile = promisify(fs.writeFile)
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import type { CliArgs, DbType, PackageManager } from '../types.js'
|
||||
|
||||
import { copyRecursiveSync } from '../utils/copy-recursive-sync.js'
|
||||
import { debug as origDebug, warning } from '../utils/log.js'
|
||||
import { moveMessage } from '../utils/messages.js'
|
||||
import { wrapNextConfig } from './wrap-next-config.js'
|
||||
|
||||
type InitNextArgs = Pick<CliArgs, '--debug'> & {
|
||||
dbType: DbType
|
||||
nextAppDetails?: NextAppDetails
|
||||
@@ -32,8 +32,6 @@ type InitNextArgs = Pick<CliArgs, '--debug'> & {
|
||||
useDistFiles?: boolean
|
||||
}
|
||||
|
||||
type NextConfigType = 'cjs' | 'esm'
|
||||
|
||||
type InitNextResult =
|
||||
| {
|
||||
isSrcDir: boolean
|
||||
@@ -55,7 +53,8 @@ export async function initNext(args: InitNextArgs): Promise<InitNextResult> {
|
||||
nextAppDetails.nextAppDir = createdAppDir
|
||||
}
|
||||
|
||||
const { hasTopLevelLayout, isSrcDir, nextAppDir, nextConfigType } = nextAppDetails
|
||||
const { hasTopLevelLayout, isPayloadInstalled, isSrcDir, nextAppDir, nextConfigType } =
|
||||
nextAppDetails
|
||||
|
||||
if (!nextConfigType) {
|
||||
return {
|
||||
@@ -228,37 +227,10 @@ async function installDeps(projectDir: string, packageManager: PackageManager, d
|
||||
|
||||
packagesToInstall.push(`@payloadcms/db-${dbType}@beta`)
|
||||
|
||||
let exitCode = 0
|
||||
switch (packageManager) {
|
||||
case 'npm': {
|
||||
;({ exitCode } = await execa('npm', ['install', '--save', ...packagesToInstall], {
|
||||
cwd: projectDir,
|
||||
}))
|
||||
break
|
||||
}
|
||||
case 'yarn':
|
||||
case 'pnpm': {
|
||||
;({ exitCode } = await execa(packageManager, ['add', ...packagesToInstall], {
|
||||
cwd: projectDir,
|
||||
}))
|
||||
break
|
||||
}
|
||||
case 'bun': {
|
||||
warning('Bun support is untested.')
|
||||
;({ exitCode } = await execa('bun', ['add', ...packagesToInstall], { cwd: projectDir }))
|
||||
break
|
||||
}
|
||||
}
|
||||
// Match graphql version of @payloadcms/next
|
||||
packagesToInstall.push('graphql@^16.8.1')
|
||||
|
||||
return { success: exitCode === 0 }
|
||||
}
|
||||
|
||||
type NextAppDetails = {
|
||||
hasTopLevelLayout: boolean
|
||||
isSrcDir: boolean
|
||||
nextAppDir?: string
|
||||
nextConfigPath?: string
|
||||
nextConfigType?: NextConfigType
|
||||
return await installPackages({ packageManager, packagesToInstall, projectDir })
|
||||
}
|
||||
|
||||
export async function getNextAppDetails(projectDir: string): Promise<NextAppDetails> {
|
||||
@@ -267,6 +239,7 @@ export async function getNextAppDetails(projectDir: string): Promise<NextAppDeta
|
||||
const nextConfigPath: string | undefined = (
|
||||
await globby('next.config.*js', { absolute: true, cwd: projectDir })
|
||||
)?.[0]
|
||||
|
||||
if (!nextConfigPath || nextConfigPath.length === 0) {
|
||||
return {
|
||||
hasTopLevelLayout: false,
|
||||
@@ -275,6 +248,16 @@ export async function getNextAppDetails(projectDir: string): Promise<NextAppDeta
|
||||
}
|
||||
}
|
||||
|
||||
const packageObj = await fse.readJson(path.resolve(projectDir, 'package.json'))
|
||||
if (packageObj.dependencies?.payload) {
|
||||
return {
|
||||
hasTopLevelLayout: false,
|
||||
isPayloadInstalled: true,
|
||||
isSrcDir,
|
||||
nextConfigPath,
|
||||
}
|
||||
}
|
||||
|
||||
let nextAppDir: string | undefined = (
|
||||
await globby(['**/app'], {
|
||||
absolute: true,
|
||||
@@ -288,7 +271,7 @@ export async function getNextAppDetails(projectDir: string): Promise<NextAppDeta
|
||||
nextAppDir = undefined
|
||||
}
|
||||
|
||||
const configType = await getProjectType(projectDir, nextConfigPath)
|
||||
const configType = getProjectType({ nextConfigPath, packageObj })
|
||||
|
||||
const hasTopLevelLayout = nextAppDir
|
||||
? fs.existsSync(path.resolve(nextAppDir, 'layout.tsx'))
|
||||
@@ -297,7 +280,11 @@ export async function getNextAppDetails(projectDir: string): Promise<NextAppDeta
|
||||
return { hasTopLevelLayout, isSrcDir, nextAppDir, nextConfigPath, nextConfigType: configType }
|
||||
}
|
||||
|
||||
async function getProjectType(projectDir: string, nextConfigPath: string): Promise<'cjs' | 'esm'> {
|
||||
function getProjectType(args: {
|
||||
nextConfigPath: string
|
||||
packageObj: Record<string, unknown>
|
||||
}): 'cjs' | 'esm' {
|
||||
const { nextConfigPath, packageObj } = args
|
||||
if (nextConfigPath.endsWith('.mjs')) {
|
||||
return 'esm'
|
||||
}
|
||||
@@ -305,7 +292,6 @@ async function getProjectType(projectDir: string, nextConfigPath: string): Promi
|
||||
return 'cjs'
|
||||
}
|
||||
|
||||
const packageObj = await fse.readJson(path.resolve(projectDir, 'package.json'))
|
||||
const packageJsonType = packageObj.type
|
||||
if (packageJsonType === 'module') {
|
||||
return 'esm'
|
||||
|
||||
Reference in New Issue
Block a user