create-payload-app 3.37.0-canary.1 → 3.37.0-canary.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,7 @@ import path from 'path';
7
7
  import { createProject } from './create-project.js';
8
8
  import { dbReplacements } from './replacements.js';
9
9
  import { getValidTemplates } from './templates.js';
10
+ import { manageEnvFiles } from './manage-env-files.js';
10
11
  describe('createProject', ()=>{
11
12
  let projectDir;
12
13
  beforeAll(()=>{
@@ -129,6 +130,61 @@ describe('createProject', ()=>{
129
130
  expect(content).toContain(dbReplacement.configReplacement().join('\n'));
130
131
  });
131
132
  });
133
+ describe('managing env files', ()=>{
134
+ it('updates .env files without overwriting existing data', async ()=>{
135
+ const envFilePath = path.join(projectDir, '.env');
136
+ const envExampleFilePath = path.join(projectDir, '.env.example');
137
+ fse.ensureDirSync(projectDir);
138
+ fse.ensureFileSync(envFilePath);
139
+ fse.ensureFileSync(envExampleFilePath);
140
+ const initialEnvContent = `CUSTOM_VAR=custom-value\nDATABASE_URI=old-connection\n`;
141
+ const initialEnvExampleContent = `CUSTOM_VAR=custom-value\nDATABASE_URI=old-connection\nPAYLOAD_SECRET=YOUR_SECRET_HERE\n`;
142
+ fse.writeFileSync(envFilePath, initialEnvContent);
143
+ fse.writeFileSync(envExampleFilePath, initialEnvExampleContent);
144
+ await manageEnvFiles({
145
+ cliArgs: {
146
+ '--debug': true
147
+ },
148
+ databaseType: 'mongodb',
149
+ databaseUri: 'mongodb://localhost:27017/test',
150
+ payloadSecret: 'test-secret',
151
+ projectDir,
152
+ template: undefined
153
+ });
154
+ const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8');
155
+ expect(updatedEnvContent).toContain('CUSTOM_VAR=custom-value');
156
+ expect(updatedEnvContent).toContain('DATABASE_URI=mongodb://localhost:27017/test');
157
+ expect(updatedEnvContent).toContain('PAYLOAD_SECRET=test-secret');
158
+ const updatedEnvExampleContent = fse.readFileSync(envExampleFilePath, 'utf-8');
159
+ expect(updatedEnvExampleContent).toContain('CUSTOM_VAR=custom-value');
160
+ expect(updatedEnvContent).toContain('DATABASE_URI=mongodb://localhost:27017/test');
161
+ expect(updatedEnvContent).toContain('PAYLOAD_SECRET=test-secret');
162
+ });
163
+ it('creates .env and .env.example if they do not exist', async ()=>{
164
+ const envFilePath = path.join(projectDir, '.env');
165
+ const envExampleFilePath = path.join(projectDir, '.env.example');
166
+ fse.ensureDirSync(projectDir);
167
+ if (fse.existsSync(envFilePath)) fse.removeSync(envFilePath);
168
+ if (fse.existsSync(envExampleFilePath)) fse.removeSync(envExampleFilePath);
169
+ await manageEnvFiles({
170
+ cliArgs: {
171
+ '--debug': true
172
+ },
173
+ databaseUri: '',
174
+ payloadSecret: '',
175
+ projectDir,
176
+ template: undefined
177
+ });
178
+ expect(fse.existsSync(envFilePath)).toBe(true);
179
+ expect(fse.existsSync(envExampleFilePath)).toBe(true);
180
+ const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8');
181
+ expect(updatedEnvContent).toContain('DATABASE_URI=your-connection-string-here');
182
+ expect(updatedEnvContent).toContain('PAYLOAD_SECRET=YOUR_SECRET_HERE');
183
+ const updatedEnvExampleContent = fse.readFileSync(envExampleFilePath, 'utf-8');
184
+ expect(updatedEnvExampleContent).toContain('DATABASE_URI=your-connection-string-here');
185
+ expect(updatedEnvExampleContent).toContain('PAYLOAD_SECRET=YOUR_SECRET_HERE');
186
+ });
187
+ });
132
188
  });
133
189
  });
