chore(create-payload-app): init-next now create payload config and modifies tsconfig.json (#5242)
This commit is contained in:
@@ -89,6 +89,7 @@
|
|||||||
"@types/testing-library__jest-dom": "5.14.8",
|
"@types/testing-library__jest-dom": "5.14.8",
|
||||||
"add-stream": "^1.0.0",
|
"add-stream": "^1.0.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
|
"comment-json": "^4.2.3",
|
||||||
"concat-stream": "^2.0.0",
|
"concat-stream": "^2.0.0",
|
||||||
"conventional-changelog": "^5.1.0",
|
"conventional-changelog": "^5.1.0",
|
||||||
"conventional-changelog-conventionalcommits": "^7.0.2",
|
"conventional-changelog-conventionalcommits": "^7.0.2",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "pnpm copyfiles && pnpm build:swc",
|
"build": "pnpm copyfiles && pnpm build:swc",
|
||||||
"copyfiles": "copyfiles -u 4 \"../next/src/app/(payload)/**\" \"dist/app\"",
|
"copyfiles": "copyfiles -u 2 \"../../app/(payload)/**\" \"dist\"",
|
||||||
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
|
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
|
||||||
"clean": "rimraf {dist,*.tsbuildinfo}",
|
"clean": "rimraf {dist,*.tsbuildinfo}",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
@@ -23,7 +23,9 @@
|
|||||||
"arg": "^5.0.0",
|
"arg": "^5.0.0",
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"command-exists": "^1.2.9",
|
"command-exists": "^1.2.9",
|
||||||
|
"comment-json": "^4.2.3",
|
||||||
"degit": "^2.8.4",
|
"degit": "^2.8.4",
|
||||||
|
"detect-package-manager": "^3.0.1",
|
||||||
"execa": "^5.0.0",
|
"execa": "^5.0.0",
|
||||||
"figures": "^3.2.0",
|
"figures": "^3.2.0",
|
||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
|
|||||||
@@ -1,16 +1,88 @@
|
|||||||
|
import type { CompilerOptions } from 'typescript'
|
||||||
|
|
||||||
|
import chalk from 'chalk'
|
||||||
|
import * as CommentJson from 'comment-json'
|
||||||
|
import { detect } from 'detect-package-manager'
|
||||||
|
import execa from 'execa'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
import fse from 'fs-extra'
|
||||||
import globby from 'globby'
|
import globby from 'globby'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
import type { CliArgs } from '../types'
|
import type { CliArgs } from '../types'
|
||||||
|
|
||||||
import { copyRecursiveSync } from '../utils/copy-recursive-sync'
|
import { copyRecursiveSync } from '../utils/copy-recursive-sync'
|
||||||
import { error, info, debug as origDebug, success } from '../utils/log'
|
import { error, info, debug as origDebug, success, warning } from '../utils/log'
|
||||||
|
|
||||||
export async function initNext(
|
type InitNextArgs = Pick<CliArgs, '--debug'> & {
|
||||||
args: Pick<CliArgs, '--debug'> & { nextDir?: string; useDistFiles?: boolean },
|
projectDir?: string
|
||||||
): Promise<{ success: boolean }> {
|
useDistFiles?: boolean
|
||||||
const { '--debug': debug, nextDir, useDistFiles } = args
|
}
|
||||||
|
type InitNextResult = { reason?: string; success: boolean; userAppDir?: string }
|
||||||
|
|
||||||
|
export async function initNext(args: InitNextArgs): Promise<InitNextResult> {
|
||||||
|
args.projectDir = args.projectDir || process.cwd()
|
||||||
|
const { projectDir } = args
|
||||||
|
const templateResult = await applyPayloadTemplateFiles(args)
|
||||||
|
if (!templateResult.success) return templateResult
|
||||||
|
|
||||||
|
const { success: installSuccess } = await installDeps(projectDir)
|
||||||
|
if (!installSuccess) {
|
||||||
|
return { ...templateResult, reason: 'Failed to install dependencies', success: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create or find payload.config.ts
|
||||||
|
const createConfigResult = findOrCreatePayloadConfig(projectDir)
|
||||||
|
if (!createConfigResult.success) {
|
||||||
|
return { ...templateResult, ...createConfigResult }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add `@payload-config` to tsconfig.json `paths`
|
||||||
|
await addPayloadConfigToTsConfig(projectDir)
|
||||||
|
|
||||||
|
// Output directions for user to update next.config.js
|
||||||
|
const withPayloadMessage = `
|
||||||
|
|
||||||
|
${chalk.bold(`Wrap your existing next.config.js with the withPayload function. Here is an example:`)}
|
||||||
|
|
||||||
|
const { withPayload } = require("@payloadcms/next");
|
||||||
|
|
||||||
|
const nextConfig = {
|
||||||
|
// Your Next.js config
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = withPayload(nextConfig);
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
console.log(withPayloadMessage)
|
||||||
|
|
||||||
|
return templateResult
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addPayloadConfigToTsConfig(projectDir: string) {
|
||||||
|
const tsConfigPath = path.resolve(projectDir, 'tsconfig.json')
|
||||||
|
const userTsConfigContent = await fse.readFile(tsConfigPath, {
|
||||||
|
encoding: 'utf8',
|
||||||
|
})
|
||||||
|
const userTsConfig = CommentJson.parse(userTsConfigContent) as {
|
||||||
|
compilerOptions?: CompilerOptions
|
||||||
|
}
|
||||||
|
if (!userTsConfig.compilerOptions && !('extends' in userTsConfig)) {
|
||||||
|
userTsConfig.compilerOptions = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userTsConfig.compilerOptions.paths?.['@payload-config']) {
|
||||||
|
userTsConfig.compilerOptions.paths = {
|
||||||
|
...(userTsConfig.compilerOptions.paths || {}),
|
||||||
|
'@payload-config': ['./payload.config.ts'],
|
||||||
|
}
|
||||||
|
await fse.writeFile(tsConfigPath, CommentJson.stringify(userTsConfig, null, 2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyPayloadTemplateFiles(args: InitNextArgs): Promise<InitNextResult> {
|
||||||
|
const { '--debug': debug, projectDir, useDistFiles } = args
|
||||||
|
|
||||||
info('Initializing Payload app in Next.js project', 1)
|
info('Initializing Payload app in Next.js project', 1)
|
||||||
|
|
||||||
@@ -18,24 +90,18 @@ export async function initNext(
|
|||||||
if (debug) origDebug(message)
|
if (debug) origDebug(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
let projectDir = process.cwd()
|
|
||||||
if (nextDir) {
|
|
||||||
projectDir = path.resolve(projectDir, nextDir)
|
|
||||||
if (debug) logDebug(`Overriding project directory to ${projectDir}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fs.existsSync(projectDir)) {
|
if (!fs.existsSync(projectDir)) {
|
||||||
error(`Could not find specified project directory at ${projectDir}`)
|
return { reason: `Could not find specified project directory at ${projectDir}`, success: false }
|
||||||
return { success: false }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Next.js configs can be next.config.js, next.config.mjs, etc.
|
||||||
const foundConfig = (await globby('next.config.*js', { cwd: projectDir }))?.[0]
|
const foundConfig = (await globby('next.config.*js', { cwd: projectDir }))?.[0]
|
||||||
const nextConfigPath = path.resolve(projectDir, foundConfig)
|
const nextConfigPath = path.resolve(projectDir, foundConfig)
|
||||||
if (!fs.existsSync(nextConfigPath)) {
|
if (!fs.existsSync(nextConfigPath)) {
|
||||||
error(
|
return {
|
||||||
`No next.config.js found at ${nextConfigPath}. Ensure you are in a Next.js project directory.`,
|
reason: `No next.config.js found at ${nextConfigPath}. Ensure you are in a Next.js project directory.`,
|
||||||
)
|
success: false,
|
||||||
return { success: false }
|
}
|
||||||
} else {
|
} else {
|
||||||
if (debug) logDebug(`Found Next config at ${nextConfigPath}`)
|
if (debug) logDebug(`Found Next config at ${nextConfigPath}`)
|
||||||
}
|
}
|
||||||
@@ -43,21 +109,27 @@ export async function initNext(
|
|||||||
const templateFilesPath =
|
const templateFilesPath =
|
||||||
__dirname.endsWith('dist') || useDistFiles
|
__dirname.endsWith('dist') || useDistFiles
|
||||||
? path.resolve(__dirname, '../..', 'dist/app')
|
? path.resolve(__dirname, '../..', 'dist/app')
|
||||||
: path.resolve(__dirname, '../../../next/src/app')
|
: path.resolve(__dirname, '../../../../app')
|
||||||
|
|
||||||
if (debug) logDebug(`Using template files from: ${templateFilesPath}`)
|
if (debug) logDebug(`Using template files from: ${templateFilesPath}`)
|
||||||
|
|
||||||
if (!fs.existsSync(templateFilesPath)) {
|
if (!fs.existsSync(templateFilesPath)) {
|
||||||
error(`Could not find template source files from ${templateFilesPath}`)
|
return {
|
||||||
return { success: false }
|
reason: `Could not find template source files from ${templateFilesPath}`,
|
||||||
|
success: false,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (debug) logDebug('Found template source files')
|
if (debug) logDebug('Found template source files')
|
||||||
}
|
}
|
||||||
|
|
||||||
const userAppDir = path.resolve(projectDir, 'src/app')
|
// src/app or app
|
||||||
|
const userAppDirGlob = await globby(['**/app'], {
|
||||||
|
cwd: projectDir,
|
||||||
|
onlyDirectories: true,
|
||||||
|
})
|
||||||
|
const userAppDir = path.resolve(projectDir, userAppDirGlob?.[0])
|
||||||
if (!fs.existsSync(userAppDir)) {
|
if (!fs.existsSync(userAppDir)) {
|
||||||
error(`Could not find user app directory at ${userAppDir}`)
|
return { reason: `Could not find user app directory inside ${projectDir}`, success: false }
|
||||||
return { success: false }
|
|
||||||
} else {
|
} else {
|
||||||
logDebug(`Found user app directory: ${userAppDir}`)
|
logDebug(`Found user app directory: ${userAppDir}`)
|
||||||
}
|
}
|
||||||
@@ -65,5 +137,83 @@ export async function initNext(
|
|||||||
logDebug(`Copying template files from ${templateFilesPath} to ${userAppDir}`)
|
logDebug(`Copying template files from ${templateFilesPath} to ${userAppDir}`)
|
||||||
copyRecursiveSync(templateFilesPath, userAppDir, debug)
|
copyRecursiveSync(templateFilesPath, userAppDir, debug)
|
||||||
success('Successfully initialized.')
|
success('Successfully initialized.')
|
||||||
return { success: true }
|
return { success: true, userAppDir }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function installDeps(projectDir: string) {
|
||||||
|
const packageManager = await detect({ cwd: projectDir })
|
||||||
|
if (!packageManager) {
|
||||||
|
throw new Error('Could not detect package manager')
|
||||||
|
}
|
||||||
|
|
||||||
|
info(`Installing dependencies with ${packageManager}`, 1)
|
||||||
|
const packagesToInstall = [
|
||||||
|
'payload',
|
||||||
|
'@payloadcms/db-mongodb',
|
||||||
|
'@payloadcms/next',
|
||||||
|
'@payloadcms/richtext-slate',
|
||||||
|
'@payloadcms/ui',
|
||||||
|
].map((pkg) => `${pkg}@alpha`)
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exitCode !== 0) {
|
||||||
|
error(`Failed to install dependencies with ${packageManager}`)
|
||||||
|
} else {
|
||||||
|
success(`Successfully installed dependencies`)
|
||||||
|
}
|
||||||
|
return { success: exitCode === 0 }
|
||||||
|
}
|
||||||
|
function findOrCreatePayloadConfig(projectDir: string) {
|
||||||
|
const configPath = path.resolve(projectDir, 'payload.config.ts')
|
||||||
|
if (fs.existsSync(configPath)) {
|
||||||
|
return { message: 'Found existing payload.config.ts', success: true }
|
||||||
|
} else {
|
||||||
|
// Create default config
|
||||||
|
// TODO: Pull this from templates
|
||||||
|
const defaultConfig = `import path from "path";
|
||||||
|
|
||||||
|
import { mongooseAdapter } from "@payloadcms/db-mongodb"; // database-adapter-import
|
||||||
|
import { slateEditor } from "@payloadcms/richtext-slate"; // editor-import
|
||||||
|
import { buildConfig } from "payload/config";
|
||||||
|
|
||||||
|
export default buildConfig({
|
||||||
|
editor: slateEditor({}), // editor-config
|
||||||
|
collections: [],
|
||||||
|
secret: "asdfasdf",
|
||||||
|
typescript: {
|
||||||
|
outputFile: path.resolve(__dirname, "payload-types.ts"),
|
||||||
|
},
|
||||||
|
graphQL: {
|
||||||
|
schemaOutputFile: path.resolve(__dirname, "generated-schema.graphql"),
|
||||||
|
},
|
||||||
|
db: mongooseAdapter({
|
||||||
|
url: "mongodb://localhost:27017/next-payload-3",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
`
|
||||||
|
|
||||||
|
fse.writeFileSync(configPath, defaultConfig)
|
||||||
|
return { message: 'Created default payload.config.ts', success: true }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { parseTemplate } from './lib/parse-template'
|
|||||||
import { selectDb } from './lib/select-db'
|
import { selectDb } from './lib/select-db'
|
||||||
import { getValidTemplates, validateTemplate } from './lib/templates'
|
import { getValidTemplates, validateTemplate } from './lib/templates'
|
||||||
import { writeEnvFile } from './lib/write-env-file'
|
import { writeEnvFile } from './lib/write-env-file'
|
||||||
import { success } from './utils/log'
|
import { error, success } from './utils/log'
|
||||||
import { helpMessage, successMessage, welcomeMessage } from './utils/messages'
|
import { helpMessage, successMessage, welcomeMessage } from './utils/messages'
|
||||||
|
|
||||||
export class Main {
|
export class Main {
|
||||||
@@ -61,6 +61,11 @@ export class Main {
|
|||||||
|
|
||||||
if (this.args['--init-next']) {
|
if (this.args['--init-next']) {
|
||||||
const result = await initNext(this.args)
|
const result = await initNext(this.args)
|
||||||
|
if (!result.success) {
|
||||||
|
error(result.reason || 'Failed to initialize Payload app in Next.js project')
|
||||||
|
} else {
|
||||||
|
success('Payload app successfully initialized in Next.js project')
|
||||||
|
}
|
||||||
process.exit(result.success ? 0 : 1)
|
process.exit(result.success ? 0 : 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
56
pnpm-lock.yaml
generated
56
pnpm-lock.yaml
generated
@@ -110,6 +110,9 @@ importers:
|
|||||||
chalk:
|
chalk:
|
||||||
specifier: ^4.1.2
|
specifier: ^4.1.2
|
||||||
version: 4.1.2
|
version: 4.1.2
|
||||||
|
comment-json:
|
||||||
|
specifier: ^4.2.3
|
||||||
|
version: 4.2.3
|
||||||
concat-stream:
|
concat-stream:
|
||||||
specifier: ^2.0.0
|
specifier: ^2.0.0
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
@@ -278,9 +281,15 @@ importers:
|
|||||||
command-exists:
|
command-exists:
|
||||||
specifier: ^1.2.9
|
specifier: ^1.2.9
|
||||||
version: 1.2.9
|
version: 1.2.9
|
||||||
|
comment-json:
|
||||||
|
specifier: ^4.2.3
|
||||||
|
version: 4.2.3
|
||||||
degit:
|
degit:
|
||||||
specifier: ^2.8.4
|
specifier: ^2.8.4
|
||||||
version: 2.8.4
|
version: 2.8.4
|
||||||
|
detect-package-manager:
|
||||||
|
specifier: ^3.0.1
|
||||||
|
version: 3.0.1
|
||||||
execa:
|
execa:
|
||||||
specifier: ^5.0.0
|
specifier: ^5.0.0
|
||||||
version: 5.1.1
|
version: 5.1.1
|
||||||
@@ -4305,7 +4314,7 @@ packages:
|
|||||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 20.6.2
|
'@types/node': 16.18.85
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
jest-message-util: 29.7.0
|
jest-message-util: 29.7.0
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
@@ -4366,7 +4375,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jest/fake-timers': 29.7.0
|
'@jest/fake-timers': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 20.6.2
|
'@types/node': 16.18.85
|
||||||
jest-mock: 29.7.0
|
jest-mock: 29.7.0
|
||||||
|
|
||||||
/@jest/expect-utils@29.7.0:
|
/@jest/expect-utils@29.7.0:
|
||||||
@@ -4390,7 +4399,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@sinonjs/fake-timers': 10.3.0
|
'@sinonjs/fake-timers': 10.3.0
|
||||||
'@types/node': 20.6.2
|
'@types/node': 16.18.85
|
||||||
jest-message-util: 29.7.0
|
jest-message-util: 29.7.0
|
||||||
jest-mock: 29.7.0
|
jest-mock: 29.7.0
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
@@ -4421,7 +4430,7 @@ packages:
|
|||||||
'@jest/transform': 29.7.0
|
'@jest/transform': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@jridgewell/trace-mapping': 0.3.23
|
'@jridgewell/trace-mapping': 0.3.23
|
||||||
'@types/node': 20.6.2
|
'@types/node': 16.18.85
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
collect-v8-coverage: 1.0.2
|
collect-v8-coverage: 1.0.2
|
||||||
exit: 0.1.2
|
exit: 0.1.2
|
||||||
@@ -7491,6 +7500,9 @@ packages:
|
|||||||
is-string: 1.0.7
|
is-string: 1.0.7
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/array-timsort@1.0.3:
|
||||||
|
resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==}
|
||||||
|
|
||||||
/array-union@2.1.0:
|
/array-union@2.1.0:
|
||||||
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
|
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -8290,6 +8302,16 @@ packages:
|
|||||||
engines: {node: ^12.20.0 || >=14}
|
engines: {node: ^12.20.0 || >=14}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/comment-json@4.2.3:
|
||||||
|
resolution: {integrity: sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
dependencies:
|
||||||
|
array-timsort: 1.0.3
|
||||||
|
core-util-is: 1.0.3
|
||||||
|
esprima: 4.0.1
|
||||||
|
has-own-prop: 2.0.0
|
||||||
|
repeat-string: 1.6.1
|
||||||
|
|
||||||
/comment-parser@1.4.1:
|
/comment-parser@1.4.1:
|
||||||
resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==}
|
resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
@@ -8559,7 +8581,6 @@ packages:
|
|||||||
|
|
||||||
/core-util-is@1.0.3:
|
/core-util-is@1.0.3:
|
||||||
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/cosmiconfig@7.1.0:
|
/cosmiconfig@7.1.0:
|
||||||
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
|
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
|
||||||
@@ -9177,6 +9198,13 @@ packages:
|
|||||||
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
|
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
/detect-package-manager@3.0.1:
|
||||||
|
resolution: {integrity: sha512-qoHDH6+lMcpJPAScE7+5CYj91W0mxZNXTwZPrCqi1KMk+x+AoQScQ2V1QyqTln1rHU5Haq5fikvOGHv+leKD8A==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
execa: 5.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/diff-sequences@27.5.1:
|
/diff-sequences@27.5.1:
|
||||||
resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==}
|
resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==}
|
||||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||||
@@ -11166,6 +11194,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
/has-own-prop@2.0.0:
|
||||||
|
resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
/has-property-descriptors@1.0.2:
|
/has-property-descriptors@1.0.2:
|
||||||
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -12313,7 +12345,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/graceful-fs': 4.1.9
|
'@types/graceful-fs': 4.1.9
|
||||||
'@types/node': 20.6.2
|
'@types/node': 16.18.85
|
||||||
anymatch: 3.1.3
|
anymatch: 3.1.3
|
||||||
fb-watchman: 2.0.2
|
fb-watchman: 2.0.2
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
@@ -12370,7 +12402,7 @@ packages:
|
|||||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 20.6.2
|
'@types/node': 16.18.85
|
||||||
jest-util: 29.7.0
|
jest-util: 29.7.0
|
||||||
|
|
||||||
/jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
|
/jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
|
||||||
@@ -12420,7 +12452,7 @@ packages:
|
|||||||
'@jest/test-result': 29.7.0
|
'@jest/test-result': 29.7.0
|
||||||
'@jest/transform': 29.7.0
|
'@jest/transform': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 20.6.2
|
'@types/node': 16.18.85
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
emittery: 0.13.1
|
emittery: 0.13.1
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
@@ -12450,7 +12482,7 @@ packages:
|
|||||||
'@jest/test-result': 29.7.0
|
'@jest/test-result': 29.7.0
|
||||||
'@jest/transform': 29.7.0
|
'@jest/transform': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 20.6.2
|
'@types/node': 16.18.85
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
cjs-module-lexer: 1.2.3
|
cjs-module-lexer: 1.2.3
|
||||||
collect-v8-coverage: 1.0.2
|
collect-v8-coverage: 1.0.2
|
||||||
@@ -12523,7 +12555,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jest/test-result': 29.7.0
|
'@jest/test-result': 29.7.0
|
||||||
'@jest/types': 29.6.3
|
'@jest/types': 29.6.3
|
||||||
'@types/node': 20.6.2
|
'@types/node': 16.18.85
|
||||||
ansi-escapes: 4.3.2
|
ansi-escapes: 4.3.2
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
emittery: 0.13.1
|
emittery: 0.13.1
|
||||||
@@ -15847,6 +15879,10 @@ packages:
|
|||||||
- typescript
|
- typescript
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/repeat-string@1.6.1:
|
||||||
|
resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==}
|
||||||
|
engines: {node: '>=0.10'}
|
||||||
|
|
||||||
/require-directory@2.1.1:
|
/require-directory@2.1.1:
|
||||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|||||||
@@ -1,48 +1,85 @@
|
|||||||
|
import type { CompilerOptions } from 'typescript'
|
||||||
|
|
||||||
|
import * as CommentJson from 'comment-json'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import shelljs from 'shelljs'
|
import shelljs from 'shelljs'
|
||||||
|
import { promisify } from 'util'
|
||||||
|
|
||||||
import { initNext } from '../../packages/create-payload-app/src/lib/init-next'
|
import { initNext } from '../../packages/create-payload-app/src/lib/init-next'
|
||||||
|
const readFile = promisify(fs.readFile)
|
||||||
|
|
||||||
|
const nextCreateCommands: Partial<Record<'noSrcDir' | 'srcDir', string>> = {
|
||||||
|
srcDir:
|
||||||
|
'pnpm create next-app@latest . --typescript --eslint --no-tailwind --app --import-alias="@/*" --src-dir',
|
||||||
|
noSrcDir:
|
||||||
|
'pnpm create next-app@latest . --typescript --eslint --no-tailwind --app --import-alias="@/*" --no-src-dir',
|
||||||
|
}
|
||||||
|
|
||||||
describe('create-payload-app', () => {
|
describe('create-payload-app', () => {
|
||||||
describe('--init-next', () => {
|
|
||||||
const nextDir = path.resolve(__dirname, 'test-app')
|
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
if (fs.existsSync(nextDir)) {
|
// Runs copyfiles copy app/(payload) -> dist/app/(payload)
|
||||||
fs.rmdirSync(nextDir, { recursive: true })
|
shelljs.exec('pnpm build:create-payload-app')
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Next.js app template files', () => {
|
||||||
|
it('should exist in dist', () => {
|
||||||
|
const distPath = path.resolve(
|
||||||
|
__dirname,
|
||||||
|
'../../packages/create-payload-app/dist/app/(payload)',
|
||||||
|
)
|
||||||
|
expect(fs.existsSync(distPath)).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe.each(Object.keys(nextCreateCommands))(`--init-next with %s`, (nextCmdKey) => {
|
||||||
|
const projectDir = path.resolve(__dirname, 'test-app')
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
if (fs.existsSync(projectDir)) {
|
||||||
|
fs.rmdirSync(projectDir, { recursive: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create dir for Next.js project
|
// Create dir for Next.js project
|
||||||
if (!fs.existsSync(nextDir)) {
|
if (!fs.existsSync(projectDir)) {
|
||||||
fs.mkdirSync(nextDir)
|
fs.mkdirSync(projectDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Next.js project with default options
|
// Create a new Next.js project with default options
|
||||||
shelljs.exec(
|
shelljs.exec(nextCreateCommands[nextCmdKey], { cwd: projectDir })
|
||||||
'pnpm create next-app@latest . --typescript --eslint --no-tailwind --app --import-alias="@/*" --src-dir',
|
|
||||||
{ cwd: nextDir },
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(() => {
|
afterEach(() => {
|
||||||
if (fs.existsSync(nextDir)) {
|
if (fs.existsSync(projectDir)) {
|
||||||
fs.rmdirSync(nextDir, { recursive: true })
|
fs.rmdirSync(projectDir, { recursive: true })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should install payload app in Next.js project', async () => {
|
it('should install payload app in Next.js project', async () => {
|
||||||
expect(fs.existsSync(nextDir)).toBe(true)
|
expect(fs.existsSync(projectDir)).toBe(true)
|
||||||
|
|
||||||
const result = await initNext({
|
const result = await initNext({
|
||||||
'--debug': true,
|
'--debug': true,
|
||||||
nextDir,
|
projectDir,
|
||||||
useDistFiles: true, // create-payload-app must be built
|
useDistFiles: true, // create-payload-app/dist/app/(payload)
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(result.success).toBe(true)
|
expect(result.success).toBe(true)
|
||||||
const payloadFilesPath = path.resolve(nextDir, 'src/app/(payload)')
|
|
||||||
|
const payloadFilesPath = path.resolve(result.userAppDir, '(payload)')
|
||||||
expect(fs.existsSync(payloadFilesPath)).toBe(true)
|
expect(fs.existsSync(payloadFilesPath)).toBe(true)
|
||||||
|
|
||||||
|
const payloadConfig = path.resolve(projectDir, 'payload.config.ts')
|
||||||
|
expect(fs.existsSync(payloadConfig)).toBe(true)
|
||||||
|
|
||||||
|
const tsConfigPath = path.resolve(projectDir, 'tsconfig.json')
|
||||||
|
const userTsConfigContent = await readFile(tsConfigPath, { encoding: 'utf8' })
|
||||||
|
const userTsConfig = CommentJson.parse(userTsConfigContent) as {
|
||||||
|
compilerOptions?: CompilerOptions
|
||||||
|
}
|
||||||
|
expect(userTsConfig.compilerOptions.paths?.['@payload-config']).toEqual([
|
||||||
|
'./payload.config.ts',
|
||||||
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user