Compare commits
16 Commits
db-postgre
...
v0.5.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2497f2a65a | ||
|
|
90948146c6 | ||
|
|
e6a5132812 | ||
|
|
53310281d0 | ||
|
|
3ac9dae1d2 | ||
|
|
9c165a73cb | ||
|
|
9b58915aff | ||
|
|
c1daeb3432 | ||
|
|
ff8acde322 | ||
|
|
1bade389e4 | ||
|
|
489de652a3 | ||
|
|
166b06e5d8 | ||
|
|
ed143c7a67 | ||
|
|
b29e2ae685 | ||
|
|
9bafc0fcbf | ||
|
|
b3db078a5f |
13
.vscode/launch.json
vendored
Normal file
13
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
"configurations": [
|
||||
{
|
||||
"command": "ts-node -T ./src/index.ts -n asdf -t blank --db mongodb --no-deps",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Debug",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
]
|
||||
}
|
||||
23
README.md
23
README.md
@@ -9,15 +9,26 @@ CLI for easily starting new Payload project
|
||||
USAGE
|
||||
|
||||
$ npx create-payload-app
|
||||
$ npx create-payload-app my-project
|
||||
$ npx create-payload-app -n my-project -t blog
|
||||
|
||||
OPTIONS
|
||||
|
||||
--name my-payload-app Set project name
|
||||
--template template_name Choose specific template
|
||||
-n my-payload-app Set project name
|
||||
-t template_name Choose specific template
|
||||
|
||||
Available templates: blank, blog, todo
|
||||
Available templates:
|
||||
|
||||
--use-npm Use npm to install dependencies
|
||||
--no-deps Do not install any dependencies
|
||||
--help Show help
|
||||
blank Blank Template
|
||||
website Website Template
|
||||
ecommerce E-commerce Template
|
||||
plugin Template for creating a Payload plugin
|
||||
payload-demo Payload demo site at https://demo.payloadcms.com
|
||||
payload-website Payload website CMS at https://payloadcms.com
|
||||
|
||||
--use-npm Use npm to install dependencies
|
||||
--use-yarn Use yarn to install dependencies
|
||||
--use-pnpm Use pnpm to install dependencies
|
||||
--no-deps Do not install any dependencies
|
||||
-h Show help
|
||||
```
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"prompts": "^2.4.2",
|
||||
"terminal-link": "^2.1.1"
|
||||
},
|
||||
"version": "0.4.2",
|
||||
"version": "0.5.0-beta.3",
|
||||
"devDependencies": {
|
||||
"@types/command-exists": "^1.2.0",
|
||||
"@types/degit": "^2.8.3",
|
||||
|
||||
107
src/lib/configure-payload-config.ts
Normal file
107
src/lib/configure-payload-config.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import fse from 'fs-extra'
|
||||
import path from 'path'
|
||||
|
||||
import type { DbDetails } from '../types'
|
||||
import { warning } from '../utils/log'
|
||||
import { bundlerPackages, dbPackages, editorPackages } from './packages'
|
||||
|
||||
/** Update payload config with necessary imports and adapters */
|
||||
export async function configurePayloadConfig(args: {
|
||||
projectDir: string
|
||||
dbDetails: DbDetails | undefined
|
||||
}): Promise<void> {
|
||||
if (!args.dbDetails) {
|
||||
return
|
||||
}
|
||||
|
||||
// Update package.json
|
||||
const packageJsonPath = path.resolve(args.projectDir, 'package.json')
|
||||
try {
|
||||
const packageObj = await fse.readJson(packageJsonPath)
|
||||
|
||||
const dbPackage = dbPackages[args.dbDetails.type]
|
||||
const bundlerPackage = bundlerPackages['webpack']
|
||||
const editorPackage = editorPackages['lexical']
|
||||
|
||||
packageObj.dependencies[dbPackage.packageName] = 'latest'
|
||||
packageObj.dependencies[bundlerPackage.packageName] = 'latest'
|
||||
packageObj.dependencies[editorPackage.packageName] = 'latest'
|
||||
|
||||
await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })
|
||||
} catch (err: unknown) {
|
||||
warning('Unable to update name in package.json')
|
||||
}
|
||||
|
||||
try {
|
||||
const possiblePaths = [
|
||||
path.resolve(args.projectDir, 'src/payload.config.ts'),
|
||||
path.resolve(args.projectDir, 'src/payload/payload.config.ts'),
|
||||
]
|
||||
|
||||
let payloadConfigPath: string | undefined
|
||||
|
||||
possiblePaths.forEach(p => {
|
||||
if (fse.pathExistsSync(p) && !payloadConfigPath) {
|
||||
payloadConfigPath = p
|
||||
}
|
||||
})
|
||||
|
||||
if (!payloadConfigPath) {
|
||||
warning('Unable to update payload.config.ts with plugins')
|
||||
return
|
||||
}
|
||||
|
||||
const configContent = fse.readFileSync(payloadConfigPath, 'utf-8')
|
||||
const configLines = configContent.split('\n')
|
||||
|
||||
const dbReplacement = dbPackages[args.dbDetails.type]
|
||||
const bundlerReplacement = bundlerPackages['webpack']
|
||||
const editorReplacement = editorPackages['lexical']
|
||||
|
||||
let dbConfigStartLineIndex: number | undefined
|
||||
let dbConfigEndLineIndex: number | undefined
|
||||
|
||||
configLines.forEach((l, i) => {
|
||||
if (l.includes('// database-adapter-import')) {
|
||||
configLines[i] = dbReplacement.importReplacement
|
||||
}
|
||||
if (l.includes('// bundler-import')) {
|
||||
configLines[i] = bundlerReplacement.importReplacement
|
||||
}
|
||||
|
||||
if (l.includes('// bundler-config')) {
|
||||
configLines[i] = bundlerReplacement.configReplacement
|
||||
}
|
||||
|
||||
if (l.includes('// editor-import')) {
|
||||
configLines[i] = editorReplacement.importReplacement
|
||||
}
|
||||
|
||||
if (l.includes('// editor-config')) {
|
||||
configLines[i] = editorReplacement.configReplacement
|
||||
}
|
||||
|
||||
if (l.includes('// database-adapter-config-start')) {
|
||||
dbConfigStartLineIndex = i
|
||||
}
|
||||
if (l.includes('// database-adapter-config-end')) {
|
||||
dbConfigEndLineIndex = i
|
||||
}
|
||||
})
|
||||
|
||||
if (!dbConfigStartLineIndex || !dbConfigEndLineIndex) {
|
||||
warning('Unable to update payload.config.ts with database adapter import')
|
||||
} else {
|
||||
// Replaces lines between `// database-adapter-config-start` and `// database-adapter-config-end`
|
||||
configLines.splice(
|
||||
dbConfigStartLineIndex,
|
||||
dbConfigEndLineIndex - dbConfigStartLineIndex + 1,
|
||||
...dbReplacement.configReplacement,
|
||||
)
|
||||
}
|
||||
|
||||
fse.writeFileSync(payloadConfigPath, configLines.join('\n'))
|
||||
} catch (err: unknown) {
|
||||
warning('Unable to update payload.config.ts with plugins')
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import fse from 'fs-extra'
|
||||
import path from 'path'
|
||||
import type { CliArgs, ProjectTemplate } from '../types'
|
||||
import type { BundlerType, CliArgs, DbType, ProjectTemplate } from '../types'
|
||||
import { createProject } from './create-project'
|
||||
import { bundlerPackages, dbPackages } from './packages'
|
||||
|
||||
const projectDir = path.resolve(__dirname, './tmp')
|
||||
describe('createProject', () => {
|
||||
@@ -22,7 +23,11 @@ describe('createProject', () => {
|
||||
|
||||
describe('#createProject', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const args = { _: ['project-name'], '--no-deps': true } as CliArgs
|
||||
const args = {
|
||||
_: ['project-name'],
|
||||
'--db': 'mongodb',
|
||||
'--no-deps': true,
|
||||
} as CliArgs
|
||||
const packageManager = 'yarn'
|
||||
|
||||
it('creates starter project', async () => {
|
||||
@@ -70,5 +75,60 @@ describe('createProject', () => {
|
||||
// Check package name and description
|
||||
expect(packageJson.name).toEqual(projectName)
|
||||
})
|
||||
|
||||
describe('db adapters and bundlers', () => {
|
||||
it.each([
|
||||
['mongodb', 'webpack'],
|
||||
['postgres', 'webpack'],
|
||||
])('update config and deps: %s, %s', async (db, bundler) => {
|
||||
const projectName = 'starter-project'
|
||||
const template: ProjectTemplate = {
|
||||
name: 'blank',
|
||||
type: 'starter',
|
||||
url: 'https://github.com/payloadcms/payload/templates/blank#2.0',
|
||||
description: 'Blank Template',
|
||||
}
|
||||
await createProject({
|
||||
cliArgs: args,
|
||||
projectName,
|
||||
projectDir,
|
||||
template,
|
||||
packageManager,
|
||||
dbDetails: {
|
||||
dbUri: `${db}://localhost:27017/create-project-test`,
|
||||
type: db as DbType,
|
||||
},
|
||||
})
|
||||
|
||||
const dbReplacement = dbPackages[db as DbType]
|
||||
const bundlerReplacement = bundlerPackages[bundler as BundlerType]
|
||||
|
||||
const packageJsonPath = path.resolve(projectDir, 'package.json')
|
||||
const packageJson = fse.readJsonSync(packageJsonPath)
|
||||
|
||||
// Check deps
|
||||
expect(packageJson.dependencies[dbReplacement.packageName]).toBeDefined()
|
||||
expect(
|
||||
packageJson.dependencies[bundlerReplacement.packageName],
|
||||
).toBeDefined()
|
||||
|
||||
const payloadConfigPath = path.resolve(projectDir, 'src/payload.config.ts')
|
||||
const content = fse.readFileSync(payloadConfigPath, 'utf-8')
|
||||
|
||||
// Check payload.config.ts
|
||||
expect(content).not.toContain('// database-adapter-import')
|
||||
expect(content).toContain(dbReplacement.importReplacement)
|
||||
|
||||
expect(content).not.toContain('// database-adapter-config-start')
|
||||
expect(content).not.toContain('// database-adapter-config-end')
|
||||
expect(content).toContain(dbReplacement.configReplacement.join('\n'))
|
||||
|
||||
expect(content).not.toContain('// bundler-config-import')
|
||||
expect(content).toContain(bundlerReplacement.importReplacement)
|
||||
|
||||
expect(content).not.toContain('// bundler-config')
|
||||
expect(content).toContain(bundlerReplacement.configReplacement)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -6,7 +6,8 @@ import ora from 'ora'
|
||||
import degit from 'degit'
|
||||
|
||||
import { success, error, warning } from '../utils/log'
|
||||
import type { CliArgs, ProjectTemplate } from '../types'
|
||||
import type { CliArgs, DbDetails, PackageManager, ProjectTemplate } from '../types'
|
||||
import { configurePayloadConfig } from './configure-payload-config'
|
||||
|
||||
async function createOrFindProjectDir(projectDir: string): Promise<void> {
|
||||
const pathExists = await fse.pathExists(projectDir)
|
||||
@@ -18,16 +19,22 @@ async function createOrFindProjectDir(projectDir: string): Promise<void> {
|
||||
async function installDeps(args: {
|
||||
cliArgs: CliArgs
|
||||
projectDir: string
|
||||
packageManager: string
|
||||
packageManager: PackageManager
|
||||
}): Promise<boolean> {
|
||||
const { cliArgs, projectDir, packageManager } = args
|
||||
if (cliArgs['--no-deps']) {
|
||||
return true
|
||||
}
|
||||
const cmd = packageManager === 'yarn' ? 'yarn' : 'npm install --legacy-peer-deps'
|
||||
let installCmd = 'npm install --legacy-peer-deps'
|
||||
|
||||
if (packageManager === 'yarn') {
|
||||
installCmd = 'yarn'
|
||||
} else if (packageManager === 'pnpm') {
|
||||
installCmd = 'pnpm install'
|
||||
}
|
||||
|
||||
try {
|
||||
await execa.command(cmd, {
|
||||
await execa.command(installCmd, {
|
||||
cwd: path.resolve(projectDir),
|
||||
})
|
||||
return true
|
||||
@@ -37,29 +44,16 @@ async function installDeps(args: {
|
||||
}
|
||||
}
|
||||
|
||||
export async function updatePackageJSONName(args: {
|
||||
projectName: string
|
||||
projectDir: string
|
||||
}): Promise<void> {
|
||||
const { projectName, projectDir } = args
|
||||
const packageJsonPath = path.resolve(projectDir, 'package.json')
|
||||
try {
|
||||
const packageObj = await fse.readJson(packageJsonPath)
|
||||
packageObj.name = projectName
|
||||
await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })
|
||||
} catch (err: unknown) {
|
||||
warning('Unable to update name in package.json')
|
||||
}
|
||||
}
|
||||
|
||||
export async function createProject(args: {
|
||||
cliArgs: CliArgs
|
||||
projectName: string
|
||||
projectDir: string
|
||||
template: ProjectTemplate
|
||||
packageManager: string
|
||||
packageManager: PackageManager
|
||||
dbDetails?: DbDetails
|
||||
}): Promise<void> {
|
||||
const { cliArgs, projectName, projectDir, template, packageManager } = args
|
||||
const { cliArgs, projectName, projectDir, template, packageManager, dbDetails } =
|
||||
args
|
||||
|
||||
await createOrFindProjectDir(projectDir)
|
||||
|
||||
@@ -72,7 +66,8 @@ export async function createProject(args: {
|
||||
|
||||
const spinner = ora('Checking latest Payload version...').start()
|
||||
|
||||
await updatePackageJSONName({ projectName, projectDir })
|
||||
await updatePackageJSON({ projectName, projectDir })
|
||||
await configurePayloadConfig({ projectDir, dbDetails })
|
||||
|
||||
// Remove yarn.lock file. This is only desired in Payload Cloud.
|
||||
const lockPath = path.resolve(projectDir, 'yarn.lock')
|
||||
@@ -90,3 +85,18 @@ export async function createProject(args: {
|
||||
error('Error installing dependencies')
|
||||
}
|
||||
}
|
||||
|
||||
export async function updatePackageJSON(args: {
|
||||
projectName: string
|
||||
projectDir: string
|
||||
}): Promise<void> {
|
||||
const { projectName, projectDir } = args
|
||||
const packageJsonPath = path.resolve(projectDir, 'package.json')
|
||||
try {
|
||||
const packageObj = await fse.readJson(packageJsonPath)
|
||||
packageObj.name = projectName
|
||||
await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })
|
||||
} catch (err: unknown) {
|
||||
warning('Unable to update name in package.json')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import prompts from 'prompts'
|
||||
import slugify from '@sindresorhus/slugify'
|
||||
import type { CliArgs } from '../types'
|
||||
|
||||
export async function getDatabaseConnection(
|
||||
args: CliArgs,
|
||||
projectName: string,
|
||||
): Promise<string> {
|
||||
if (args['--db']) return args['--db']
|
||||
|
||||
const response = await prompts(
|
||||
{
|
||||
type: 'text',
|
||||
name: 'value',
|
||||
message: 'Enter MongoDB connection',
|
||||
initial: `mongodb://127.0.0.1/${
|
||||
projectName === '.'
|
||||
? `payload-${getRandomDigitSuffix()}`
|
||||
: slugify(projectName)
|
||||
}`,
|
||||
validate: (value: string) => !!value.length,
|
||||
},
|
||||
{
|
||||
onCancel: () => {
|
||||
process.exit(0)
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return response.value
|
||||
}
|
||||
|
||||
function getRandomDigitSuffix(): string {
|
||||
return (Math.random() * Math.pow(10, 6)).toFixed(0)
|
||||
}
|
||||
79
src/lib/packages.ts
Normal file
79
src/lib/packages.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import type { BundlerType, DbType, EditorType } from '../types'
|
||||
|
||||
type DbAdapterReplacement = {
|
||||
packageName: string
|
||||
importReplacement: string
|
||||
configReplacement: string[]
|
||||
}
|
||||
|
||||
type BundlerReplacement = {
|
||||
packageName: string
|
||||
importReplacement: string
|
||||
configReplacement: string
|
||||
}
|
||||
|
||||
type EditorReplacement = {
|
||||
packageName: string
|
||||
importReplacement: string
|
||||
configReplacement: string
|
||||
}
|
||||
|
||||
const mongodbReplacement: DbAdapterReplacement = {
|
||||
packageName: '@payloadcms/db-mongodb',
|
||||
importReplacement: "import { mongooseAdapter } from '@payloadcms/db-mongodb'",
|
||||
// Replacement between `// database-adapter-config-start` and `// database-adapter-config-end`
|
||||
configReplacement: [
|
||||
' db: mongooseAdapter({',
|
||||
' url: process.env.DATABASE_URI,',
|
||||
' }),',
|
||||
],
|
||||
}
|
||||
|
||||
const postgresReplacement: DbAdapterReplacement = {
|
||||
packageName: '@payloadcms/db-postgres',
|
||||
importReplacement: "import { postgresAdapter } from '@payloadcms/db-postgres'",
|
||||
configReplacement: [
|
||||
' db: postgresAdapter({',
|
||||
' client: {',
|
||||
' connectionString: process.env.DATABASE_URI,',
|
||||
' },',
|
||||
' }),',
|
||||
],
|
||||
}
|
||||
|
||||
export const dbPackages: Record<DbType, DbAdapterReplacement> = {
|
||||
mongodb: mongodbReplacement,
|
||||
postgres: postgresReplacement,
|
||||
}
|
||||
|
||||
const webpackReplacement: BundlerReplacement = {
|
||||
packageName: '@payloadcms/bundler-webpack',
|
||||
importReplacement: "import { webpackBundler } from '@payloadcms/bundler-webpack'",
|
||||
// Replacement of line containing `// bundler-config`
|
||||
configReplacement: ' bundler: webpackBundler(),',
|
||||
}
|
||||
|
||||
const viteReplacement: BundlerReplacement = {
|
||||
packageName: '@payloadcms/bundler-vite',
|
||||
importReplacement: "import { viteBundler } from '@payloadcms/bundler-vite'",
|
||||
configReplacement: ' bundler: viteBundler(),',
|
||||
}
|
||||
|
||||
export const bundlerPackages: Record<BundlerType, BundlerReplacement> = {
|
||||
webpack: webpackReplacement,
|
||||
vite: viteReplacement,
|
||||
}
|
||||
|
||||
export const editorPackages: Record<EditorType, EditorReplacement> = {
|
||||
slate: {
|
||||
packageName: '@payloadcms/richtext-slate',
|
||||
importReplacement: "import { slateEditor } from '@payloadcms/richtext-slate'",
|
||||
configReplacement: ' editor: slateEditor({}),',
|
||||
},
|
||||
lexical: {
|
||||
packageName: '@payloadcms/richtext-lexical',
|
||||
importReplacement:
|
||||
"import { lexicalEditor } from '@payloadcms/richtext-lexical'",
|
||||
configReplacement: ' editor: lexicalEditor({}),',
|
||||
},
|
||||
}
|
||||
96
src/lib/select-db.ts
Normal file
96
src/lib/select-db.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import prompts from 'prompts'
|
||||
import slugify from '@sindresorhus/slugify'
|
||||
import type { CliArgs, DbDetails, DbType } from '../types'
|
||||
|
||||
type DbChoice = {
|
||||
value: DbType
|
||||
title: string
|
||||
dbConnectionPrefix: `${string}/`
|
||||
}
|
||||
|
||||
const dbChoiceRecord: Record<DbType, DbChoice> = {
|
||||
mongodb: {
|
||||
value: 'mongodb',
|
||||
title: 'MongoDB',
|
||||
dbConnectionPrefix: 'mongodb://127.0.0.1/',
|
||||
},
|
||||
postgres: {
|
||||
value: 'postgres',
|
||||
title: 'PostgreSQL',
|
||||
dbConnectionPrefix: 'postgres://127.0.0.1:5432/',
|
||||
},
|
||||
}
|
||||
|
||||
export async function selectDb(
|
||||
args: CliArgs,
|
||||
projectName: string,
|
||||
): Promise<DbDetails> {
|
||||
let dbType: DbType | undefined = undefined
|
||||
if (args['--db']) {
|
||||
if (
|
||||
!Object.values(dbChoiceRecord).some(
|
||||
dbChoice => dbChoice.value === args['--db'],
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
`Invalid database type given. Valid types are: ${Object.values(
|
||||
dbChoiceRecord,
|
||||
)
|
||||
.map(dbChoice => dbChoice.value)
|
||||
.join(', ')}`,
|
||||
)
|
||||
}
|
||||
dbType = args['--db'] as DbType
|
||||
} else {
|
||||
const dbTypeRes = await prompts(
|
||||
{
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
message: 'Select a database',
|
||||
choices: Object.values(dbChoiceRecord).map(dbChoice => {
|
||||
return {
|
||||
title: dbChoice.title,
|
||||
value: dbChoice.value,
|
||||
}
|
||||
}),
|
||||
validate: (value: string) => !!value.length,
|
||||
},
|
||||
{
|
||||
onCancel: () => {
|
||||
process.exit(0)
|
||||
},
|
||||
},
|
||||
)
|
||||
dbType = dbTypeRes.value
|
||||
}
|
||||
|
||||
const dbChoice = dbChoiceRecord[dbType as DbType]
|
||||
|
||||
const dbUriRes = await prompts(
|
||||
{
|
||||
type: 'text',
|
||||
name: 'value',
|
||||
message: `Enter ${dbChoice.title} connection string`,
|
||||
initial: `${dbChoice.dbConnectionPrefix}${
|
||||
projectName === '.'
|
||||
? `payload-${getRandomDigitSuffix()}`
|
||||
: slugify(projectName)
|
||||
}`,
|
||||
validate: (value: string) => !!value.length,
|
||||
},
|
||||
{
|
||||
onCancel: () => {
|
||||
process.exit(0)
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
return {
|
||||
type: dbChoice.value,
|
||||
dbUri: dbUriRes.value,
|
||||
}
|
||||
}
|
||||
|
||||
function getRandomDigitSuffix(): string {
|
||||
return (Math.random() * Math.pow(10, 6)).toFixed(0)
|
||||
}
|
||||
@@ -16,19 +16,19 @@ export async function getValidTemplates(): Promise<ProjectTemplate[]> {
|
||||
{
|
||||
name: 'blank',
|
||||
type: 'starter',
|
||||
url: 'https://github.com/payloadcms/payload/templates/blank',
|
||||
url: 'https://github.com/payloadcms/payload/templates/blank#2.0',
|
||||
description: 'Blank Template',
|
||||
},
|
||||
{
|
||||
name: 'website',
|
||||
type: 'starter',
|
||||
url: 'https://github.com/payloadcms/payload/templates/website',
|
||||
url: 'https://github.com/payloadcms/payload/templates/website#2.0',
|
||||
description: 'Website Template',
|
||||
},
|
||||
{
|
||||
name: 'ecommerce',
|
||||
type: 'starter',
|
||||
url: 'https://github.com/payloadcms/payload/templates/ecommerce',
|
||||
url: 'https://github.com/payloadcms/payload/templates/ecommerce#2.0',
|
||||
description: 'E-commerce Template',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -31,7 +31,11 @@ export async function writeEnvFile(args: {
|
||||
const key = split[0]
|
||||
let value = split[1]
|
||||
|
||||
if (key === 'MONGODB_URI' || key === 'MONGO_URL') {
|
||||
if (
|
||||
key === 'MONGODB_URI' ||
|
||||
key === 'MONGO_URL' ||
|
||||
key === 'DATABASE_URI'
|
||||
) {
|
||||
value = databaseUri
|
||||
}
|
||||
if (key === 'PAYLOAD_SECRET' || key === 'PAYLOAD_SECRET_KEY') {
|
||||
|
||||
27
src/main.ts
27
src/main.ts
@@ -2,13 +2,13 @@ import slugify from '@sindresorhus/slugify'
|
||||
import arg from 'arg'
|
||||
import commandExists from 'command-exists'
|
||||
import { createProject } from './lib/create-project'
|
||||
import { getDatabaseConnection } from './lib/get-db-connection'
|
||||
import { selectDb } from './lib/select-db'
|
||||
import { generateSecret } from './lib/generate-secret'
|
||||
import { parseProjectName } from './lib/parse-project-name'
|
||||
import { parseTemplate } from './lib/parse-template'
|
||||
import { getValidTemplates, validateTemplate } from './lib/templates'
|
||||
import { writeEnvFile } from './lib/write-env-file'
|
||||
import type { CliArgs } from './types'
|
||||
import type { CliArgs, PackageManager } from './types'
|
||||
import { success } from './utils/log'
|
||||
import { helpMessage, successMessage, welcomeMessage } from './utils/messages'
|
||||
|
||||
@@ -25,6 +25,8 @@ export class Main {
|
||||
'--db': String,
|
||||
'--secret': String,
|
||||
'--use-npm': Boolean,
|
||||
'--use-yarn': Boolean,
|
||||
'--use-pnpm': Boolean,
|
||||
'--no-deps': Boolean,
|
||||
'--dry-run': Boolean,
|
||||
'--beta': Boolean,
|
||||
@@ -62,7 +64,7 @@ export class Main {
|
||||
const packageManager = await getPackageManager(this.args)
|
||||
|
||||
if (template.type !== 'plugin') {
|
||||
const databaseUri = await getDatabaseConnection(this.args, projectName)
|
||||
const dbDetails = await selectDb(this.args, projectName)
|
||||
const payloadSecret = await generateSecret()
|
||||
if (!this.args['--dry-run']) {
|
||||
await createProject({
|
||||
@@ -71,9 +73,10 @@ export class Main {
|
||||
projectDir,
|
||||
template,
|
||||
packageManager,
|
||||
dbDetails,
|
||||
})
|
||||
await writeEnvFile({
|
||||
databaseUri,
|
||||
databaseUri: dbDetails.dbUri,
|
||||
payloadSecret,
|
||||
template,
|
||||
projectDir,
|
||||
@@ -99,14 +102,22 @@ export class Main {
|
||||
}
|
||||
}
|
||||
|
||||
async function getPackageManager(args: CliArgs): Promise<string> {
|
||||
let packageManager: string
|
||||
async function getPackageManager(args: CliArgs): Promise<PackageManager> {
|
||||
let packageManager: PackageManager = 'npm'
|
||||
|
||||
if (args['--use-npm']) {
|
||||
packageManager = 'npm'
|
||||
} else if (args['--use-yarn']) {
|
||||
packageManager = 'yarn'
|
||||
} else if (args['--use-pnpm']) {
|
||||
packageManager = 'pnpm'
|
||||
} else {
|
||||
try {
|
||||
await commandExists('yarn')
|
||||
packageManager = 'yarn'
|
||||
if (await commandExists('yarn')) {
|
||||
packageManager = 'yarn'
|
||||
} else if (await commandExists('pnpm')) {
|
||||
packageManager = 'pnpm'
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
packageManager = 'npm'
|
||||
}
|
||||
|
||||
14
src/types.ts
14
src/types.ts
@@ -7,6 +7,8 @@ export interface Args extends arg.Spec {
|
||||
'--db': StringConstructor
|
||||
'--secret': StringConstructor
|
||||
'--use-npm': BooleanConstructor
|
||||
'--use-yarn': BooleanConstructor
|
||||
'--use-pnpm': BooleanConstructor
|
||||
'--no-deps': BooleanConstructor
|
||||
'--dry-run': BooleanConstructor
|
||||
'--beta': BooleanConstructor
|
||||
@@ -42,3 +44,15 @@ interface Template {
|
||||
type: ProjectTemplate['type']
|
||||
description?: string
|
||||
}
|
||||
|
||||
export type PackageManager = 'npm' | 'yarn' | 'pnpm'
|
||||
|
||||
export type DbType = 'mongodb' | 'postgres'
|
||||
|
||||
export type DbDetails = {
|
||||
type: DbType
|
||||
dbUri: string
|
||||
}
|
||||
|
||||
export type BundlerType = 'webpack' | 'vite'
|
||||
export type EditorType = 'lexical' | 'slate'
|
||||
|
||||
@@ -31,6 +31,8 @@ export async function helpMessage(): Promise<string> {
|
||||
{dim Available templates: ${formatTemplates(validTemplates)}}
|
||||
|
||||
--use-npm Use npm to install dependencies
|
||||
--use-yarn Use yarn to install dependencies
|
||||
--use-pnpm Use pnpm to install dependencies
|
||||
--no-deps Do not install any dependencies
|
||||
-h Show help
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user