134
190
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/create-project.spec.ts"],"sourcesContent":["import { jest } from '@jest/globals'\nimport fs from 'fs'\nimport fse from 'fs-extra'\nimport globby from 'globby'\nimport * as os from 'node:os'\nimport path from 'path'\n\nimport type { CliArgs, DbType, ProjectExample, ProjectTemplate } from '../types.js'\n\nimport { createProject } from './create-project.js'\nimport { dbReplacements } from './replacements.js'\nimport { getValidTemplates } from './templates.js'\n\ndescribe('createProject', () => {\n let projectDir: string\n beforeAll(() => {\n // eslint-disable-next-line no-console\n console.log = jest.fn()\n })\n\n beforeEach(() => {\n const tempDirectory = fs.realpathSync(os.tmpdir())\n projectDir = `${tempDirectory}/${Math.random().toString(36).substring(7)}`\n })\n\n afterEach(() => {\n if (fse.existsSync(projectDir)) {\n fse.rmSync(projectDir, { recursive: true })\n }\n })\n\n describe('#createProject', () => {\n const args = {\n _: ['project-name'],\n '--db': 'mongodb',\n '--local-template': 'blank',\n '--no-deps': true,\n } as CliArgs\n const packageManager = 'yarn'\n\n it('creates plugin template', async () => {\n const projectName = 'plugin'\n const template: ProjectTemplate = {\n name: 'plugin',\n type: 'plugin',\n description: 'Template for creating a Payload plugin',\n url: 'https://github.com/payloadcms/payload/templates/plugin',\n }\n\n await createProject({\n cliArgs: { ...args, '--local-template': 'plugin' } as CliArgs,\n packageManager,\n projectDir,\n projectName,\n template,\n })\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Check package name and description\n expect(packageJson.name).toStrictEqual(projectName)\n })\n\n it('creates example', async () => {\n const projectName = 'custom-server-example'\n const example: ProjectExample = {\n name: 'custom-server',\n url: 'https://github.com/payloadcms/payload/examples/custom-server#main',\n }\n\n await createProject({\n cliArgs: {\n ...args,\n '--local-template': undefined,\n '--local-example': 'custom-server',\n } as CliArgs,\n packageManager,\n projectDir,\n projectName,\n example,\n })\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Check package name and description\n expect(packageJson.name).toStrictEqual(projectName)\n })\n\n describe('creates project from template', () => {\n const templates = getValidTemplates()\n\n it.each([\n ['blank', 'mongodb'],\n ['blank', 'postgres'],\n\n // TODO: Re-enable these once 3.0 is stable and templates updated\n // ['website', 'mongodb'],\n // ['website', 'postgres'],\n // ['ecommerce', 'mongodb'],\n // ['ecommerce', 'postgres'],\n ])('update config and deps: %s, %s', async (templateName, db) => {\n const projectName = 'starter-project'\n\n const template = templates.find((t) => t.name === templateName)\n\n const cliArgs = {\n ...args,\n '--db': db,\n '--local-template': templateName,\n } as CliArgs\n\n await createProject({\n cliArgs,\n dbDetails: {\n type: db as DbType,\n dbUri: `${db}://localhost:27017/create-project-test`,\n },\n packageManager,\n projectDir,\n projectName,\n template: template as ProjectTemplate,\n })\n\n const dbReplacement = dbReplacements[db as DbType]\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Verify git was initialized\n expect(fse.existsSync(path.resolve(projectDir, '.git'))).toBe(true)\n\n // Should only have one db adapter\n expect(\n Object.keys(packageJson.dependencies).filter((n) => n.startsWith('@payloadcms/db-')),\n ).toHaveLength(1)\n\n const payloadConfigPath = (\n await globby('**/payload.config.ts', {\n absolute: true,\n cwd: projectDir,\n })\n )?.[0]\n\n const content = fse.readFileSync(payloadConfigPath, 'utf-8')\n\n // Check payload.config.ts\n expect(content).not.toContain('// database-adapter-import')\n expect(content).toContain(dbReplacement.importReplacement)\n\n expect(content).not.toContain('// database-adapter-config-start')\n expect(content).not.toContain('// database-adapter-config-end')\n expect(content).toContain(dbReplacement.configReplacement().join('\\n'))\n })\n })\n })\n})\n"],"names":["jest","fs","fse","globby","os","path","createProject","dbReplacements","getValidTemplates","describe","projectDir","beforeAll","console","log","fn","beforeEach","tempDirectory","realpathSync","tmpdir","Math","random","toString","substring","afterEach","existsSync","rmSync","recursive","args","_","packageManager","it","projectName","template","name","type","description","url","cliArgs","packageJsonPath","resolve","packageJson","readJsonSync","expect","toStrictEqual","example","undefined","templates","each","templateName","db","find","t","dbDetails","dbUri","dbReplacement","toBe","Object","keys","dependencies","filter","n","startsWith","toHaveLength","payloadConfigPath","absolute","cwd","content","readFileSync","not","toContain","importReplacement","configReplacement","join"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/lib/create-project.spec.ts"],"sourcesContent":["import { jest } from '@jest/globals'\nimport fs from 'fs'\nimport fse from 'fs-extra'\nimport globby from 'globby'\nimport * as os from 'node:os'\nimport path from 'path'\n\nimport type { CliArgs, DbType, ProjectExample, ProjectTemplate } from '../types.js'\n\nimport { createProject } from './create-project.js'\nimport { dbReplacements } from './replacements.js'\nimport { getValidTemplates } from './templates.js'\nimport { manageEnvFiles } from './manage-env-files.js'\n\ndescribe('createProject', () => {\n let projectDir: string\n beforeAll(() => {\n // eslint-disable-next-line no-console\n console.log = jest.fn()\n })\n\n beforeEach(() => {\n const tempDirectory = fs.realpathSync(os.tmpdir())\n projectDir = `${tempDirectory}/${Math.random().toString(36).substring(7)}`\n })\n\n afterEach(() => {\n if (fse.existsSync(projectDir)) {\n fse.rmSync(projectDir, { recursive: true })\n }\n })\n\n describe('#createProject', () => {\n const args = {\n _: ['project-name'],\n '--db': 'mongodb',\n '--local-template': 'blank',\n '--no-deps': true,\n } as CliArgs\n const packageManager = 'yarn'\n\n it('creates plugin template', async () => {\n const projectName = 'plugin'\n const template: ProjectTemplate = {\n name: 'plugin',\n type: 'plugin',\n description: 'Template for creating a Payload plugin',\n url: 'https://github.com/payloadcms/payload/templates/plugin',\n }\n\n await createProject({\n cliArgs: { ...args, '--local-template': 'plugin' } as CliArgs,\n packageManager,\n projectDir,\n projectName,\n template,\n })\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Check package name and description\n expect(packageJson.name).toStrictEqual(projectName)\n })\n\n it('creates example', async () => {\n const projectName = 'custom-server-example'\n const example: ProjectExample = {\n name: 'custom-server',\n url: 'https://github.com/payloadcms/payload/examples/custom-server#main',\n }\n\n await createProject({\n cliArgs: {\n ...args,\n '--local-template': undefined,\n '--local-example': 'custom-server',\n } as CliArgs,\n packageManager,\n projectDir,\n projectName,\n example,\n })\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Check package name and description\n expect(packageJson.name).toStrictEqual(projectName)\n })\n\n describe('creates project from template', () => {\n const templates = getValidTemplates()\n\n it.each([\n ['blank', 'mongodb'],\n ['blank', 'postgres'],\n\n // TODO: Re-enable these once 3.0 is stable and templates updated\n // ['website', 'mongodb'],\n // ['website', 'postgres'],\n // ['ecommerce', 'mongodb'],\n // ['ecommerce', 'postgres'],\n ])('update config and deps: %s, %s', async (templateName, db) => {\n const projectName = 'starter-project'\n\n const template = templates.find((t) => t.name === templateName)\n\n const cliArgs = {\n ...args,\n '--db': db,\n '--local-template': templateName,\n } as CliArgs\n\n await createProject({\n cliArgs,\n dbDetails: {\n type: db as DbType,\n dbUri: `${db}://localhost:27017/create-project-test`,\n },\n packageManager,\n projectDir,\n projectName,\n template: template as ProjectTemplate,\n })\n\n const dbReplacement = dbReplacements[db as DbType]\n\n const packageJsonPath = path.resolve(projectDir, 'package.json')\n const packageJson = fse.readJsonSync(packageJsonPath)\n\n // Verify git was initialized\n expect(fse.existsSync(path.resolve(projectDir, '.git'))).toBe(true)\n\n // Should only have one db adapter\n expect(\n Object.keys(packageJson.dependencies).filter((n) => n.startsWith('@payloadcms/db-')),\n ).toHaveLength(1)\n\n const payloadConfigPath = (\n await globby('**/payload.config.ts', {\n absolute: true,\n cwd: projectDir,\n })\n )?.[0]\n\n const content = fse.readFileSync(payloadConfigPath, 'utf-8')\n\n // Check payload.config.ts\n expect(content).not.toContain('// database-adapter-import')\n expect(content).toContain(dbReplacement.importReplacement)\n\n expect(content).not.toContain('// database-adapter-config-start')\n expect(content).not.toContain('// database-adapter-config-end')\n expect(content).toContain(dbReplacement.configReplacement().join('\\n'))\n })\n })\n describe('managing env files', () => {\n it('updates .env files without overwriting existing data', async () => {\n const envFilePath = path.join(projectDir, '.env')\n const envExampleFilePath = path.join(projectDir, '.env.example')\n\n fse.ensureDirSync(projectDir)\n fse.ensureFileSync(envFilePath)\n fse.ensureFileSync(envExampleFilePath)\n\n const initialEnvContent = `CUSTOM_VAR=custom-value\\nDATABASE_URI=old-connection\\n`\n const initialEnvExampleContent = `CUSTOM_VAR=custom-value\\nDATABASE_URI=old-connection\\nPAYLOAD_SECRET=YOUR_SECRET_HERE\\n`\n\n fse.writeFileSync(envFilePath, initialEnvContent)\n fse.writeFileSync(envExampleFilePath, initialEnvExampleContent)\n\n await manageEnvFiles({\n cliArgs: {\n '--debug': true,\n } as CliArgs,\n databaseType: 'mongodb',\n databaseUri: 'mongodb://localhost:27017/test',\n payloadSecret: 'test-secret',\n projectDir,\n template: undefined,\n })\n\n const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8')\n\n expect(updatedEnvContent).toContain('CUSTOM_VAR=custom-value')\n expect(updatedEnvContent).toContain('DATABASE_URI=mongodb://localhost:27017/test')\n expect(updatedEnvContent).toContain('PAYLOAD_SECRET=test-secret')\n\n const updatedEnvExampleContent = fse.readFileSync(envExampleFilePath, 'utf-8')\n\n expect(updatedEnvExampleContent).toContain('CUSTOM_VAR=custom-value')\n expect(updatedEnvContent).toContain('DATABASE_URI=mongodb://localhost:27017/test')\n expect(updatedEnvContent).toContain('PAYLOAD_SECRET=test-secret')\n })\n\n it('creates .env and .env.example if they do not exist', async () => {\n const envFilePath = path.join(projectDir, '.env')\n const envExampleFilePath = path.join(projectDir, '.env.example')\n\n fse.ensureDirSync(projectDir)\n\n if (fse.existsSync(envFilePath)) fse.removeSync(envFilePath)\n if (fse.existsSync(envExampleFilePath)) fse.removeSync(envExampleFilePath)\n\n await manageEnvFiles({\n cliArgs: {\n '--debug': true,\n } as CliArgs,\n databaseUri: '',\n payloadSecret: '',\n projectDir,\n template: undefined,\n })\n\n expect(fse.existsSync(envFilePath)).toBe(true)\n expect(fse.existsSync(envExampleFilePath)).toBe(true)\n\n const updatedEnvContent = fse.readFileSync(envFilePath, 'utf-8')\n expect(updatedEnvContent).toContain('DATABASE_URI=your-connection-string-here')\n expect(updatedEnvContent).toContain('PAYLOAD_SECRET=YOUR_SECRET_HERE')\n\n const updatedEnvExampleContent = fse.readFileSync(envExampleFilePath, 'utf-8')\n expect(updatedEnvExampleContent).toContain('DATABASE_URI=your-connection-string-here')\n expect(updatedEnvExampleContent).toContain('PAYLOAD_SECRET=YOUR_SECRET_HERE')\n })\n })\n })\n})\n"],"names":["jest","fs","fse","globby","os","path","createProject","dbReplacements","getValidTemplates","manageEnvFiles","describe","projectDir","beforeAll","console","log","fn","beforeEach","tempDirectory","realpathSync","tmpdir","Math","random","toString","substring","afterEach","existsSync","rmSync","recursive","args","_","packageManager","it","projectName","template","name","type","description","url","cliArgs","packageJsonPath","resolve","packageJson","readJsonSync","expect","toStrictEqual","example","undefined","templates","each","templateName","db","find","t","dbDetails","dbUri","dbReplacement","toBe","Object","keys","dependencies","filter","n","startsWith","toHaveLength","payloadConfigPath","absolute","cwd","content","readFileSync","not","toContain","importReplacement","configReplacement","join","envFilePath","envExampleFilePath","ensureDirSync","ensureFileSync","initialEnvContent","initialEnvExampleContent","writeFileSync","databaseType","databaseUri","payloadSecret","updatedEnvContent","updatedEnvExampleContent","removeSync"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"manage-env-files.d.ts","sourceRoot":"","sources":["../../src/lib/manage-env-files.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAmEnE,wDAAwD;AACxD,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,eAAe,CAAA;CAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDhB"}
1
+ {"version":3,"file":"manage-env-files.d.ts","sourceRoot":"","sources":["../../src/lib/manage-env-files.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAwDnE,wDAAwD;AACxD,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,eAAe,CAAA;CAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFhB"}
@@ -2,41 +2,34 @@ import fs from 'fs-extra';
2
2
  import path from 'path';
3
3
  import { debug, error } from '../utils/log.js';
4
4
  import { dbChoiceRecord } from './select-db.js';
5
- const updateEnvExampleVariables = (contents, databaseType)=>{
6
- return contents.split('\n').map((line)=>{
5
+ const updateEnvExampleVariables = (contents, databaseType, payloadSecret, databaseUri)=>{
6
+ const seenKeys = new Set();
7
+ const updatedEnv = contents.split('\n').map((line)=>{
7
8
  if (line.startsWith('#') || !line.includes('=')) {
8
- return line // Preserve comments and unrelated lines
9
- ;
9
+ return line;
10
10
  }
11
11
  const [key] = line.split('=');
12
+ if (!key) {
13
+ return;
14
+ }
12
15
  if (key === 'DATABASE_URI' || key === 'POSTGRES_URL' || key === 'MONGODB_URI') {
13
16
  const dbChoice = databaseType ? dbChoiceRecord[databaseType] : null;
14
17
  if (dbChoice) {
15
- const placeholderUri = `${dbChoice.dbConnectionPrefix}your-database-name${dbChoice.dbConnectionSuffix || ''}`;
16
- return databaseType === 'vercel-postgres' ? `POSTGRES_URL=${placeholderUri}` : `DATABASE_URI=${placeholderUri}`;
18
+ const placeholderUri = databaseUri ? databaseUri : `${dbChoice.dbConnectionPrefix}your-database-name${dbChoice.dbConnectionSuffix || ''}`;
19
+ line = databaseType === 'vercel-postgres' ? `POSTGRES_URL=${placeholderUri}` : `DATABASE_URI=${placeholderUri}`;
17
20
  }
18
- return `DATABASE_URI=your-database-connection-here` // Fallback
19
- ;
20
21
  }
21
22
  if (key === 'PAYLOAD_SECRET' || key === 'PAYLOAD_SECRET_KEY') {
22
- return `PAYLOAD_SECRET=YOUR_SECRET_HERE`;
23
+ line = `PAYLOAD_SECRET=${payloadSecret || 'YOUR_SECRET_HERE'}`;
24
+ }
25
+ // handles dupes
26
+ if (seenKeys.has(key)) {
27
+ return null;
23
28
  }
29
+ seenKeys.add(key);
24
30
  return line;
25
- }).join('\n');
26
- };
27
- const generateEnvContent = (existingEnv, databaseType, databaseUri, payloadSecret)=>{
28
- const dbKey = databaseType === 'vercel-postgres' ? 'POSTGRES_URL' : 'DATABASE_URI';
29
- const envVars = {};
30
- existingEnv.split('\n').filter((line)=>line.includes('=') && !line.startsWith('#')).forEach((line)=>{
31
- const [key, value] = line.split('=');
32
- // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
33
- envVars[key] = value;
34
- });
35
- // Override specific keys
36
- envVars[dbKey] = databaseUri;
37
- envVars['PAYLOAD_SECRET'] = payloadSecret;
38
- // Rebuild content
39
- return Object.entries(envVars).map(([key, value])=>`${key}=${value}`).join('\n');
31
+ }).filter(Boolean).reverse().join('\n');
32
+ return updatedEnv;
40
33
  };
41
34
  /** Parse and swap .env.example values and write .env */ export async function manageEnvFiles(args) {
42
35
  const { cliArgs, databaseType, databaseUri, payloadSecret, projectDir, template } = args;
@@ -47,30 +40,44 @@ const generateEnvContent = (existingEnv, databaseType, databaseUri, payloadSecre
47
40
  }
48
41
  const envExamplePath = path.join(projectDir, '.env.example');
49
42
  const envPath = path.join(projectDir, '.env');
43
+ const emptyEnvContent = `# Added by Payload\nDATABASE_URI=your-connection-string-here\nPAYLOAD_SECRET=YOUR_SECRET_HERE\n`;
50
44
  try {
51
45
  let updatedExampleContents;
52
- // Update .env.example
53
- if (template?.type === 'starter') {
54
- if (!fs.existsSync(envExamplePath)) {
55
- error(`.env.example file not found at ${envExamplePath}`);
56
- process.exit(1);
46
+ if (template?.type === 'plugin') {
47
+ if (debugFlag) {
48
+ debug(`plugin template detected - no .env added .env.example added`);
49
+ }
50
+ return;
51
+ }
52
+ if (!fs.existsSync(envExamplePath)) {
53
+ updatedExampleContents = updateEnvExampleVariables(emptyEnvContent, databaseType, payloadSecret, databaseUri);
54
+ await fs.writeFile(envExamplePath, updatedExampleContents);
55
+ if (debugFlag) {
56
+ debug(`.env.example file successfully created`);
57
57
  }
58
+ } else {
58
59
  const envExampleContents = await fs.readFile(envExamplePath, 'utf8');
59
- updatedExampleContents = updateEnvExampleVariables(envExampleContents, databaseType);
60
- await fs.writeFile(envExamplePath, updatedExampleContents.trimEnd() + '\n');
60
+ const mergedEnvs = envExampleContents + '\n' + emptyEnvContent;
61
+ updatedExampleContents = updateEnvExampleVariables(mergedEnvs, databaseType, payloadSecret, databaseUri);
62
+ await fs.writeFile(envExamplePath, updatedExampleContents);
61
63
  if (debugFlag) {
62
64
  debug(`.env.example file successfully updated`);
63
65
  }
64
- } else {
65
- updatedExampleContents = `# Added by Payload\nDATABASE_URI=your-connection-string-here\nPAYLOAD_SECRET=YOUR_SECRET_HERE\n`;
66
- await fs.writeFile(envExamplePath, updatedExampleContents.trimEnd() + '\n');
67
66
  }
68
- // Merge existing variables and create or update .env
69
- const envExampleContents = await fs.readFile(envExamplePath, 'utf8');
70
- const envContent = generateEnvContent(envExampleContents, databaseType, databaseUri, payloadSecret);
71
- await fs.writeFile(envPath, `# Added by Payload\n${envContent.trimEnd()}\n`);
72
- if (debugFlag) {
73
- debug(`.env file successfully created or updated`);
67
+ if (!fs.existsSync(envPath)) {
68
+ const envContent = updateEnvExampleVariables(emptyEnvContent, databaseType, payloadSecret, databaseUri);
69
+ await fs.writeFile(envPath, envContent);
70
+ if (debugFlag) {
71
+ debug(`.env file successfully created`);
72
+ }
73
+ } else {
74
+ const envContents = await fs.readFile(envPath, 'utf8');
75
+ const mergedEnvs = envContents + '\n' + emptyEnvContent;
76
+ const updatedEnvContents = updateEnvExampleVariables(mergedEnvs, databaseType, payloadSecret, databaseUri);
77
+ await fs.writeFile(envPath, updatedEnvContents);
78
+ if (debugFlag) {
79
+ debug(`.env file successfully updated`);
80
+ }
74
81
  }
75
82
  } catch (err) {
76
83
  error('Unable to manage environment files');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/manage-env-files.ts"],"sourcesContent":["import fs from 'fs-extra'\nimport path from 'path'\n\nimport type { CliArgs, DbType, ProjectTemplate } from '../types.js'\n\nimport { debug, error } from '../utils/log.js'\nimport { dbChoiceRecord } from './select-db.js'\n\nconst updateEnvExampleVariables = (contents: string, databaseType: DbType | undefined): string => {\n return contents\n .split('\\n')\n .map((line) => {\n if (line.startsWith('#') || !line.includes('=')) {\n return line // Preserve comments and unrelated lines\n }\n\n const [key] = line.split('=')\n\n if (key === 'DATABASE_URI' || key === 'POSTGRES_URL' || key === 'MONGODB_URI') {\n const dbChoice = databaseType ? dbChoiceRecord[databaseType] : null\n\n if (dbChoice) {\n const placeholderUri = `${dbChoice.dbConnectionPrefix}your-database-name${\n dbChoice.dbConnectionSuffix || ''\n }`\n return databaseType === 'vercel-postgres'\n ? `POSTGRES_URL=${placeholderUri}`\n : `DATABASE_URI=${placeholderUri}`\n }\n\n return `DATABASE_URI=your-database-connection-here` // Fallback\n }\n\n if (key === 'PAYLOAD_SECRET' || key === 'PAYLOAD_SECRET_KEY') {\n return `PAYLOAD_SECRET=YOUR_SECRET_HERE`\n }\n\n return line\n })\n .join('\\n')\n}\n\nconst generateEnvContent = (\n existingEnv: string,\n databaseType: DbType | undefined,\n databaseUri: string,\n payloadSecret: string,\n): string => {\n const dbKey = databaseType === 'vercel-postgres' ? 'POSTGRES_URL' : 'DATABASE_URI'\n\n const envVars: Record<string, string> = {}\n existingEnv\n .split('\\n')\n .filter((line) => line.includes('=') && !line.startsWith('#'))\n .forEach((line) => {\n const [key, value] = line.split('=')\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n envVars[key] = value\n })\n\n // Override specific keys\n envVars[dbKey] = databaseUri\n envVars['PAYLOAD_SECRET'] = payloadSecret\n\n // Rebuild content\n return Object.entries(envVars)\n .map(([key, value]) => `${key}=${value}`)\n .join('\\n')\n}\n\n/** Parse and swap .env.example values and write .env */\nexport async function manageEnvFiles(args: {\n cliArgs: CliArgs\n databaseType?: DbType\n databaseUri: string\n payloadSecret: string\n projectDir: string\n template?: ProjectTemplate\n}): Promise<void> {\n const { cliArgs, databaseType, databaseUri, payloadSecret, projectDir, template } = args\n\n const debugFlag = cliArgs['--debug']\n\n if (cliArgs['--dry-run']) {\n debug(`DRY RUN: Environment files managed`)\n return\n }\n\n const envExamplePath = path.join(projectDir, '.env.example')\n const envPath = path.join(projectDir, '.env')\n\n try {\n let updatedExampleContents: string\n\n // Update .env.example\n if (template?.type === 'starter') {\n if (!fs.existsSync(envExamplePath)) {\n error(`.env.example file not found at ${envExamplePath}`)\n process.exit(1)\n }\n\n const envExampleContents = await fs.readFile(envExamplePath, 'utf8')\n updatedExampleContents = updateEnvExampleVariables(envExampleContents, databaseType)\n\n await fs.writeFile(envExamplePath, updatedExampleContents.trimEnd() + '\\n')\n\n if (debugFlag) {\n debug(`.env.example file successfully updated`)\n }\n } else {\n updatedExampleContents = `# Added by Payload\\nDATABASE_URI=your-connection-string-here\\nPAYLOAD_SECRET=YOUR_SECRET_HERE\\n`\n await fs.writeFile(envExamplePath, updatedExampleContents.trimEnd() + '\\n')\n }\n\n // Merge existing variables and create or update .env\n const envExampleContents = await fs.readFile(envExamplePath, 'utf8')\n const envContent = generateEnvContent(\n envExampleContents,\n databaseType,\n databaseUri,\n payloadSecret,\n )\n await fs.writeFile(envPath, `# Added by Payload\\n${envContent.trimEnd()}\\n`)\n\n if (debugFlag) {\n debug(`.env file successfully created or updated`)\n }\n } catch (err: unknown) {\n error('Unable to manage environment files')\n if (err instanceof Error) {\n error(err.message)\n }\n process.exit(1)\n }\n}\n"],"names":["fs","path","debug","error","dbChoiceRecord","updateEnvExampleVariables","contents","databaseType","split","map","line","startsWith","includes","key","dbChoice","placeholderUri","dbConnectionPrefix","dbConnectionSuffix","join","generateEnvContent","existingEnv","databaseUri","payloadSecret","dbKey","envVars","filter","forEach","value","Object","entries","manageEnvFiles","args","cliArgs","projectDir","template","debugFlag","envExamplePath","envPath","updatedExampleContents","type","existsSync","process","exit","envExampleContents","readFile","writeFile","trimEnd","envContent","err","Error","message"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/lib/manage-env-files.ts"],"sourcesContent":["import fs from 'fs-extra'\nimport path from 'path'\n\nimport type { CliArgs, DbType, ProjectTemplate } from '../types.js'\n\nimport { debug, error } from '../utils/log.js'\nimport { dbChoiceRecord } from './select-db.js'\n\nconst updateEnvExampleVariables = (\n contents: string,\n databaseType: DbType | undefined,\n payloadSecret?: string,\n databaseUri?: string,\n): string => {\n const seenKeys = new Set<string>()\n const updatedEnv = contents\n .split('\\n')\n .map((line) => {\n if (line.startsWith('#') || !line.includes('=')) {\n return line\n }\n\n const [key] = line.split('=')\n\n if (!key) {return}\n\n if (key === 'DATABASE_URI' || key === 'POSTGRES_URL' || key === 'MONGODB_URI') {\n const dbChoice = databaseType ? dbChoiceRecord[databaseType] : null\n if (dbChoice) {\n const placeholderUri = databaseUri\n ? databaseUri\n : `${dbChoice.dbConnectionPrefix}your-database-name${dbChoice.dbConnectionSuffix || ''}`\n line =\n databaseType === 'vercel-postgres'\n ? `POSTGRES_URL=${placeholderUri}`\n : `DATABASE_URI=${placeholderUri}`\n }\n }\n\n if (key === 'PAYLOAD_SECRET' || key === 'PAYLOAD_SECRET_KEY') {\n line = `PAYLOAD_SECRET=${payloadSecret || 'YOUR_SECRET_HERE'}`\n }\n\n // handles dupes\n if (seenKeys.has(key)) {\n return null\n }\n\n seenKeys.add(key)\n\n return line\n })\n .filter(Boolean)\n .reverse()\n .join('\\n')\n\n return updatedEnv\n}\n\n/** Parse and swap .env.example values and write .env */\nexport async function manageEnvFiles(args: {\n cliArgs: CliArgs\n databaseType?: DbType\n databaseUri: string\n payloadSecret: string\n projectDir: string\n template?: ProjectTemplate\n}): Promise<void> {\n const { cliArgs, databaseType, databaseUri, payloadSecret, projectDir, template } = args\n\n const debugFlag = cliArgs['--debug']\n\n if (cliArgs['--dry-run']) {\n debug(`DRY RUN: Environment files managed`)\n return\n }\n\n const envExamplePath = path.join(projectDir, '.env.example')\n const envPath = path.join(projectDir, '.env')\n const emptyEnvContent = `# Added by Payload\\nDATABASE_URI=your-connection-string-here\\nPAYLOAD_SECRET=YOUR_SECRET_HERE\\n`\n try {\n let updatedExampleContents: string\n\n if (template?.type === 'plugin') {\n if (debugFlag) {\n debug(`plugin template detected - no .env added .env.example added`)\n }\n return\n }\n\n if (!fs.existsSync(envExamplePath)) {\n updatedExampleContents = updateEnvExampleVariables(\n emptyEnvContent,\n databaseType,\n payloadSecret,\n databaseUri,\n )\n\n await fs.writeFile(envExamplePath, updatedExampleContents)\n if (debugFlag) {\n debug(`.env.example file successfully created`)\n }\n } else {\n const envExampleContents = await fs.readFile(envExamplePath, 'utf8')\n const mergedEnvs = envExampleContents + '\\n' + emptyEnvContent\n updatedExampleContents = updateEnvExampleVariables(\n mergedEnvs,\n databaseType,\n payloadSecret,\n databaseUri,\n )\n\n await fs.writeFile(envExamplePath, updatedExampleContents)\n if (debugFlag) {\n debug(`.env.example file successfully updated`)\n }\n }\n\n if (!fs.existsSync(envPath)) {\n const envContent = updateEnvExampleVariables(\n emptyEnvContent,\n databaseType,\n payloadSecret,\n databaseUri,\n )\n await fs.writeFile(envPath, envContent)\n\n if (debugFlag) {\n debug(`.env file successfully created`)\n }\n } else {\n const envContents = await fs.readFile(envPath, 'utf8')\n const mergedEnvs = envContents + '\\n' + emptyEnvContent\n const updatedEnvContents = updateEnvExampleVariables(\n mergedEnvs,\n databaseType,\n payloadSecret,\n databaseUri,\n )\n\n await fs.writeFile(envPath, updatedEnvContents)\n if (debugFlag) {\n debug(`.env file successfully updated`)\n }\n }\n } catch (err: unknown) {\n error('Unable to manage environment files')\n if (err instanceof Error) {\n error(err.message)\n }\n process.exit(1)\n }\n}\n"],"names":["fs","path","debug","error","dbChoiceRecord","updateEnvExampleVariables","contents","databaseType","payloadSecret","databaseUri","seenKeys","Set","updatedEnv","split","map","line","startsWith","includes","key","dbChoice","placeholderUri","dbConnectionPrefix","dbConnectionSuffix","has","add","filter","Boolean","reverse","join","manageEnvFiles","args","cliArgs","projectDir","template","debugFlag","envExamplePath","envPath","emptyEnvContent","updatedExampleContents","type","existsSync","writeFile","envExampleContents","readFile","mergedEnvs","envContent","envContents","updatedEnvContents","err","Error","message","process","exit"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-payload-app",
3
- "version": "3.37.0-canary.1",
3
+ "version": "3.37.0-canary.2",
4
4
  "homepage": "https://payloadcms.com",
5
5
  "repository": {
6
6
  "type": "git",