fix(cpa): updates CPAs w/ vercel-postgres db types to use POSTGRES_URL & updates .env.example to use generic env var strings (#10027)
CPA projects generated with the `vercel-postgres` db type were not receiving the proper DB env vars in the .env.example & .env files With the `vercel-postgres` db type, the DB env var needs to be `POSTGRES_URL` not `DATABASE_URI`. Additionally, updates the generated .env.example file to show generic env var strings. #### Blank w/ MongoDB: - `.env.example`: ``` DATABASE_URI=mongodb://127.0.0.1/your-database-name PAYLOAD_SECRET=YOUR_SECRET_HERE ``` - `.env`: ``` # Added by Payload DATABASE_URI=mongodb://127.0.0.1/test-cpa-blank-mongodb PAYLOAD_SECRET=aef857429edc7f42a90bb374 ``` #### Blank w/ Postgres: - `.env.example`: ``` DATABASE_URI=postgres://postgres:<password>@127.0.0.1:5432/your-database-name PAYLOAD_SECRET=YOUR_SECRET_HERE ``` - `.env`: ``` # Added by Payload DATABASE_URI=postgres://postgres:<password>@127.0.0.1:5432/test-cpa-blank-postgres PAYLOAD_SECRET=241bfe11fbe0a56dd9757019 ``` #### Blank w/ SQLite: - `.env.example`: ``` DATABASE_URI=file:./your-database-name.db PAYLOAD_SECRET=YOUR_SECRET_HERE ``` - `.env`: ``` # Added by Payload DATABASE_URI=file:./test-cpa-blank-sqlite.db PAYLOAD_SECRET=a7808731b93240a73a11930c ``` #### Blank w/ vercel-postgres: - `.env.example`: ``` POSTGRES_URL=postgres://postgres:<password>@127.0.0.1:5432/your-database-name PAYLOAD_SECRET=YOUR_SECRET_HERE ``` - `.env`: ``` # Added by Payload POSTGRES_URL=postgres://postgres:<password>@127.0.0.1:5432/test-cpa-blank-vercel-postgres PAYLOAD_SECRET=af3951e923e8e4662c9c3d9e ``` Fixes #9996
This commit is contained in:
@@ -4,42 +4,66 @@ import path from 'path'
|
||||
import type { CliArgs, DbType, ProjectTemplate } from '../types.js'
|
||||
|
||||
import { debug, error } from '../utils/log.js'
|
||||
import { dbChoiceRecord } from './select-db.js'
|
||||
|
||||
const updateEnvVariables = (
|
||||
contents: string,
|
||||
const updateEnvExampleVariables = (contents: string, databaseType: DbType | undefined): string => {
|
||||
return contents
|
||||
.split('\n')
|
||||
.map((line) => {
|
||||
if (line.startsWith('#') || !line.includes('=')) {
|
||||
return line // Preserve comments and unrelated lines
|
||||
}
|
||||
|
||||
const [key] = line.split('=')
|
||||
|
||||
if (key === 'DATABASE_URI' || key === 'POSTGRES_URL' || key === 'MONGODB_URI') {
|
||||
const dbChoice = databaseType ? dbChoiceRecord[databaseType] : null
|
||||
|
||||
if (dbChoice) {
|
||||
const placeholderUri = `${dbChoice.dbConnectionPrefix}your-database-name${
|
||||
dbChoice.dbConnectionSuffix || ''
|
||||
}`
|
||||
return databaseType === 'vercel-postgres'
|
||||
? `POSTGRES_URL=${placeholderUri}`
|
||||
: `DATABASE_URI=${placeholderUri}`
|
||||
}
|
||||
|
||||
return `DATABASE_URI=your-database-connection-here` // Fallback
|
||||
}
|
||||
|
||||
if (key === 'PAYLOAD_SECRET' || key === 'PAYLOAD_SECRET_KEY') {
|
||||
return `PAYLOAD_SECRET=YOUR_SECRET_HERE`
|
||||
}
|
||||
|
||||
return line
|
||||
})
|
||||
.join('\n')
|
||||
}
|
||||
|
||||
const generateEnvContent = (
|
||||
existingEnv: string,
|
||||
databaseType: DbType | undefined,
|
||||
databaseUri: string,
|
||||
payloadSecret: string,
|
||||
): string => {
|
||||
return contents
|
||||
const dbKey = databaseType === 'vercel-postgres' ? 'POSTGRES_URL' : 'DATABASE_URI'
|
||||
|
||||
const envVars: Record<string, string> = {}
|
||||
existingEnv
|
||||
.split('\n')
|
||||
.filter((e) => e)
|
||||
.map((line) => {
|
||||
if (line.startsWith('#') || !line.includes('=')) {
|
||||
return line
|
||||
}
|
||||
|
||||
const [key, ...valueParts] = line.split('=')
|
||||
let value = valueParts.join('=')
|
||||
|
||||
if (
|
||||
key === 'MONGODB_URI' ||
|
||||
key === 'MONGO_URL' ||
|
||||
key === 'DATABASE_URI' ||
|
||||
key === 'POSTGRES_URL'
|
||||
) {
|
||||
value = databaseUri
|
||||
if (databaseType === 'vercel-postgres') {
|
||||
value = databaseUri
|
||||
}
|
||||
}
|
||||
|
||||
if (key === 'PAYLOAD_SECRET' || key === 'PAYLOAD_SECRET_KEY') {
|
||||
value = payloadSecret
|
||||
}
|
||||
|
||||
return `${key}=${value}`
|
||||
.filter((line) => line.includes('=') && !line.startsWith('#'))
|
||||
.forEach((line) => {
|
||||
const [key, value] = line.split('=')
|
||||
envVars[key] = value
|
||||
})
|
||||
|
||||
// Override specific keys
|
||||
envVars[dbKey] = databaseUri
|
||||
envVars['PAYLOAD_SECRET'] = payloadSecret
|
||||
|
||||
// Rebuild content
|
||||
return Object.entries(envVars)
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join('\n')
|
||||
}
|
||||
|
||||
@@ -65,6 +89,7 @@ export async function manageEnvFiles(args: {
|
||||
try {
|
||||
let updatedExampleContents: string
|
||||
|
||||
// Update .env.example
|
||||
if (template?.type === 'starter') {
|
||||
if (!fs.existsSync(envExamplePath)) {
|
||||
error(`.env.example file not found at ${envExamplePath}`)
|
||||
@@ -72,25 +97,25 @@ export async function manageEnvFiles(args: {
|
||||
}
|
||||
|
||||
const envExampleContents = await fs.readFile(envExamplePath, 'utf8')
|
||||
updatedExampleContents = updateEnvVariables(
|
||||
envExampleContents,
|
||||
databaseType,
|
||||
databaseUri,
|
||||
payloadSecret,
|
||||
)
|
||||
updatedExampleContents = updateEnvExampleVariables(envExampleContents, databaseType)
|
||||
|
||||
await fs.writeFile(envExamplePath, updatedExampleContents)
|
||||
await fs.writeFile(envExamplePath, updatedExampleContents.trimEnd() + '\n')
|
||||
debug(`.env.example file successfully updated`)
|
||||
} else {
|
||||
updatedExampleContents = `# Added by Payload\nDATABASE_URI=${databaseUri}\nPAYLOAD_SECRET=${payloadSecret}\n`
|
||||
updatedExampleContents = `# Added by Payload\nDATABASE_URI=your-connection-string-here\nPAYLOAD_SECRET=YOUR_SECRET_HERE\n`
|
||||
await fs.writeFile(envExamplePath, updatedExampleContents.trimEnd() + '\n')
|
||||
}
|
||||
|
||||
const existingEnvContents = fs.existsSync(envPath) ? await fs.readFile(envPath, 'utf8') : ''
|
||||
const updatedEnvContents = existingEnvContents
|
||||
? `${existingEnvContents}\n# Added by Payload\n${updatedExampleContents}`
|
||||
: `# Added by Payload\n${updatedExampleContents}`
|
||||
// Merge existing variables and create or update .env
|
||||
const envExampleContents = await fs.readFile(envExamplePath, 'utf8')
|
||||
const envContent = generateEnvContent(
|
||||
envExampleContents,
|
||||
databaseType,
|
||||
databaseUri,
|
||||
payloadSecret,
|
||||
)
|
||||
await fs.writeFile(envPath, `# Added by Payload\n${envContent.trimEnd()}\n`)
|
||||
|
||||
await fs.writeFile(envPath, updatedEnvContents)
|
||||
debug(`.env file successfully created or updated`)
|
||||
} catch (err: unknown) {
|
||||
error('Unable to manage environment files')
|
||||
|
||||
@@ -10,7 +10,7 @@ type DbChoice = {
|
||||
value: DbType
|
||||
}
|
||||
|
||||
const dbChoiceRecord: Record<DbType, DbChoice> = {
|
||||
export const dbChoiceRecord: Record<DbType, DbChoice> = {
|
||||
mongodb: {
|
||||
dbConnectionPrefix: 'mongodb://127.0.0.1/',
|
||||
title: 'MongoDB',
|
||||
|
||||
Reference in New Issue
Block a user