Skip to content

Commit 1aa23d3

Browse files
authored
chore(cpa): updates .env.example env vars along side .env vars based on selected DB (#9757)
### What? Previously, the create-payload-app install would properly update the env vars in the new created `.env` file but kept outdated env vars in the `.env.example` file. I.e If selecting a `postgres` DB for the blank or website template: `.env` --> `DATABASE_URI` --> `postgres://postgres:<password>@127.0.0.1:5432/test-cpa` `.env.example` --> `DATABASE_URI` --> `mongodb://127.0.0.1/payload-template-blank-3-0` ### Now `.env` --> `DATABASE_URI` --> `postgres://postgres:<password>@127.0.0.1:5432/test-cpa` `.env.example` --> `DATABASE_URI` --> `postgres://postgres:<password>@127.0.0.1:5432/test-cpa`
1 parent a1a0a07 commit 1aa23d3

File tree

3 files changed

+108
-87
lines changed

3 files changed

+108
-87
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import fs from 'fs-extra'
2+
import path from 'path'
3+
4+
import type { CliArgs, DbType, ProjectTemplate } from '../types.js'
5+
6+
import { debug, error } from '../utils/log.js'
7+
8+
const updateEnvVariables = (
9+
contents: string,
10+
databaseType: DbType | undefined,
11+
databaseUri: string,
12+
payloadSecret: string,
13+
): string => {
14+
return contents
15+
.split('\n')
16+
.filter((e) => e)
17+
.map((line) => {
18+
if (line.startsWith('#') || !line.includes('=')) {
19+
return line
20+
}
21+
22+
const [key, ...valueParts] = line.split('=')
23+
let value = valueParts.join('=')
24+
25+
if (
26+
key === 'MONGODB_URI' ||
27+
key === 'MONGO_URL' ||
28+
key === 'DATABASE_URI' ||
29+
key === 'POSTGRES_URL'
30+
) {
31+
value = databaseUri
32+
if (databaseType === 'vercel-postgres') {
33+
value = databaseUri
34+
}
35+
}
36+
37+
if (key === 'PAYLOAD_SECRET' || key === 'PAYLOAD_SECRET_KEY') {
38+
value = payloadSecret
39+
}
40+
41+
return `${key}=${value}`
42+
})
43+
.join('\n')
44+
}
45+
46+
/** Parse and swap .env.example values and write .env */
47+
export async function manageEnvFiles(args: {
48+
cliArgs: CliArgs
49+
databaseType?: DbType
50+
databaseUri: string
51+
payloadSecret: string
52+
projectDir: string
53+
template?: ProjectTemplate
54+
}): Promise<void> {
55+
const { cliArgs, databaseType, databaseUri, payloadSecret, projectDir, template } = args
56+
57+
if (cliArgs['--dry-run']) {
58+
debug(`DRY RUN: Environment files managed`)
59+
return
60+
}
61+
62+
const envExamplePath = path.join(projectDir, '.env.example')
63+
const envPath = path.join(projectDir, '.env')
64+
65+
try {
66+
let updatedExampleContents: string
67+
68+
if (template?.type === 'starter') {
69+
if (!fs.existsSync(envExamplePath)) {
70+
error(`.env.example file not found at ${envExamplePath}`)
71+
process.exit(1)
72+
}
73+
74+
const envExampleContents = await fs.readFile(envExamplePath, 'utf8')
75+
updatedExampleContents = updateEnvVariables(
76+
envExampleContents,
77+
databaseType,
78+
databaseUri,
79+
payloadSecret,
80+
)
81+
82+
await fs.writeFile(envExamplePath, updatedExampleContents)
83+
debug(`.env.example file successfully updated`)
84+
} else {
85+
updatedExampleContents = `# Added by Payload\nDATABASE_URI=${databaseUri}\nPAYLOAD_SECRET=${payloadSecret}\n`
86+
}
87+
88+
const existingEnvContents = fs.existsSync(envPath) ? await fs.readFile(envPath, 'utf8') : ''
89+
const updatedEnvContents = existingEnvContents
90+
? `${existingEnvContents}\n# Added by Payload\n${updatedExampleContents}`
91+
: `# Added by Payload\n${updatedExampleContents}`
92+
93+
await fs.writeFile(envPath, updatedEnvContents)
94+
debug(`.env file successfully created or updated`)
95+
} catch (err: unknown) {
96+
error('Unable to manage environment files')
97+
if (err instanceof Error) {
98+
error(err.message)
99+
}
100+
process.exit(1)
101+
}
102+
}

packages/create-payload-app/src/lib/write-env-file.ts

Lines changed: 0 additions & 84 deletions
This file was deleted.

packages/create-payload-app/src/main.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ import { createProject } from './lib/create-project.js'
1313
import { generateSecret } from './lib/generate-secret.js'
1414
import { getPackageManager } from './lib/get-package-manager.js'
1515
import { getNextAppDetails, initNext } from './lib/init-next.js'
16+
import { manageEnvFiles } from './lib/manage-env-files.js'
1617
import { parseProjectName } from './lib/parse-project-name.js'
1718
import { parseTemplate } from './lib/parse-template.js'
1819
import { selectDb } from './lib/select-db.js'
1920
import { getValidTemplates, validateTemplate } from './lib/templates.js'
2021
import { updatePayloadInProject } from './lib/update-payload-in-project.js'
21-
import { writeEnvFile } from './lib/write-env-file.js'
2222
import { debug, error, info } from './utils/log.js'
2323
import {
2424
feedbackOutro,
@@ -181,7 +181,7 @@ export class Main {
181181
},
182182
})
183183

184-
await writeEnvFile({
184+
await manageEnvFiles({
185185
cliArgs: this.args,
186186
databaseType: dbDetails.type,
187187
databaseUri: dbDetails.dbUri,
@@ -230,6 +230,7 @@ export class Main {
230230
case 'starter': {
231231
const dbDetails = await selectDb(this.args, projectName)
232232
const payloadSecret = generateSecret()
233+
233234
await createProject({
234235
cliArgs: this.args,
235236
dbDetails,
@@ -238,14 +239,16 @@ export class Main {
238239
projectName,
239240
template,
240241
})
241-
await writeEnvFile({
242+
243+
await manageEnvFiles({
242244
cliArgs: this.args,
243245
databaseType: dbDetails.type,
244246
databaseUri: dbDetails.dbUri,
245247
payloadSecret,
246248
projectDir,
247249
template,
248250
})
251+
249252
break
250253
}
251254
}

0 commit comments

Comments
 (0)