chore(templates): add generated templates [no-lint] (#6604)
Generate static template variations
This commit is contained in:
33
.github/workflows/main.yml
vendored
33
.github/workflows/main.yml
vendored
@@ -56,7 +56,8 @@ jobs:
|
|||||||
echo "templates: ${{ steps.filter.outputs.templates }}"
|
echo "templates: ${{ steps.filter.outputs.templates }}"
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
if: github.event_name == 'pull_request'
|
if: >
|
||||||
|
github.event_name == 'pull_request' && !contains(github.event.pull_request.title, 'no-lint') && !contains(github.event.pull_request.title, 'skip-lint')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -500,6 +501,36 @@ jobs:
|
|||||||
yarn build
|
yarn build
|
||||||
yarn generate:types
|
yarn generate:types
|
||||||
|
|
||||||
|
generated-templates:
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# https://github.com/actions/virtual-environments/issues/1187
|
||||||
|
- name: tune linux network
|
||||||
|
run: sudo ethtool -K eth0 tx off rx off
|
||||||
|
|
||||||
|
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
|
||||||
|
- name: Install pnpm
|
||||||
|
uses: pnpm/action-setup@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.PNPM_VERSION }}
|
||||||
|
run_install: false
|
||||||
|
|
||||||
|
- name: Restore build
|
||||||
|
uses: actions/cache@v4
|
||||||
|
timeout-minutes: 10
|
||||||
|
with:
|
||||||
|
path: ./*
|
||||||
|
key: ${{ github.sha }}-${{ github.run_number }}
|
||||||
|
|
||||||
|
- name: Build all generated templates
|
||||||
|
run: pnpm tsx ./scripts/build-generated-templates.ts
|
||||||
|
|
||||||
all-green:
|
all-green:
|
||||||
name: All Green
|
name: All Green
|
||||||
if: always()
|
if: always()
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
"reinstall": "pnpm clean:all && pnpm install",
|
"reinstall": "pnpm clean:all && pnpm install",
|
||||||
"release:alpha": "tsx ./scripts/release.ts --bump prerelease --tag alpha",
|
"release:alpha": "tsx ./scripts/release.ts --bump prerelease --tag alpha",
|
||||||
"release:beta": "tsx ./scripts/release.ts --bump prerelease --tag beta",
|
"release:beta": "tsx ./scripts/release.ts --bump prerelease --tag beta",
|
||||||
|
"script:gen-templates": "tsx ./scripts/generate-template-variations.ts",
|
||||||
"script:list-published": "tsx scripts/lib/getPackageRegistryVersions.ts",
|
"script:list-published": "tsx scripts/lib/getPackageRegistryVersions.ts",
|
||||||
"script:pack": "tsx scripts/pack-all-to-dest.ts",
|
"script:pack": "tsx scripts/pack-all-to-dest.ts",
|
||||||
"pretest": "pnpm build",
|
"pretest": "pnpm build",
|
||||||
@@ -107,6 +108,7 @@
|
|||||||
"changelogen": "^0.5.5",
|
"changelogen": "^0.5.5",
|
||||||
"comment-json": "^4.2.3",
|
"comment-json": "^4.2.3",
|
||||||
"copyfiles": "2.4.1",
|
"copyfiles": "2.4.1",
|
||||||
|
"create-payload-app": "workspace:*",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"dotenv": "16.4.5",
|
"dotenv": "16.4.5",
|
||||||
"drizzle-kit": "0.20.14-1f2c838",
|
"drizzle-kit": "0.20.14-1f2c838",
|
||||||
|
|||||||
@@ -10,10 +10,24 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
"./types": {
|
||||||
|
"import": "./src/types.ts",
|
||||||
|
"require": "./src/types.ts"
|
||||||
|
},
|
||||||
"./commands": {
|
"./commands": {
|
||||||
"import": "./src/lib/init-next.ts",
|
"import": "./src/lib/init-next.ts",
|
||||||
"require": "./src/lib/init-next.ts",
|
"require": "./src/lib/init-next.ts",
|
||||||
"types": "./src/lib/init-next.ts"
|
"types": "./src/lib/init-next.ts"
|
||||||
|
},
|
||||||
|
"./lib/*": {
|
||||||
|
"import": "./src/lib/*",
|
||||||
|
"require": "./src/lib/*",
|
||||||
|
"types": "./src/lib/*"
|
||||||
|
},
|
||||||
|
"./utils/*": {
|
||||||
|
"import": "./src/utils/*",
|
||||||
|
"require": "./src/utils/*",
|
||||||
|
"types": "./src/utils/*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
import fse from 'fs-extra'
|
import fse from 'fs-extra'
|
||||||
import globby from 'globby'
|
import globby from 'globby'
|
||||||
import { fileURLToPath } from 'node:url'
|
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
const filename = fileURLToPath(import.meta.url)
|
|
||||||
const dirname = path.dirname(filename)
|
|
||||||
|
|
||||||
import type { DbDetails } from '../types.js'
|
import type { DbType, StorageAdapterType } from '../types.js'
|
||||||
|
|
||||||
import { warning } from '../utils/log.js'
|
import { warning } from '../utils/log.js'
|
||||||
import { dbReplacements } from './packages.js'
|
import { configReplacements, dbReplacements, storageReplacements } from './replacements.js'
|
||||||
|
|
||||||
/** Update payload config with necessary imports and adapters */
|
/** Update payload config with necessary imports and adapters */
|
||||||
export async function configurePayloadConfig(args: {
|
export async function configurePayloadConfig(args: {
|
||||||
dbDetails: DbDetails | undefined
|
dbType?: DbType
|
||||||
|
envNames?: {
|
||||||
|
dbUri: string
|
||||||
|
}
|
||||||
|
packageJsonName?: string
|
||||||
projectDirOrConfigPath: { payloadConfigPath: string } | { projectDir: string }
|
projectDirOrConfigPath: { payloadConfigPath: string } | { projectDir: string }
|
||||||
|
storageAdapter?: StorageAdapterType
|
||||||
|
sharp?: boolean
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
if (!args.dbDetails) {
|
if (!args.dbType) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +31,7 @@ export async function configurePayloadConfig(args: {
|
|||||||
try {
|
try {
|
||||||
const packageObj = await fse.readJson(packageJsonPath)
|
const packageObj = await fse.readJson(packageJsonPath)
|
||||||
|
|
||||||
const dbPackage = dbReplacements[args.dbDetails.type]
|
const dbPackage = dbReplacements[args.dbType]
|
||||||
|
|
||||||
// Delete all other db adapters
|
// Delete all other db adapters
|
||||||
Object.values(dbReplacements).forEach((p) => {
|
Object.values(dbReplacements).forEach((p) => {
|
||||||
@@ -40,6 +43,24 @@ export async function configurePayloadConfig(args: {
|
|||||||
// Set version of db adapter to match payload version
|
// Set version of db adapter to match payload version
|
||||||
packageObj.dependencies[dbPackage.packageName] = packageObj.dependencies['payload']
|
packageObj.dependencies[dbPackage.packageName] = packageObj.dependencies['payload']
|
||||||
|
|
||||||
|
if (args.storageAdapter) {
|
||||||
|
const storagePackage = storageReplacements[args.storageAdapter]
|
||||||
|
|
||||||
|
if (storagePackage?.packageName) {
|
||||||
|
// Set version of storage adapter to match payload version
|
||||||
|
packageObj.dependencies[storagePackage.packageName] = packageObj.dependencies['payload']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sharp provided by default, only remove if explicitly set to false
|
||||||
|
if (args.sharp === false) {
|
||||||
|
delete packageObj.dependencies['sharp']
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.packageJsonName) {
|
||||||
|
packageObj.name = args.packageJsonName
|
||||||
|
}
|
||||||
|
|
||||||
await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })
|
await fse.writeJson(packageJsonPath, packageObj, { spaces: 2 })
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
warning(`Unable to configure Payload in package.json`)
|
warning(`Unable to configure Payload in package.json`)
|
||||||
@@ -66,35 +87,54 @@ export async function configurePayloadConfig(args: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const configContent = fse.readFileSync(payloadConfigPath, 'utf-8')
|
const configContent = fse.readFileSync(payloadConfigPath, 'utf-8')
|
||||||
const configLines = configContent.split('\n')
|
let configLines = configContent.split('\n')
|
||||||
|
|
||||||
const dbReplacement = dbReplacements[args.dbDetails.type]
|
// DB Replacement
|
||||||
|
const dbReplacement = dbReplacements[args.dbType]
|
||||||
|
|
||||||
let dbConfigStartLineIndex: number | undefined
|
configLines = replaceInConfigLines({
|
||||||
let dbConfigEndLineIndex: number | undefined
|
replacement: dbReplacement.configReplacement(args.envNames?.dbUri),
|
||||||
|
startMatch: `// database-adapter-config-start`,
|
||||||
configLines.forEach((l, i) => {
|
endMatch: `// database-adapter-config-end`,
|
||||||
if (l.includes('// database-adapter-import')) {
|
lines: configLines,
|
||||||
configLines[i] = dbReplacement.importReplacement
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l.includes('// database-adapter-config-start')) {
|
|
||||||
dbConfigStartLineIndex = i
|
|
||||||
}
|
|
||||||
if (l.includes('// database-adapter-config-end')) {
|
|
||||||
dbConfigEndLineIndex = i
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!dbConfigStartLineIndex || !dbConfigEndLineIndex) {
|
configLines = replaceInConfigLines({
|
||||||
warning('Unable to update payload.config.ts with database adapter import')
|
replacement: [dbReplacement.importReplacement],
|
||||||
} else {
|
startMatch: '// database-adapter-import',
|
||||||
// Replaces lines between `// database-adapter-config-start` and `// database-adapter-config-end`
|
lines: configLines,
|
||||||
configLines.splice(
|
})
|
||||||
dbConfigStartLineIndex,
|
|
||||||
dbConfigEndLineIndex - dbConfigStartLineIndex + 1,
|
// Storage Adapter Replacement
|
||||||
...dbReplacement.configReplacement,
|
if (args.storageAdapter) {
|
||||||
)
|
const replacement = storageReplacements[args.storageAdapter]
|
||||||
|
configLines = replaceInConfigLines({
|
||||||
|
replacement: replacement.configReplacement,
|
||||||
|
startMatch: '// storage-adapter-placeholder',
|
||||||
|
lines: configLines,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (replacement?.importReplacement) {
|
||||||
|
configLines = replaceInConfigLines({
|
||||||
|
replacement: [replacement.importReplacement],
|
||||||
|
startMatch: '// storage-adapter-import-placeholder',
|
||||||
|
lines: configLines,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sharp Replacement (provided by default, only remove if explicitly set to false)
|
||||||
|
if (args.sharp === false) {
|
||||||
|
configLines = replaceInConfigLines({
|
||||||
|
replacement: [],
|
||||||
|
startMatch: 'sharp,',
|
||||||
|
lines: configLines,
|
||||||
|
})
|
||||||
|
configLines = replaceInConfigLines({
|
||||||
|
replacement: [],
|
||||||
|
startMatch: "import sharp from 'sharp'",
|
||||||
|
lines: configLines,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fse.writeFileSync(payloadConfigPath, configLines.join('\n'))
|
fse.writeFileSync(payloadConfigPath, configLines.join('\n'))
|
||||||
@@ -104,3 +144,30 @@ export async function configurePayloadConfig(args: {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function replaceInConfigLines({
|
||||||
|
replacement,
|
||||||
|
startMatch,
|
||||||
|
endMatch,
|
||||||
|
lines,
|
||||||
|
}: {
|
||||||
|
replacement: string[]
|
||||||
|
startMatch: string
|
||||||
|
/** Optional endMatch to replace multiple lines */
|
||||||
|
endMatch?: string
|
||||||
|
lines: string[]
|
||||||
|
}) {
|
||||||
|
if (!replacement) {
|
||||||
|
return lines
|
||||||
|
}
|
||||||
|
|
||||||
|
const startIndex = lines.findIndex((l) => l.includes(startMatch))
|
||||||
|
const endIndex = endMatch ? lines.findIndex((l) => l.includes(endMatch)) : startIndex
|
||||||
|
|
||||||
|
if (startIndex === -1 || endIndex === -1) {
|
||||||
|
return lines
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.splice(startIndex, endIndex - startIndex + 1, ...replacement)
|
||||||
|
return lines
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import fse from 'fs-extra'
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
import type { CliArgs, DbType, ProjectTemplate } from '../types.js'
|
import type { CliArgs, DbType, ProjectTemplate } from '../types.js'
|
||||||
import { createProject } from './create-project.js'
|
import { createProject } from './create-project.js'
|
||||||
import { dbReplacements } from './packages.js'
|
import { dbReplacements } from './replacements.js'
|
||||||
import { getValidTemplates } from './templates.js'
|
import { getValidTemplates } from './templates.js'
|
||||||
import globby from 'globby'
|
import globby from 'globby'
|
||||||
import { jest } from '@jest/globals'
|
import { jest } from '@jest/globals'
|
||||||
@@ -125,7 +125,7 @@ describe('createProject', () => {
|
|||||||
|
|
||||||
expect(content).not.toContain('// database-adapter-config-start')
|
expect(content).not.toContain('// database-adapter-config-start')
|
||||||
expect(content).not.toContain('// database-adapter-config-end')
|
expect(content).not.toContain('// database-adapter-config-end')
|
||||||
expect(content).toContain(dbReplacement.configReplacement.join('\n'))
|
expect(content).toContain(dbReplacement.configReplacement().join('\n'))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -90,7 +90,10 @@ export async function createProject(args: {
|
|||||||
|
|
||||||
await updatePackageJSON({ projectDir, projectName })
|
await updatePackageJSON({ projectDir, projectName })
|
||||||
spinner.message('Configuring Payload...')
|
spinner.message('Configuring Payload...')
|
||||||
await configurePayloadConfig({ dbDetails, projectDirOrConfigPath: { projectDir } })
|
await configurePayloadConfig({
|
||||||
|
dbType: dbDetails?.type,
|
||||||
|
projectDirOrConfigPath: { projectDir },
|
||||||
|
})
|
||||||
|
|
||||||
// Remove yarn.lock file. This is only desired in Payload Cloud.
|
// Remove yarn.lock file. This is only desired in Payload Cloud.
|
||||||
const lockPath = path.resolve(projectDir, 'yarn.lock')
|
const lockPath = path.resolve(projectDir, 'yarn.lock')
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
import type { DbType } from '../types.js'
|
|
||||||
|
|
||||||
type DbAdapterReplacement = {
|
|
||||||
configReplacement: string[]
|
|
||||||
importReplacement: string
|
|
||||||
packageName: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const mongodbReplacement: DbAdapterReplacement = {
|
|
||||||
importReplacement: "import { mongooseAdapter } from '@payloadcms/db-mongodb'",
|
|
||||||
packageName: '@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 = {
|
|
||||||
configReplacement: [
|
|
||||||
' db: postgresAdapter({',
|
|
||||||
' pool: {',
|
|
||||||
" connectionString: process.env.DATABASE_URI || '',",
|
|
||||||
' },',
|
|
||||||
' }),',
|
|
||||||
],
|
|
||||||
importReplacement: "import { postgresAdapter } from '@payloadcms/db-postgres'",
|
|
||||||
packageName: '@payloadcms/db-postgres',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const dbReplacements: Record<DbType, DbAdapterReplacement> = {
|
|
||||||
mongodb: mongodbReplacement,
|
|
||||||
postgres: postgresReplacement,
|
|
||||||
}
|
|
||||||
96
packages/create-payload-app/src/lib/replacements.ts
Normal file
96
packages/create-payload-app/src/lib/replacements.ts
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import type { DbType, StorageAdapterType } from '../types.js'
|
||||||
|
|
||||||
|
type DbAdapterReplacement = {
|
||||||
|
configReplacement: (envName?: string) => string[]
|
||||||
|
importReplacement: string
|
||||||
|
packageName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const mongodbReplacement: DbAdapterReplacement = {
|
||||||
|
// Replacement between `// database-adapter-config-start` and `// database-adapter-config-end`
|
||||||
|
configReplacement: (envName = 'DATABASE_URI') => [
|
||||||
|
' db: mongooseAdapter({',
|
||||||
|
` url: process.env.${envName} || '',`,
|
||||||
|
' }),',
|
||||||
|
],
|
||||||
|
importReplacement: "import { mongooseAdapter } from '@payloadcms/db-mongodb'",
|
||||||
|
packageName: '@payloadcms/db-mongodb',
|
||||||
|
}
|
||||||
|
|
||||||
|
const postgresReplacement: DbAdapterReplacement = {
|
||||||
|
configReplacement: (envName = 'DATABASE_URI') => [
|
||||||
|
' db: postgresAdapter({',
|
||||||
|
' pool: {',
|
||||||
|
` connectionString: process.env.${envName} || '',`,
|
||||||
|
' },',
|
||||||
|
' }),',
|
||||||
|
],
|
||||||
|
importReplacement: "import { postgresAdapter } from '@payloadcms/db-postgres'",
|
||||||
|
packageName: '@payloadcms/db-postgres',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dbReplacements: Record<DbType, DbAdapterReplacement> = {
|
||||||
|
mongodb: mongodbReplacement,
|
||||||
|
postgres: postgresReplacement,
|
||||||
|
}
|
||||||
|
|
||||||
|
type StorageAdapterReplacement = {
|
||||||
|
configReplacement: string[]
|
||||||
|
importReplacement?: string
|
||||||
|
packageName?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const vercelBlobStorageReplacement: StorageAdapterReplacement = {
|
||||||
|
// Replacement of `// storage-adapter-placeholder`
|
||||||
|
configReplacement: [
|
||||||
|
' vercelBlobStorage({',
|
||||||
|
' collections: {',
|
||||||
|
' [Media.slug]: true,',
|
||||||
|
' },',
|
||||||
|
" token: process.env.BLOB_READ_WRITE_TOKEN || '',",
|
||||||
|
' }),',
|
||||||
|
],
|
||||||
|
importReplacement: "import { vercelBlobStorage } from '@payloadcms/storage-vercel-blob'",
|
||||||
|
packageName: '@payloadcms/storage-vercel-blob',
|
||||||
|
}
|
||||||
|
|
||||||
|
const payloadCloudReplacement: StorageAdapterReplacement = {
|
||||||
|
configReplacement: [' payloadCloudPlugin(),'],
|
||||||
|
importReplacement: "import { payloadCloudPlugin } from '@payloadcms/plugin-cloud'",
|
||||||
|
packageName: '@payloadcms/plugin-cloud',
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes placeholders
|
||||||
|
const diskReplacement: StorageAdapterReplacement = {
|
||||||
|
configReplacement: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
export const storageReplacements: Record<StorageAdapterType, StorageAdapterReplacement> = {
|
||||||
|
payloadCloud: payloadCloudReplacement,
|
||||||
|
vercelBlobStorage: vercelBlobStorageReplacement,
|
||||||
|
localDisk: diskReplacement,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic config replacement
|
||||||
|
*/
|
||||||
|
type ConfigReplacement = {
|
||||||
|
configReplacement: {
|
||||||
|
match: string
|
||||||
|
replacement: string
|
||||||
|
}
|
||||||
|
importReplacement: string
|
||||||
|
packageName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const configReplacements: Record<string, ConfigReplacement> = {
|
||||||
|
sharp: {
|
||||||
|
// Replacement of `sharp, // Now optional`
|
||||||
|
configReplacement: {
|
||||||
|
match: 'sharp,',
|
||||||
|
replacement: ' // sharp,',
|
||||||
|
},
|
||||||
|
importReplacement: "import sharp from 'sharp'",
|
||||||
|
packageName: 'sharp',
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -95,7 +95,7 @@ export class Main {
|
|||||||
message: chalk.bold(`Upgrade Payload in this project?`),
|
message: chalk.bold(`Upgrade Payload in this project?`),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!p.isCancel(shouldUpdate) || shouldUpdate) {
|
if (!p.isCancel(shouldUpdate) && shouldUpdate) {
|
||||||
const { message, success: updateSuccess } = await updatePayloadInProject(nextAppDetails)
|
const { message, success: updateSuccess } = await updatePayloadInProject(nextAppDetails)
|
||||||
if (updateSuccess) {
|
if (updateSuccess) {
|
||||||
info(message)
|
info(message)
|
||||||
@@ -156,7 +156,7 @@ export class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await configurePayloadConfig({
|
await configurePayloadConfig({
|
||||||
dbDetails,
|
dbType: dbDetails?.type,
|
||||||
projectDirOrConfigPath: {
|
projectDirOrConfigPath: {
|
||||||
payloadConfigPath: result.payloadConfigPath,
|
payloadConfigPath: result.payloadConfigPath,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -76,3 +76,5 @@ export type NextAppDetails = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type NextConfigType = 'cjs' | 'esm'
|
export type NextConfigType = 'cjs' | 'esm'
|
||||||
|
|
||||||
|
export type StorageAdapterType = 'payloadCloud' | 'vercelBlobStorage' | 'localDisk'
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import path from 'path'
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively copy files from src to dest
|
* Recursively copy files from src to dest
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
*/
|
*/
|
||||||
export function copyRecursiveSync(src: string, dest: string, debug?: boolean) {
|
export function copyRecursiveSync(src: string, dest: string, debug?: boolean) {
|
||||||
const exists = fs.existsSync(src)
|
const exists = fs.existsSync(src)
|
||||||
|
|||||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -95,6 +95,9 @@ importers:
|
|||||||
copyfiles:
|
copyfiles:
|
||||||
specifier: 2.4.1
|
specifier: 2.4.1
|
||||||
version: 2.4.1
|
version: 2.4.1
|
||||||
|
create-payload-app:
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:packages/create-payload-app
|
||||||
cross-env:
|
cross-env:
|
||||||
specifier: 7.0.3
|
specifier: 7.0.3
|
||||||
version: 7.0.3
|
version: 7.0.3
|
||||||
|
|||||||
36
scripts/build-generated-templates.ts
Normal file
36
scripts/build-generated-templates.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import * as fs from 'node:fs/promises'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import path from 'path'
|
||||||
|
import { execSync } from 'child_process'
|
||||||
|
|
||||||
|
const filename = fileURLToPath(import.meta.url)
|
||||||
|
const dirname = path.dirname(filename)
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
console.error(error)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
// Get all directories in `templates` directory
|
||||||
|
const repoRoot = path.resolve(dirname, '..')
|
||||||
|
const templatesDir = path.resolve(repoRoot, 'templates')
|
||||||
|
|
||||||
|
const rawTemplateDirs = await fs.readdir(templatesDir, { withFileTypes: true })
|
||||||
|
const templateDirnames = rawTemplateDirs
|
||||||
|
.filter(
|
||||||
|
(dirent) =>
|
||||||
|
dirent.isDirectory() && (dirent.name.startsWith('with') || dirent.name == 'blank'),
|
||||||
|
)
|
||||||
|
.map((dirent) => dirent.name)
|
||||||
|
|
||||||
|
console.log(`Found generated templates: ${templateDirnames}`)
|
||||||
|
|
||||||
|
// Build each template
|
||||||
|
for (const template of templateDirnames) {
|
||||||
|
const cmd = `cd ${templatesDir}/${template} && pnpm install --ignore-workspace --no-frozen-lockfile && pnpm build`
|
||||||
|
console.log(`🔧 Building ${template}...`)
|
||||||
|
console.log(` cmd: ${cmd}\n\n`)
|
||||||
|
execSync(cmd, { stdio: 'inherit' })
|
||||||
|
}
|
||||||
|
}
|
||||||
196
scripts/generate-template-variations.ts
Normal file
196
scripts/generate-template-variations.ts
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/**
|
||||||
|
* This script generates variations of the templates into the `templates` directory.
|
||||||
|
*
|
||||||
|
* How to use:
|
||||||
|
*
|
||||||
|
* pnpm run script:gen-templates
|
||||||
|
*
|
||||||
|
* NOTE: You will likely have to commit by using the `--no-verify` flag to avoid the repo linting
|
||||||
|
* There is no way currently to have lint-staged ignore the templates directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { DbType, StorageAdapterType } from 'packages/create-payload-app/src/types.js'
|
||||||
|
|
||||||
|
import { configurePayloadConfig } from 'create-payload-app/lib/configure-payload-config.js'
|
||||||
|
import { copyRecursiveSync } from 'create-payload-app/utils/copy-recursive-sync.js'
|
||||||
|
import * as fs from 'node:fs/promises'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import path from 'path'
|
||||||
|
import { execSync } from 'child_process'
|
||||||
|
|
||||||
|
const filename = fileURLToPath(import.meta.url)
|
||||||
|
const dirname = path.dirname(filename)
|
||||||
|
|
||||||
|
type TemplateVariations = {
|
||||||
|
/** package.json name */
|
||||||
|
name: string
|
||||||
|
/** Directory in templates dir */
|
||||||
|
dirname: string
|
||||||
|
db: DbType
|
||||||
|
storage: StorageAdapterType
|
||||||
|
sharp: boolean
|
||||||
|
vercelDeployButtonLink?: string
|
||||||
|
envNames?: {
|
||||||
|
dbUri: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
console.error(error)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const templatesDir = path.resolve(dirname, '../templates')
|
||||||
|
|
||||||
|
// WARNING: This will need to be updated when this merges into main
|
||||||
|
const templateRepoUrlBase = `https://github.com/payloadcms/payload/tree/beta/templates`
|
||||||
|
|
||||||
|
const variations: TemplateVariations[] = [
|
||||||
|
{
|
||||||
|
name: 'payload-vercel-postgres-template',
|
||||||
|
dirname: 'with-vercel-postgres',
|
||||||
|
db: 'postgres',
|
||||||
|
storage: 'vercelBlobStorage',
|
||||||
|
sharp: false,
|
||||||
|
vercelDeployButtonLink:
|
||||||
|
`https://vercel.com/new/clone?repository-url=` +
|
||||||
|
encodeURI(
|
||||||
|
`${templateRepoUrlBase}/${dirname}` +
|
||||||
|
'&project-name=payload-project' +
|
||||||
|
'&env=PAYLOAD_SECRET' +
|
||||||
|
'&build-command=pnpm run ci' +
|
||||||
|
'&stores=[{"type":"postgres"},{"type":"blob"}]', // Postgres and Vercel Blob Storage
|
||||||
|
),
|
||||||
|
envNames: {
|
||||||
|
// This will replace the process.env.DATABASE_URI to process.env.POSTGRES_URL
|
||||||
|
dbUri: 'POSTGRES_URL',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'payload-vercel-mongodb-template',
|
||||||
|
dirname: 'with-vercel-mongodb',
|
||||||
|
db: 'mongodb',
|
||||||
|
storage: 'vercelBlobStorage',
|
||||||
|
sharp: false,
|
||||||
|
vercelDeployButtonLink:
|
||||||
|
`https://vercel.com/new/clone?repository-url=` +
|
||||||
|
encodeURI(
|
||||||
|
`${templateRepoUrlBase}/${dirname}` +
|
||||||
|
'&project-name=payload-project' +
|
||||||
|
'&env=PAYLOAD_SECRET' +
|
||||||
|
'&build-command=pnpm run ci' +
|
||||||
|
'&stores=[{"type":"blob"}]' + // Vercel Blob Storage
|
||||||
|
'&integration-ids=oac_jnzmjqM10gllKmSrG0SGrHOH', // MongoDB Atlas
|
||||||
|
),
|
||||||
|
envNames: {
|
||||||
|
dbUri: 'MONGODB_URI',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'blank',
|
||||||
|
dirname: 'blank',
|
||||||
|
db: 'mongodb',
|
||||||
|
storage: 'localDisk',
|
||||||
|
sharp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'payload-cloud-mongodb-template',
|
||||||
|
dirname: 'with-payload-cloud',
|
||||||
|
db: 'mongodb',
|
||||||
|
storage: 'payloadCloud',
|
||||||
|
sharp: true,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const {
|
||||||
|
name,
|
||||||
|
dirname,
|
||||||
|
db,
|
||||||
|
storage,
|
||||||
|
vercelDeployButtonLink,
|
||||||
|
envNames,
|
||||||
|
sharp,
|
||||||
|
} of variations) {
|
||||||
|
console.log(`Generating ${name}...`)
|
||||||
|
const destDir = path.join(templatesDir, dirname)
|
||||||
|
copyRecursiveSync(path.join(templatesDir, '_template'), destDir)
|
||||||
|
console.log(`Generated ${name} in ${destDir}`)
|
||||||
|
|
||||||
|
// Configure payload config
|
||||||
|
await configurePayloadConfig({
|
||||||
|
dbType: db,
|
||||||
|
packageJsonName: name,
|
||||||
|
projectDirOrConfigPath: { projectDir: destDir },
|
||||||
|
storageAdapter: storage,
|
||||||
|
sharp,
|
||||||
|
envNames,
|
||||||
|
})
|
||||||
|
|
||||||
|
await generateReadme({
|
||||||
|
destDir,
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
description: name, // TODO: Add descriptions
|
||||||
|
attributes: { db, storage },
|
||||||
|
...(vercelDeployButtonLink && { vercelDeployButtonLink }),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Copy in initial migration if db is postgres. This contains user and media.
|
||||||
|
if (db === 'postgres') {
|
||||||
|
const migrationSrcDir = path.join(templatesDir, '_data/migrations')
|
||||||
|
const migrationDestDir = path.join(destDir, 'src/migrations')
|
||||||
|
|
||||||
|
// Make directory if it doesn't exist
|
||||||
|
if ((await fs.stat(migrationDestDir).catch(() => null)) === null) {
|
||||||
|
await fs.mkdir(migrationDestDir, { recursive: true })
|
||||||
|
}
|
||||||
|
console.log(`Copying migrations from ${migrationSrcDir} to ${migrationDestDir}`)
|
||||||
|
copyRecursiveSync(migrationSrcDir, migrationDestDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Email?
|
||||||
|
|
||||||
|
// TODO: Sharp?
|
||||||
|
|
||||||
|
console.log(`Done configuring payload config for ${destDir}/src/payload.config.ts`)
|
||||||
|
}
|
||||||
|
// TODO: Run prettier manually on the generated files, husky blows up
|
||||||
|
console.log('Running prettier on generated files...')
|
||||||
|
execSync(`pnpm prettier --write templates "*.{js,jsx,ts,tsx}"`)
|
||||||
|
|
||||||
|
console.log('Template generation complete!')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateReadme({
|
||||||
|
destDir,
|
||||||
|
data: { name, description, attributes, vercelDeployButtonLink },
|
||||||
|
}: {
|
||||||
|
destDir: string
|
||||||
|
data: {
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
attributes: Pick<TemplateVariations, 'db' | 'storage'>
|
||||||
|
vercelDeployButtonLink?: string
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
let header = `# ${name}\n`
|
||||||
|
if (vercelDeployButtonLink) {
|
||||||
|
header += `\n[](${vercelDeployButtonLink})`
|
||||||
|
}
|
||||||
|
|
||||||
|
const readmeContent = `${header}
|
||||||
|
|
||||||
|
${description}
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
- **Database**: ${attributes.db}
|
||||||
|
- **Storage Adapter**: ${attributes.storage}
|
||||||
|
`
|
||||||
|
|
||||||
|
const readmePath = path.join(destDir, 'README.md')
|
||||||
|
await fs.writeFile(readmePath, readmeContent)
|
||||||
|
console.log(`Generated README.md in ${readmePath}`)
|
||||||
|
}
|
||||||
375
templates/_data/migrations/initial.json
Normal file
375
templates/_data/migrations/initial.json
Normal file
@@ -0,0 +1,375 @@
|
|||||||
|
{
|
||||||
|
"id": "8146d795-d1a9-49be-857d-4320898b38fb",
|
||||||
|
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||||
|
"version": "5",
|
||||||
|
"dialect": "pg",
|
||||||
|
"tables": {
|
||||||
|
"users": {
|
||||||
|
"name": "users",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"reset_password_token": {
|
||||||
|
"name": "reset_password_token",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"reset_password_expiration": {
|
||||||
|
"name": "reset_password_expiration",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"salt": {
|
||||||
|
"name": "salt",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"hash": {
|
||||||
|
"name": "hash",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"login_attempts": {
|
||||||
|
"name": "login_attempts",
|
||||||
|
"type": "numeric",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"lock_until": {
|
||||||
|
"name": "lock_until",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"users_created_at_idx": {
|
||||||
|
"name": "users_created_at_idx",
|
||||||
|
"columns": ["created_at"],
|
||||||
|
"isUnique": false
|
||||||
|
},
|
||||||
|
"users_email_idx": {
|
||||||
|
"name": "users_email_idx",
|
||||||
|
"columns": ["email"],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"media": {
|
||||||
|
"name": "media",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"alt": {
|
||||||
|
"name": "alt",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"name": "url",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"thumbnail_u_r_l": {
|
||||||
|
"name": "thumbnail_u_r_l",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"filename": {
|
||||||
|
"name": "filename",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"mime_type": {
|
||||||
|
"name": "mime_type",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"filesize": {
|
||||||
|
"name": "filesize",
|
||||||
|
"type": "numeric",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"name": "width",
|
||||||
|
"type": "numeric",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"height": {
|
||||||
|
"name": "height",
|
||||||
|
"type": "numeric",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"focal_x": {
|
||||||
|
"name": "focal_x",
|
||||||
|
"type": "numeric",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"focal_y": {
|
||||||
|
"name": "focal_y",
|
||||||
|
"type": "numeric",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"media_created_at_idx": {
|
||||||
|
"name": "media_created_at_idx",
|
||||||
|
"columns": ["created_at"],
|
||||||
|
"isUnique": false
|
||||||
|
},
|
||||||
|
"media_filename_idx": {
|
||||||
|
"name": "media_filename_idx",
|
||||||
|
"columns": ["filename"],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"payload_preferences": {
|
||||||
|
"name": "payload_preferences",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "jsonb",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"payload_preferences_key_idx": {
|
||||||
|
"name": "payload_preferences_key_idx",
|
||||||
|
"columns": ["key"],
|
||||||
|
"isUnique": false
|
||||||
|
},
|
||||||
|
"payload_preferences_created_at_idx": {
|
||||||
|
"name": "payload_preferences_created_at_idx",
|
||||||
|
"columns": ["created_at"],
|
||||||
|
"isUnique": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"payload_preferences_rels": {
|
||||||
|
"name": "payload_preferences_rels",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"order": {
|
||||||
|
"name": "order",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"parent_id": {
|
||||||
|
"name": "parent_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"name": "path",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"users_id": {
|
||||||
|
"name": "users_id",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"payload_preferences_rels_order_idx": {
|
||||||
|
"name": "payload_preferences_rels_order_idx",
|
||||||
|
"columns": ["order"],
|
||||||
|
"isUnique": false
|
||||||
|
},
|
||||||
|
"payload_preferences_rels_parent_idx": {
|
||||||
|
"name": "payload_preferences_rels_parent_idx",
|
||||||
|
"columns": ["parent_id"],
|
||||||
|
"isUnique": false
|
||||||
|
},
|
||||||
|
"payload_preferences_rels_path_idx": {
|
||||||
|
"name": "payload_preferences_rels_path_idx",
|
||||||
|
"columns": ["path"],
|
||||||
|
"isUnique": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {
|
||||||
|
"payload_preferences_rels_parent_fk": {
|
||||||
|
"name": "payload_preferences_rels_parent_fk",
|
||||||
|
"tableFrom": "payload_preferences_rels",
|
||||||
|
"tableTo": "payload_preferences",
|
||||||
|
"columnsFrom": ["parent_id"],
|
||||||
|
"columnsTo": ["id"],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"payload_preferences_rels_users_fk": {
|
||||||
|
"name": "payload_preferences_rels_users_fk",
|
||||||
|
"tableFrom": "payload_preferences_rels",
|
||||||
|
"tableTo": "users",
|
||||||
|
"columnsFrom": ["users_id"],
|
||||||
|
"columnsTo": ["id"],
|
||||||
|
"onDelete": "cascade",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
},
|
||||||
|
"payload_migrations": {
|
||||||
|
"name": "payload_migrations",
|
||||||
|
"schema": "",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "serial",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"batch": {
|
||||||
|
"name": "batch",
|
||||||
|
"type": "numeric",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamp(3) with time zone",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"default": "now()"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"payload_migrations_created_at_idx": {
|
||||||
|
"name": "payload_migrations_created_at_idx",
|
||||||
|
"columns": ["created_at"],
|
||||||
|
"isUnique": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"_meta": {
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {},
|
||||||
|
"columns": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
93
templates/_data/migrations/initial.ts
Normal file
93
templates/_data/migrations/initial.ts
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import type { MigrateDownArgs, MigrateUpArgs } from '@payloadcms/db-postgres'
|
||||||
|
|
||||||
|
import { sql } from '@payloadcms/db-postgres'
|
||||||
|
|
||||||
|
export async function up({ payload }: MigrateUpArgs): Promise<void> {
|
||||||
|
await payload.db.drizzle.execute(sql`
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "users" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"email" varchar NOT NULL,
|
||||||
|
"reset_password_token" varchar,
|
||||||
|
"reset_password_expiration" timestamp(3) with time zone,
|
||||||
|
"salt" varchar,
|
||||||
|
"hash" varchar,
|
||||||
|
"login_attempts" numeric,
|
||||||
|
"lock_until" timestamp(3) with time zone
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "media" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"alt" varchar NOT NULL,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"url" varchar,
|
||||||
|
"thumbnail_u_r_l" varchar,
|
||||||
|
"filename" varchar,
|
||||||
|
"mime_type" varchar,
|
||||||
|
"filesize" numeric,
|
||||||
|
"width" numeric,
|
||||||
|
"height" numeric,
|
||||||
|
"focal_x" numeric,
|
||||||
|
"focal_y" numeric
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "payload_preferences" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"key" varchar,
|
||||||
|
"value" jsonb,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "payload_preferences_rels" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"order" integer,
|
||||||
|
"parent_id" integer NOT NULL,
|
||||||
|
"path" varchar NOT NULL,
|
||||||
|
"users_id" integer
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "payload_migrations" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"name" varchar,
|
||||||
|
"batch" numeric,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS "users_created_at_idx" ON "users" ("created_at");
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS "users_email_idx" ON "users" ("email");
|
||||||
|
CREATE INDEX IF NOT EXISTS "media_created_at_idx" ON "media" ("created_at");
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS "media_filename_idx" ON "media" ("filename");
|
||||||
|
CREATE INDEX IF NOT EXISTS "payload_preferences_key_idx" ON "payload_preferences" ("key");
|
||||||
|
CREATE INDEX IF NOT EXISTS "payload_preferences_created_at_idx" ON "payload_preferences" ("created_at");
|
||||||
|
CREATE INDEX IF NOT EXISTS "payload_preferences_rels_order_idx" ON "payload_preferences_rels" ("order");
|
||||||
|
CREATE INDEX IF NOT EXISTS "payload_preferences_rels_parent_idx" ON "payload_preferences_rels" ("parent_id");
|
||||||
|
CREATE INDEX IF NOT EXISTS "payload_preferences_rels_path_idx" ON "payload_preferences_rels" ("path");
|
||||||
|
CREATE INDEX IF NOT EXISTS "payload_migrations_created_at_idx" ON "payload_migrations" ("created_at");
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_preferences_rels" ADD CONSTRAINT "payload_preferences_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "payload_preferences"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_preferences_rels" ADD CONSTRAINT "payload_preferences_rels_users_fk" FOREIGN KEY ("users_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down({ payload }: MigrateDownArgs): Promise<void> {
|
||||||
|
await payload.db.drizzle.execute(sql`
|
||||||
|
|
||||||
|
DROP TABLE "users";
|
||||||
|
DROP TABLE "media";
|
||||||
|
DROP TABLE "payload_preferences";
|
||||||
|
DROP TABLE "payload_preferences_rels";
|
||||||
|
DROP TABLE "payload_migrations";`)
|
||||||
|
}
|
||||||
2
templates/_template/.env.example
Normal file
2
templates/_template/.env.example
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
DATABASE_URI=mongodb://127.0.0.1/payload-template-blank-3-0
|
||||||
|
PAYLOAD_SECRET=YOUR_SECRET_HERE
|
||||||
8
templates/_template/.eslintrc.cjs
Normal file
8
templates/_template/.eslintrc.cjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/** @type {import('eslint').Linter.Config} */
|
||||||
|
module.exports = {
|
||||||
|
extends: ['next/core-web-vitals'],
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.json'],
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
|
}
|
||||||
43
templates/_template/.gitignore
vendored
Normal file
43
templates/_template/.gitignore
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
.yarn/install-state.gz
|
||||||
|
|
||||||
|
/.idea/*
|
||||||
|
!/.idea/runConfigurations
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|
||||||
|
.env
|
||||||
|
|
||||||
|
/media
|
||||||
6
templates/_template/.prettierrc.json
Normal file
6
templates/_template/.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"printWidth": 100,
|
||||||
|
"semi": false
|
||||||
|
}
|
||||||
1
templates/_template/.yarnrc
Normal file
1
templates/_template/.yarnrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--install.ignore-engines true
|
||||||
69
templates/_template/Dockerfile
Normal file
69
templates/_template/Dockerfile
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# From https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile
|
||||||
|
|
||||||
|
FROM node:18-alpine AS base
|
||||||
|
|
||||||
|
# Install dependencies only when needed
|
||||||
|
FROM base AS deps
|
||||||
|
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies based on the preferred package manager
|
||||||
|
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
||||||
|
elif [ -f package-lock.json ]; then npm ci; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Rebuild the source code only when needed
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Next.js collects completely anonymous telemetry data about general usage.
|
||||||
|
# Learn more here: https://nextjs.org/telemetry
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn run build; \
|
||||||
|
elif [ -f package-lock.json ]; then npm run build; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
|
||||||
|
# Set the correct permission for prerender cache
|
||||||
|
RUN mkdir .next
|
||||||
|
RUN chown nextjs:nodejs .next
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENV PORT 3000
|
||||||
|
|
||||||
|
# server.js is created by next build from the standalone output
|
||||||
|
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
|
||||||
|
CMD HOSTNAME="0.0.0.0" node server.js
|
||||||
42
templates/_template/README.md
Normal file
42
templates/_template/README.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Payload Blank Template
|
||||||
|
|
||||||
|
A blank template for [Payload](https://github.com/payloadcms/payload) to help you get up and running quickly. This repo may have been created by running `npx create-payload-app@latest` and selecting the "blank" template or by cloning this template on [Payload Cloud](https://payloadcms.com/new/clone/blank).
|
||||||
|
|
||||||
|
See the official [Examples Directory](https://github.com/payloadcms/payload/tree/main/examples) for details on how to use Payload in a variety of different ways.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
To spin up the project locally, follow these steps:
|
||||||
|
|
||||||
|
1. First clone the repo
|
||||||
|
1. Then `cd YOUR_PROJECT_REPO && cp .env.example .env`
|
||||||
|
1. Next `yarn && yarn dev` (or `docker-compose up`, see [Docker](#docker))
|
||||||
|
1. Now `open http://localhost:3000/admin` to access the admin panel
|
||||||
|
1. Create your first admin user using the form on the page
|
||||||
|
|
||||||
|
That's it! Changes made in `./src` will be reflected in your app.
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
Alternatively, you can use [Docker](https://www.docker.com) to spin up this project locally. To do so, follow these steps:
|
||||||
|
|
||||||
|
1. Follow [steps 1 and 2 from above](#development), the docker-compose file will automatically use the `.env` file in your project root
|
||||||
|
1. Next run `docker-compose up`
|
||||||
|
1. Follow [steps 4 and 5 from above](#development) to login and create your first admin user
|
||||||
|
|
||||||
|
That's it! The Docker instance will help you get up and running quickly while also standardizing the development environment across your teams.
|
||||||
|
|
||||||
|
## Production
|
||||||
|
|
||||||
|
To run Payload in production, you need to build and serve the Admin panel. To do so, follow these steps:
|
||||||
|
|
||||||
|
1. First invoke the `payload build` script by running `yarn build` or `npm run build` in your project root. This creates a `./build` directory with a production-ready admin bundle.
|
||||||
|
1. Then run `yarn serve` or `npm run serve` to run Node in production and serve Payload from the `./build` directory.
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
|
||||||
|
The easiest way to deploy your project is to use [Payload Cloud](https://payloadcms.com/new/import), a one-click hosting solution to deploy production-ready instances of your Payload apps directly from your GitHub repo. You can also deploy your app manually, check out the [deployment documentation](https://payloadcms.com/docs/production/deployment) for full details.
|
||||||
|
|
||||||
|
## Questions
|
||||||
|
|
||||||
|
If you have any issues or questions, reach out to us on [Discord](https://discord.com/invite/payload) or start a [GitHub discussion](https://github.com/payloadcms/payload/discussions).
|
||||||
43
templates/_template/docker-compose.yml
Normal file
43
templates/_template/docker-compose.yml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
payload:
|
||||||
|
image: node:18-alpine
|
||||||
|
ports:
|
||||||
|
- '3000:3000'
|
||||||
|
volumes:
|
||||||
|
- .:/home/node/app
|
||||||
|
- node_modules:/home/node/app/node_modules
|
||||||
|
working_dir: /home/node/app/
|
||||||
|
command: sh -c "corepack enable && corepack prepare pnpm@latest --activate && pnpm install && pnpm dev"
|
||||||
|
depends_on:
|
||||||
|
- mongo
|
||||||
|
# - postgres
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
# Ensure your DATABASE_URI uses 'mongo' as the hostname ie. mongodb://mongo/my-db-name
|
||||||
|
mongo:
|
||||||
|
image: mongo:latest
|
||||||
|
ports:
|
||||||
|
- '27017:27017'
|
||||||
|
command:
|
||||||
|
- --storageEngine=wiredTiger
|
||||||
|
volumes:
|
||||||
|
- data:/data/db
|
||||||
|
logging:
|
||||||
|
driver: none
|
||||||
|
|
||||||
|
# Uncomment the following to use postgres
|
||||||
|
# postgres:
|
||||||
|
# restart: always
|
||||||
|
# image: postgres:latest
|
||||||
|
# volumes:
|
||||||
|
# - pgdata:/var/lib/postgresql/data
|
||||||
|
# ports:
|
||||||
|
# - "5432:5432"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
data:
|
||||||
|
# pgdata:
|
||||||
|
node_modules:
|
||||||
8
templates/_template/next.config.mjs
Normal file
8
templates/_template/next.config.mjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { withPayload } from '@payloadcms/next/withPayload'
|
||||||
|
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
// Your Next.js config here
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withPayload(nextConfig)
|
||||||
51
templates/_template/package.json
Normal file
51
templates/_template/package.json
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"name": "template-blank-3.0",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A blank template to get started with Payload 3.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
|
||||||
|
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||||
|
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||||
|
"generate:types": "payload generate:types",
|
||||||
|
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
|
||||||
|
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
|
||||||
|
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@payloadcms/db-mongodb": "beta",
|
||||||
|
"@payloadcms/next": "beta",
|
||||||
|
"@payloadcms/plugin-cloud": "beta",
|
||||||
|
"@payloadcms/richtext-lexical": "beta",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"graphql": "^16.8.1",
|
||||||
|
"next": "15.0.0-rc.0",
|
||||||
|
"payload": "beta",
|
||||||
|
"react": "^19.0.0-rc-f994737d14-20240522",
|
||||||
|
"react-dom": "^19.0.0-rc-f994737d14-20240522",
|
||||||
|
"sharp": "0.32.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.12.12",
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-config-next": "^14.2.3",
|
||||||
|
"typescript": "^5.4.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.20.2 || >=20.6.0"
|
||||||
|
},
|
||||||
|
"pnpm": {
|
||||||
|
"overrides": {
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
import type { Metadata } from 'next'
|
||||||
|
|
||||||
|
import config from '@payload-config'
|
||||||
|
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||||
|
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
params: {
|
||||||
|
segments: string[]
|
||||||
|
}
|
||||||
|
searchParams: {
|
||||||
|
[key: string]: string | string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||||
|
generatePageMetadata({ config, params, searchParams })
|
||||||
|
|
||||||
|
const NotFound = ({ params, searchParams }: Args) => NotFoundPage({ config, params, searchParams })
|
||||||
|
|
||||||
|
export default NotFound
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
import type { Metadata } from 'next'
|
||||||
|
|
||||||
|
import config from '@payload-config'
|
||||||
|
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||||
|
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
params: {
|
||||||
|
segments: string[]
|
||||||
|
}
|
||||||
|
searchParams: {
|
||||||
|
[key: string]: string | string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||||
|
generatePageMetadata({ config, params, searchParams })
|
||||||
|
|
||||||
|
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
|
||||||
|
|
||||||
|
export default Page
|
||||||
10
templates/_template/src/app/(payload)/api/[...slug]/route.ts
Normal file
10
templates/_template/src/app/(payload)/api/[...slug]/route.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||||
|
import config from '@payload-config'
|
||||||
|
import { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST } from '@payloadcms/next/routes'
|
||||||
|
|
||||||
|
export const GET = REST_GET(config)
|
||||||
|
export const POST = REST_POST(config)
|
||||||
|
export const DELETE = REST_DELETE(config)
|
||||||
|
export const PATCH = REST_PATCH(config)
|
||||||
|
export const OPTIONS = REST_OPTIONS(config)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||||
|
import config from '@payload-config'
|
||||||
|
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||||
|
|
||||||
|
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||||
|
import config from '@payload-config'
|
||||||
|
import { GRAPHQL_POST } from '@payloadcms/next/routes'
|
||||||
|
|
||||||
|
export const POST = GRAPHQL_POST(config)
|
||||||
0
templates/_template/src/app/(payload)/custom.scss
Normal file
0
templates/_template/src/app/(payload)/custom.scss
Normal file
16
templates/_template/src/app/(payload)/layout.tsx
Normal file
16
templates/_template/src/app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
import configPromise from '@payload-config'
|
||||||
|
import '@payloadcms/next/css'
|
||||||
|
import { RootLayout } from '@payloadcms/next/layouts'
|
||||||
|
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import './custom.scss'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
children: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
|
||||||
|
|
||||||
|
export default Layout
|
||||||
14
templates/_template/src/app/my-route/route.ts
Normal file
14
templates/_template/src/app/my-route/route.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import configPromise from '@payload-config'
|
||||||
|
import { getPayload } from 'payload'
|
||||||
|
|
||||||
|
export const GET = async () => {
|
||||||
|
const payload = await getPayload({
|
||||||
|
config: configPromise,
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = await payload.find({
|
||||||
|
collection: 'users',
|
||||||
|
})
|
||||||
|
|
||||||
|
return Response.json(data)
|
||||||
|
}
|
||||||
16
templates/_template/src/collections/Media.ts
Normal file
16
templates/_template/src/collections/Media.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { CollectionConfig } from 'payload/types'
|
||||||
|
|
||||||
|
export const Media: CollectionConfig = {
|
||||||
|
slug: 'media',
|
||||||
|
access: {
|
||||||
|
read: () => true,
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'alt',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
upload: true,
|
||||||
|
}
|
||||||
13
templates/_template/src/collections/Users.ts
Normal file
13
templates/_template/src/collections/Users.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import type { CollectionConfig } from 'payload/types'
|
||||||
|
|
||||||
|
export const Users: CollectionConfig = {
|
||||||
|
slug: 'users',
|
||||||
|
admin: {
|
||||||
|
useAsTitle: 'email',
|
||||||
|
},
|
||||||
|
auth: true,
|
||||||
|
fields: [
|
||||||
|
// Email added by default
|
||||||
|
// Add more fields as needed
|
||||||
|
],
|
||||||
|
}
|
||||||
34
templates/_template/src/payload.config.ts
Normal file
34
templates/_template/src/payload.config.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// storage-adapter-import-placeholder
|
||||||
|
import { mongooseAdapter } from '@payloadcms/db-mongodb' // database-adapter-import
|
||||||
|
import { lexicalEditor } from '@payloadcms/richtext-lexical'
|
||||||
|
import path from 'path'
|
||||||
|
import { buildConfig } from 'payload/config'
|
||||||
|
import { fileURLToPath } from 'url'
|
||||||
|
import sharp from 'sharp'
|
||||||
|
|
||||||
|
import { Users } from './collections/Users'
|
||||||
|
import { Media } from './collections/Media'
|
||||||
|
|
||||||
|
const filename = fileURLToPath(import.meta.url)
|
||||||
|
const dirname = path.dirname(filename)
|
||||||
|
|
||||||
|
export default buildConfig({
|
||||||
|
admin: {
|
||||||
|
user: Users.slug,
|
||||||
|
},
|
||||||
|
collections: [Users, Media],
|
||||||
|
editor: lexicalEditor(),
|
||||||
|
secret: process.env.PAYLOAD_SECRET || '',
|
||||||
|
typescript: {
|
||||||
|
outputFile: path.resolve(dirname, 'payload-types.ts'),
|
||||||
|
},
|
||||||
|
// database-adapter-config-start
|
||||||
|
db: mongooseAdapter({
|
||||||
|
url: process.env.DATABASE_URI || '',
|
||||||
|
}),
|
||||||
|
// database-adapter-config-end
|
||||||
|
sharp,
|
||||||
|
plugins: [
|
||||||
|
// storage-adapter-placeholder
|
||||||
|
],
|
||||||
|
})
|
||||||
44
templates/_template/tsconfig.json
Normal file
44
templates/_template/tsconfig.json
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./src/*"
|
||||||
|
],
|
||||||
|
"@payload-config": [
|
||||||
|
"./src/payload.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"target": "ES2017"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
||||||
16
templates/blank-3.0/src/collections/Media.ts
Normal file
16
templates/blank-3.0/src/collections/Media.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { CollectionConfig } from 'payload/types'
|
||||||
|
|
||||||
|
export const Media: CollectionConfig = {
|
||||||
|
slug: 'media',
|
||||||
|
access: {
|
||||||
|
read: () => true,
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'alt',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
upload: true,
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
|
// storage-adapter-import-placeholder
|
||||||
import { mongooseAdapter } from '@payloadcms/db-mongodb' // database-adapter-import
|
import { mongooseAdapter } from '@payloadcms/db-mongodb' // database-adapter-import
|
||||||
// import { payloadCloud } from '@payloadcms/plugin-cloud'
|
|
||||||
import { lexicalEditor } from '@payloadcms/richtext-lexical'
|
import { lexicalEditor } from '@payloadcms/richtext-lexical'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { buildConfig } from 'payload/config'
|
import { buildConfig } from 'payload/config'
|
||||||
// import sharp from 'sharp'
|
|
||||||
import { fileURLToPath } from 'url'
|
import { fileURLToPath } from 'url'
|
||||||
|
import sharp from 'sharp'
|
||||||
|
|
||||||
import { Users } from './collections/Users'
|
import { Users } from './collections/Users'
|
||||||
|
import { Media } from './collections/Media'
|
||||||
|
|
||||||
const filename = fileURLToPath(import.meta.url)
|
const filename = fileURLToPath(import.meta.url)
|
||||||
const dirname = path.dirname(filename)
|
const dirname = path.dirname(filename)
|
||||||
@@ -15,9 +16,8 @@ export default buildConfig({
|
|||||||
admin: {
|
admin: {
|
||||||
user: Users.slug,
|
user: Users.slug,
|
||||||
},
|
},
|
||||||
collections: [Users],
|
collections: [Users, Media],
|
||||||
editor: lexicalEditor({}),
|
editor: lexicalEditor(),
|
||||||
// plugins: [payloadCloud()], // TODO: Re-enable when cloud supports 3.0
|
|
||||||
secret: process.env.PAYLOAD_SECRET || '',
|
secret: process.env.PAYLOAD_SECRET || '',
|
||||||
typescript: {
|
typescript: {
|
||||||
outputFile: path.resolve(dirname, 'payload-types.ts'),
|
outputFile: path.resolve(dirname, 'payload-types.ts'),
|
||||||
@@ -27,13 +27,8 @@ export default buildConfig({
|
|||||||
url: process.env.DATABASE_URI || '',
|
url: process.env.DATABASE_URI || '',
|
||||||
}),
|
}),
|
||||||
// database-adapter-config-end
|
// database-adapter-config-end
|
||||||
|
sharp,
|
||||||
// Sharp is now an optional dependency -
|
plugins: [
|
||||||
// if you want to resize images, crop, set focal point, etc.
|
// storage-adapter-placeholder
|
||||||
// make sure to install it and pass it to the config.
|
],
|
||||||
|
|
||||||
// This is temporary - we may make an adapter pattern
|
|
||||||
// for this before reaching 3.0 stable
|
|
||||||
|
|
||||||
// sharp,
|
|
||||||
})
|
})
|
||||||
|
|||||||
2
templates/blank/.env.example
Normal file
2
templates/blank/.env.example
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
DATABASE_URI=mongodb://127.0.0.1/payload-template-blank-3-0
|
||||||
|
PAYLOAD_SECRET=YOUR_SECRET_HERE
|
||||||
8
templates/blank/.eslintrc.cjs
Normal file
8
templates/blank/.eslintrc.cjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/** @type {import('eslint').Linter.Config} */
|
||||||
|
module.exports = {
|
||||||
|
extends: ['next/core-web-vitals'],
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.json'],
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
|
}
|
||||||
43
templates/blank/.gitignore
vendored
Normal file
43
templates/blank/.gitignore
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
.yarn/install-state.gz
|
||||||
|
|
||||||
|
/.idea/*
|
||||||
|
!/.idea/runConfigurations
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|
||||||
|
.env
|
||||||
|
|
||||||
|
/media
|
||||||
6
templates/blank/.prettierrc.json
Normal file
6
templates/blank/.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"printWidth": 100,
|
||||||
|
"semi": false
|
||||||
|
}
|
||||||
1
templates/blank/.yarnrc
Normal file
1
templates/blank/.yarnrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--install.ignore-engines true
|
||||||
69
templates/blank/Dockerfile
Normal file
69
templates/blank/Dockerfile
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# From https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile
|
||||||
|
|
||||||
|
FROM node:18-alpine AS base
|
||||||
|
|
||||||
|
# Install dependencies only when needed
|
||||||
|
FROM base AS deps
|
||||||
|
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies based on the preferred package manager
|
||||||
|
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
||||||
|
elif [ -f package-lock.json ]; then npm ci; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Rebuild the source code only when needed
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Next.js collects completely anonymous telemetry data about general usage.
|
||||||
|
# Learn more here: https://nextjs.org/telemetry
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn run build; \
|
||||||
|
elif [ -f package-lock.json ]; then npm run build; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
|
||||||
|
# Set the correct permission for prerender cache
|
||||||
|
RUN mkdir .next
|
||||||
|
RUN chown nextjs:nodejs .next
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENV PORT 3000
|
||||||
|
|
||||||
|
# server.js is created by next build from the standalone output
|
||||||
|
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
|
||||||
|
CMD HOSTNAME="0.0.0.0" node server.js
|
||||||
8
templates/blank/README.md
Normal file
8
templates/blank/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# blank
|
||||||
|
|
||||||
|
blank
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
- **Database**: mongodb
|
||||||
|
- **Storage Adapter**: localDisk
|
||||||
43
templates/blank/docker-compose.yml
Normal file
43
templates/blank/docker-compose.yml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
payload:
|
||||||
|
image: node:18-alpine
|
||||||
|
ports:
|
||||||
|
- '3000:3000'
|
||||||
|
volumes:
|
||||||
|
- .:/home/node/app
|
||||||
|
- node_modules:/home/node/app/node_modules
|
||||||
|
working_dir: /home/node/app/
|
||||||
|
command: sh -c "corepack enable && corepack prepare pnpm@latest --activate && pnpm install && pnpm dev"
|
||||||
|
depends_on:
|
||||||
|
- mongo
|
||||||
|
# - postgres
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
# Ensure your DATABASE_URI uses 'mongo' as the hostname ie. mongodb://mongo/my-db-name
|
||||||
|
mongo:
|
||||||
|
image: mongo:latest
|
||||||
|
ports:
|
||||||
|
- '27017:27017'
|
||||||
|
command:
|
||||||
|
- --storageEngine=wiredTiger
|
||||||
|
volumes:
|
||||||
|
- data:/data/db
|
||||||
|
logging:
|
||||||
|
driver: none
|
||||||
|
|
||||||
|
# Uncomment the following to use postgres
|
||||||
|
# postgres:
|
||||||
|
# restart: always
|
||||||
|
# image: postgres:latest
|
||||||
|
# volumes:
|
||||||
|
# - pgdata:/var/lib/postgresql/data
|
||||||
|
# ports:
|
||||||
|
# - "5432:5432"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
data:
|
||||||
|
# pgdata:
|
||||||
|
node_modules:
|
||||||
8
templates/blank/next.config.mjs
Normal file
8
templates/blank/next.config.mjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { withPayload } from '@payloadcms/next/withPayload'
|
||||||
|
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
// Your Next.js config here
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withPayload(nextConfig)
|
||||||
51
templates/blank/package.json
Normal file
51
templates/blank/package.json
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"name": "blank",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A blank template to get started with Payload 3.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
|
||||||
|
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||||
|
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||||
|
"generate:types": "payload generate:types",
|
||||||
|
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
|
||||||
|
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
|
||||||
|
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@payloadcms/db-mongodb": "beta",
|
||||||
|
"@payloadcms/next": "beta",
|
||||||
|
"@payloadcms/plugin-cloud": "beta",
|
||||||
|
"@payloadcms/richtext-lexical": "beta",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"graphql": "^16.8.1",
|
||||||
|
"next": "15.0.0-rc.0",
|
||||||
|
"payload": "beta",
|
||||||
|
"react": "^19.0.0-rc-f994737d14-20240522",
|
||||||
|
"react-dom": "^19.0.0-rc-f994737d14-20240522",
|
||||||
|
"sharp": "0.32.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.12.12",
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-config-next": "^14.2.3",
|
||||||
|
"typescript": "^5.4.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.20.2 || >=20.6.0"
|
||||||
|
},
|
||||||
|
"pnpm": {
|
||||||
|
"overrides": {
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
import type { Metadata } from 'next'
|
||||||
|
|
||||||
|
import config from '@payload-config'
|
||||||
|
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||||
|
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
params: {
|
||||||
|
segments: string[]
|
||||||
|
}
|
||||||
|
searchParams: {
|
||||||
|
[key: string]: string | string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||||
|
generatePageMetadata({ config, params, searchParams })
|
||||||
|
|
||||||
|
const NotFound = ({ params, searchParams }: Args) => NotFoundPage({ config, params, searchParams })
|
||||||
|
|
||||||
|
export default NotFound
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
import type { Metadata } from 'next'
|
||||||
|
|
||||||
|
import config from '@payload-config'
|
||||||
|
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||||
|
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
params: {
|
||||||
|
segments: string[]
|
||||||
|
}
|
||||||
|
searchParams: {
|
||||||
|
[key: string]: string | string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||||
|
generatePageMetadata({ config, params, searchParams })
|
||||||
|
|
||||||
|
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
|
||||||
|
|
||||||
|
export default Page
|
||||||
10
templates/blank/src/app/(payload)/api/[...slug]/route.ts
Normal file
10
templates/blank/src/app/(payload)/api/[...slug]/route.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||||
|
import config from '@payload-config'
|
||||||
|
import { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST } from '@payloadcms/next/routes'
|
||||||
|
|
||||||
|
export const GET = REST_GET(config)
|
||||||
|
export const POST = REST_POST(config)
|
||||||
|
export const DELETE = REST_DELETE(config)
|
||||||
|
export const PATCH = REST_PATCH(config)
|
||||||
|
export const OPTIONS = REST_OPTIONS(config)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||||
|
import config from '@payload-config'
|
||||||
|
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||||
|
|
||||||
|
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||||
6
templates/blank/src/app/(payload)/api/graphql/route.ts
Normal file
6
templates/blank/src/app/(payload)/api/graphql/route.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||||
|
import config from '@payload-config'
|
||||||
|
import { GRAPHQL_POST } from '@payloadcms/next/routes'
|
||||||
|
|
||||||
|
export const POST = GRAPHQL_POST(config)
|
||||||
0
templates/blank/src/app/(payload)/custom.scss
Normal file
0
templates/blank/src/app/(payload)/custom.scss
Normal file
16
templates/blank/src/app/(payload)/layout.tsx
Normal file
16
templates/blank/src/app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
import configPromise from '@payload-config'
|
||||||
|
import '@payloadcms/next/css'
|
||||||
|
import { RootLayout } from '@payloadcms/next/layouts'
|
||||||
|
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import './custom.scss'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
children: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
|
||||||
|
|
||||||
|
export default Layout
|
||||||
14
templates/blank/src/app/my-route/route.ts
Normal file
14
templates/blank/src/app/my-route/route.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import configPromise from '@payload-config'
|
||||||
|
import { getPayload } from 'payload'
|
||||||
|
|
||||||
|
export const GET = async () => {
|
||||||
|
const payload = await getPayload({
|
||||||
|
config: configPromise,
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = await payload.find({
|
||||||
|
collection: 'users',
|
||||||
|
})
|
||||||
|
|
||||||
|
return Response.json(data)
|
||||||
|
}
|
||||||
16
templates/blank/src/collections/Media.ts
Normal file
16
templates/blank/src/collections/Media.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { CollectionConfig } from 'payload/types'
|
||||||
|
|
||||||
|
export const Media: CollectionConfig = {
|
||||||
|
slug: 'media',
|
||||||
|
access: {
|
||||||
|
read: () => true,
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'alt',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
upload: true,
|
||||||
|
}
|
||||||
13
templates/blank/src/collections/Users.ts
Normal file
13
templates/blank/src/collections/Users.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import type { CollectionConfig } from 'payload/types'
|
||||||
|
|
||||||
|
export const Users: CollectionConfig = {
|
||||||
|
slug: 'users',
|
||||||
|
admin: {
|
||||||
|
useAsTitle: 'email',
|
||||||
|
},
|
||||||
|
auth: true,
|
||||||
|
fields: [
|
||||||
|
// Email added by default
|
||||||
|
// Add more fields as needed
|
||||||
|
],
|
||||||
|
}
|
||||||
30
templates/blank/src/payload.config.ts
Normal file
30
templates/blank/src/payload.config.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// storage-adapter-import-placeholder
|
||||||
|
import { mongooseAdapter } from '@payloadcms/db-mongodb'
|
||||||
|
import { lexicalEditor } from '@payloadcms/richtext-lexical'
|
||||||
|
import path from 'path'
|
||||||
|
import { buildConfig } from 'payload/config'
|
||||||
|
import { fileURLToPath } from 'url'
|
||||||
|
import sharp from 'sharp'
|
||||||
|
|
||||||
|
import { Users } from './collections/Users'
|
||||||
|
import { Media } from './collections/Media'
|
||||||
|
|
||||||
|
const filename = fileURLToPath(import.meta.url)
|
||||||
|
const dirname = path.dirname(filename)
|
||||||
|
|
||||||
|
export default buildConfig({
|
||||||
|
admin: {
|
||||||
|
user: Users.slug,
|
||||||
|
},
|
||||||
|
collections: [Users, Media],
|
||||||
|
editor: lexicalEditor(),
|
||||||
|
secret: process.env.PAYLOAD_SECRET || '',
|
||||||
|
typescript: {
|
||||||
|
outputFile: path.resolve(dirname, 'payload-types.ts'),
|
||||||
|
},
|
||||||
|
db: mongooseAdapter({
|
||||||
|
url: process.env.DATABASE_URI || '',
|
||||||
|
}),
|
||||||
|
sharp,
|
||||||
|
plugins: [],
|
||||||
|
})
|
||||||
44
templates/blank/tsconfig.json
Normal file
44
templates/blank/tsconfig.json
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./src/*"
|
||||||
|
],
|
||||||
|
"@payload-config": [
|
||||||
|
"./src/payload.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"target": "ES2017"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { withPayload } from '@payloadcms/next/withPayload'
|
import { withPayload } from '@payloadcms/next/withPayload'
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {};
|
const nextConfig = {}
|
||||||
|
|
||||||
export default withPayload(nextConfig);
|
export default withPayload(nextConfig)
|
||||||
|
|||||||
5353
templates/vercel-postgres/pnpm-lock.yaml
generated
5353
templates/vercel-postgres/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -3,4 +3,4 @@ module.exports = {
|
|||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
autoprefixer: {},
|
autoprefixer: {},
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { MigrateDownArgs, MigrateUpArgs} from '@payloadcms/db-postgres';
|
import type { MigrateDownArgs, MigrateUpArgs } from '@payloadcms/db-postgres'
|
||||||
|
|
||||||
import { sql } from '@payloadcms/db-postgres'
|
import { sql } from '@payloadcms/db-postgres'
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
import type { Config } from "tailwindcss";
|
import type { Config } from 'tailwindcss'
|
||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
content: [
|
content: [
|
||||||
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||||
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||||
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
backgroundImage: {
|
backgroundImage: {
|
||||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||||
"gradient-conic":
|
'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
||||||
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
};
|
}
|
||||||
export default config;
|
export default config
|
||||||
|
|||||||
2
templates/with-payload-cloud/.env.example
Normal file
2
templates/with-payload-cloud/.env.example
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
DATABASE_URI=mongodb://127.0.0.1/payload-template-blank-3-0
|
||||||
|
PAYLOAD_SECRET=YOUR_SECRET_HERE
|
||||||
8
templates/with-payload-cloud/.eslintrc.cjs
Normal file
8
templates/with-payload-cloud/.eslintrc.cjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/** @type {import('eslint').Linter.Config} */
|
||||||
|
module.exports = {
|
||||||
|
extends: ['next/core-web-vitals'],
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.json'],
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
|
}
|
||||||
43
templates/with-payload-cloud/.gitignore
vendored
Normal file
43
templates/with-payload-cloud/.gitignore
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
.yarn/install-state.gz
|
||||||
|
|
||||||
|
/.idea/*
|
||||||
|
!/.idea/runConfigurations
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|
||||||
|
.env
|
||||||
|
|
||||||
|
/media
|
||||||
6
templates/with-payload-cloud/.prettierrc.json
Normal file
6
templates/with-payload-cloud/.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"printWidth": 100,
|
||||||
|
"semi": false
|
||||||
|
}
|
||||||
1
templates/with-payload-cloud/.yarnrc
Normal file
1
templates/with-payload-cloud/.yarnrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--install.ignore-engines true
|
||||||
69
templates/with-payload-cloud/Dockerfile
Normal file
69
templates/with-payload-cloud/Dockerfile
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# From https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile
|
||||||
|
|
||||||
|
FROM node:18-alpine AS base
|
||||||
|
|
||||||
|
# Install dependencies only when needed
|
||||||
|
FROM base AS deps
|
||||||
|
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies based on the preferred package manager
|
||||||
|
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
||||||
|
elif [ -f package-lock.json ]; then npm ci; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Rebuild the source code only when needed
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Next.js collects completely anonymous telemetry data about general usage.
|
||||||
|
# Learn more here: https://nextjs.org/telemetry
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn run build; \
|
||||||
|
elif [ -f package-lock.json ]; then npm run build; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
|
||||||
|
# Set the correct permission for prerender cache
|
||||||
|
RUN mkdir .next
|
||||||
|
RUN chown nextjs:nodejs .next
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENV PORT 3000
|
||||||
|
|
||||||
|
# server.js is created by next build from the standalone output
|
||||||
|
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
|
||||||
|
CMD HOSTNAME="0.0.0.0" node server.js
|
||||||
8
templates/with-payload-cloud/README.md
Normal file
8
templates/with-payload-cloud/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# payload-cloud-mongodb-template
|
||||||
|
|
||||||
|
payload-cloud-mongodb-template
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
- **Database**: mongodb
|
||||||
|
- **Storage Adapter**: payloadCloud
|
||||||
43
templates/with-payload-cloud/docker-compose.yml
Normal file
43
templates/with-payload-cloud/docker-compose.yml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
payload:
|
||||||
|
image: node:18-alpine
|
||||||
|
ports:
|
||||||
|
- '3000:3000'
|
||||||
|
volumes:
|
||||||
|
- .:/home/node/app
|
||||||
|
- node_modules:/home/node/app/node_modules
|
||||||
|
working_dir: /home/node/app/
|
||||||
|
command: sh -c "corepack enable && corepack prepare pnpm@latest --activate && pnpm install && pnpm dev"
|
||||||
|
depends_on:
|
||||||
|
- mongo
|
||||||
|
# - postgres
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
# Ensure your DATABASE_URI uses 'mongo' as the hostname ie. mongodb://mongo/my-db-name
|
||||||
|
mongo:
|
||||||
|
image: mongo:latest
|
||||||
|
ports:
|
||||||
|
- '27017:27017'
|
||||||
|
command:
|
||||||
|
- --storageEngine=wiredTiger
|
||||||
|
volumes:
|
||||||
|
- data:/data/db
|
||||||
|
logging:
|
||||||
|
driver: none
|
||||||
|
|
||||||
|
# Uncomment the following to use postgres
|
||||||
|
# postgres:
|
||||||
|
# restart: always
|
||||||
|
# image: postgres:latest
|
||||||
|
# volumes:
|
||||||
|
# - pgdata:/var/lib/postgresql/data
|
||||||
|
# ports:
|
||||||
|
# - "5432:5432"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
data:
|
||||||
|
# pgdata:
|
||||||
|
node_modules:
|
||||||
8
templates/with-payload-cloud/next.config.mjs
Normal file
8
templates/with-payload-cloud/next.config.mjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { withPayload } from '@payloadcms/next/withPayload'
|
||||||
|
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
// Your Next.js config here
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withPayload(nextConfig)
|
||||||
51
templates/with-payload-cloud/package.json
Normal file
51
templates/with-payload-cloud/package.json
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"name": "payload-cloud-mongodb-template",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A blank template to get started with Payload 3.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
|
||||||
|
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||||
|
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||||
|
"generate:types": "payload generate:types",
|
||||||
|
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
|
||||||
|
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
|
||||||
|
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@payloadcms/db-mongodb": "beta",
|
||||||
|
"@payloadcms/next": "beta",
|
||||||
|
"@payloadcms/plugin-cloud": "beta",
|
||||||
|
"@payloadcms/richtext-lexical": "beta",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"graphql": "^16.8.1",
|
||||||
|
"next": "15.0.0-rc.0",
|
||||||
|
"payload": "beta",
|
||||||
|
"react": "^19.0.0-rc-f994737d14-20240522",
|
||||||
|
"react-dom": "^19.0.0-rc-f994737d14-20240522",
|
||||||
|
"sharp": "0.32.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.12.12",
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-config-next": "^14.2.3",
|
||||||
|
"typescript": "^5.4.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.20.2 || >=20.6.0"
|
||||||
|
},
|
||||||
|
"pnpm": {
|
||||||
|
"overrides": {
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
9812
templates/with-payload-cloud/pnpm-lock.yaml
generated
Normal file
9812
templates/with-payload-cloud/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
import type { Metadata } from 'next'
|
||||||
|
|
||||||
|
import config from '@payload-config'
|
||||||
|
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||||
|
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
params: {
|
||||||
|
segments: string[]
|
||||||
|
}
|
||||||
|
searchParams: {
|
||||||
|
[key: string]: string | string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||||
|
generatePageMetadata({ config, params, searchParams })
|
||||||
|
|
||||||
|
const NotFound = ({ params, searchParams }: Args) => NotFoundPage({ config, params, searchParams })
|
||||||
|
|
||||||
|
export default NotFound
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
import type { Metadata } from 'next'
|
||||||
|
|
||||||
|
import config from '@payload-config'
|
||||||
|
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||||
|
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
params: {
|
||||||
|
segments: string[]
|
||||||
|
}
|
||||||
|
searchParams: {
|
||||||
|
[key: string]: string | string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||||
|
generatePageMetadata({ config, params, searchParams })
|
||||||
|
|
||||||
|
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
|
||||||
|
|
||||||
|
export default Page
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||||
|
import config from '@payload-config'
|
||||||
|
import { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST } from '@payloadcms/next/routes'
|
||||||
|
|
||||||
|
export const GET = REST_GET(config)
|
||||||
|
export const POST = REST_POST(config)
|
||||||
|
export const DELETE = REST_DELETE(config)
|
||||||
|
export const PATCH = REST_PATCH(config)
|
||||||
|
export const OPTIONS = REST_OPTIONS(config)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||||
|
import config from '@payload-config'
|
||||||
|
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||||
|
|
||||||
|
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||||
|
import config from '@payload-config'
|
||||||
|
import { GRAPHQL_POST } from '@payloadcms/next/routes'
|
||||||
|
|
||||||
|
export const POST = GRAPHQL_POST(config)
|
||||||
16
templates/with-payload-cloud/src/app/(payload)/layout.tsx
Normal file
16
templates/with-payload-cloud/src/app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||||
|
import configPromise from '@payload-config'
|
||||||
|
import '@payloadcms/next/css'
|
||||||
|
import { RootLayout } from '@payloadcms/next/layouts'
|
||||||
|
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import './custom.scss'
|
||||||
|
|
||||||
|
type Args = {
|
||||||
|
children: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
|
||||||
|
|
||||||
|
export default Layout
|
||||||
14
templates/with-payload-cloud/src/app/my-route/route.ts
Normal file
14
templates/with-payload-cloud/src/app/my-route/route.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import configPromise from '@payload-config'
|
||||||
|
import { getPayload } from 'payload'
|
||||||
|
|
||||||
|
export const GET = async () => {
|
||||||
|
const payload = await getPayload({
|
||||||
|
config: configPromise,
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = await payload.find({
|
||||||
|
collection: 'users',
|
||||||
|
})
|
||||||
|
|
||||||
|
return Response.json(data)
|
||||||
|
}
|
||||||
16
templates/with-payload-cloud/src/collections/Media.ts
Normal file
16
templates/with-payload-cloud/src/collections/Media.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { CollectionConfig } from 'payload/types'
|
||||||
|
|
||||||
|
export const Media: CollectionConfig = {
|
||||||
|
slug: 'media',
|
||||||
|
access: {
|
||||||
|
read: () => true,
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'alt',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
upload: true,
|
||||||
|
}
|
||||||
13
templates/with-payload-cloud/src/collections/Users.ts
Normal file
13
templates/with-payload-cloud/src/collections/Users.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import type { CollectionConfig } from 'payload/types'
|
||||||
|
|
||||||
|
export const Users: CollectionConfig = {
|
||||||
|
slug: 'users',
|
||||||
|
admin: {
|
||||||
|
useAsTitle: 'email',
|
||||||
|
},
|
||||||
|
auth: true,
|
||||||
|
fields: [
|
||||||
|
// Email added by default
|
||||||
|
// Add more fields as needed
|
||||||
|
],
|
||||||
|
}
|
||||||
30
templates/with-payload-cloud/src/payload.config.ts
Normal file
30
templates/with-payload-cloud/src/payload.config.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { payloadCloudPlugin } from '@payloadcms/plugin-cloud'
|
||||||
|
import { mongooseAdapter } from '@payloadcms/db-mongodb'
|
||||||
|
import { lexicalEditor } from '@payloadcms/richtext-lexical'
|
||||||
|
import path from 'path'
|
||||||
|
import { buildConfig } from 'payload/config'
|
||||||
|
import { fileURLToPath } from 'url'
|
||||||
|
import sharp from 'sharp'
|
||||||
|
|
||||||
|
import { Users } from './collections/Users'
|
||||||
|
import { Media } from './collections/Media'
|
||||||
|
|
||||||
|
const filename = fileURLToPath(import.meta.url)
|
||||||
|
const dirname = path.dirname(filename)
|
||||||
|
|
||||||
|
export default buildConfig({
|
||||||
|
admin: {
|
||||||
|
user: Users.slug,
|
||||||
|
},
|
||||||
|
collections: [Users, Media],
|
||||||
|
editor: lexicalEditor(),
|
||||||
|
secret: process.env.PAYLOAD_SECRET || '',
|
||||||
|
typescript: {
|
||||||
|
outputFile: path.resolve(dirname, 'payload-types.ts'),
|
||||||
|
},
|
||||||
|
db: mongooseAdapter({
|
||||||
|
url: process.env.DATABASE_URI || '',
|
||||||
|
}),
|
||||||
|
sharp,
|
||||||
|
plugins: [payloadCloudPlugin()],
|
||||||
|
})
|
||||||
44
templates/with-payload-cloud/tsconfig.json
Normal file
44
templates/with-payload-cloud/tsconfig.json
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./src/*"
|
||||||
|
],
|
||||||
|
"@payload-config": [
|
||||||
|
"./src/payload.config.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"target": "ES2017"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
||||||
2
templates/with-vercel-mongodb/.env.example
Normal file
2
templates/with-vercel-mongodb/.env.example
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
DATABASE_URI=mongodb://127.0.0.1/payload-template-blank-3-0
|
||||||
|
PAYLOAD_SECRET=YOUR_SECRET_HERE
|
||||||
8
templates/with-vercel-mongodb/.eslintrc.cjs
Normal file
8
templates/with-vercel-mongodb/.eslintrc.cjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/** @type {import('eslint').Linter.Config} */
|
||||||
|
module.exports = {
|
||||||
|
extends: ['next/core-web-vitals'],
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.json'],
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
},
|
||||||
|
}
|
||||||
43
templates/with-vercel-mongodb/.gitignore
vendored
Normal file
43
templates/with-vercel-mongodb/.gitignore
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
.yarn/install-state.gz
|
||||||
|
|
||||||
|
/.idea/*
|
||||||
|
!/.idea/runConfigurations
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|
||||||
|
.env
|
||||||
|
|
||||||
|
/media
|
||||||
6
templates/with-vercel-mongodb/.prettierrc.json
Normal file
6
templates/with-vercel-mongodb/.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"printWidth": 100,
|
||||||
|
"semi": false
|
||||||
|
}
|
||||||
1
templates/with-vercel-mongodb/.yarnrc
Normal file
1
templates/with-vercel-mongodb/.yarnrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--install.ignore-engines true
|
||||||
69
templates/with-vercel-mongodb/Dockerfile
Normal file
69
templates/with-vercel-mongodb/Dockerfile
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# From https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile
|
||||||
|
|
||||||
|
FROM node:18-alpine AS base
|
||||||
|
|
||||||
|
# Install dependencies only when needed
|
||||||
|
FROM base AS deps
|
||||||
|
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies based on the preferred package manager
|
||||||
|
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
||||||
|
elif [ -f package-lock.json ]; then npm ci; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Rebuild the source code only when needed
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Next.js collects completely anonymous telemetry data about general usage.
|
||||||
|
# Learn more here: https://nextjs.org/telemetry
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn run build; \
|
||||||
|
elif [ -f package-lock.json ]; then npm run build; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
|
||||||
|
# Set the correct permission for prerender cache
|
||||||
|
RUN mkdir .next
|
||||||
|
RUN chown nextjs:nodejs .next
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENV PORT 3000
|
||||||
|
|
||||||
|
# server.js is created by next build from the standalone output
|
||||||
|
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
|
||||||
|
CMD HOSTNAME="0.0.0.0" node server.js
|
||||||
10
templates/with-vercel-mongodb/README.md
Normal file
10
templates/with-vercel-mongodb/README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# payload-vercel-mongodb-template
|
||||||
|
|
||||||
|
[](https://vercel.com/new/clone?repository-url=https://github.com/payloadcms/payload/tree/beta/templates//Users/elliot/dev/core/scripts&project-name=payload-project&env=PAYLOAD_SECRET&build-command=pnpm%20run%20ci&stores=%5B%7B%22type%22:%22blob%22%7D%5D&integration-ids=oac_jnzmjqM10gllKmSrG0SGrHOH)
|
||||||
|
|
||||||
|
payload-vercel-mongodb-template
|
||||||
|
|
||||||
|
## Attributes
|
||||||
|
|
||||||
|
- **Database**: mongodb
|
||||||
|
- **Storage Adapter**: vercelBlobStorage
|
||||||
43
templates/with-vercel-mongodb/docker-compose.yml
Normal file
43
templates/with-vercel-mongodb/docker-compose.yml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
payload:
|
||||||
|
image: node:18-alpine
|
||||||
|
ports:
|
||||||
|
- '3000:3000'
|
||||||
|
volumes:
|
||||||
|
- .:/home/node/app
|
||||||
|
- node_modules:/home/node/app/node_modules
|
||||||
|
working_dir: /home/node/app/
|
||||||
|
command: sh -c "corepack enable && corepack prepare pnpm@latest --activate && pnpm install && pnpm dev"
|
||||||
|
depends_on:
|
||||||
|
- mongo
|
||||||
|
# - postgres
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
# Ensure your DATABASE_URI uses 'mongo' as the hostname ie. mongodb://mongo/my-db-name
|
||||||
|
mongo:
|
||||||
|
image: mongo:latest
|
||||||
|
ports:
|
||||||
|
- '27017:27017'
|
||||||
|
command:
|
||||||
|
- --storageEngine=wiredTiger
|
||||||
|
volumes:
|
||||||
|
- data:/data/db
|
||||||
|
logging:
|
||||||
|
driver: none
|
||||||
|
|
||||||
|
# Uncomment the following to use postgres
|
||||||
|
# postgres:
|
||||||
|
# restart: always
|
||||||
|
# image: postgres:latest
|
||||||
|
# volumes:
|
||||||
|
# - pgdata:/var/lib/postgresql/data
|
||||||
|
# ports:
|
||||||
|
# - "5432:5432"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
data:
|
||||||
|
# pgdata:
|
||||||
|
node_modules:
|
||||||
8
templates/with-vercel-mongodb/next.config.mjs
Normal file
8
templates/with-vercel-mongodb/next.config.mjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { withPayload } from '@payloadcms/next/withPayload'
|
||||||
|
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
// Your Next.js config here
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withPayload(nextConfig)
|
||||||
51
templates/with-vercel-mongodb/package.json
Normal file
51
templates/with-vercel-mongodb/package.json
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"name": "payload-vercel-mongodb-template",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A blank template to get started with Payload 3.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
|
||||||
|
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||||
|
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||||
|
"generate:types": "payload generate:types",
|
||||||
|
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
|
||||||
|
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
|
||||||
|
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@payloadcms/db-mongodb": "beta",
|
||||||
|
"@payloadcms/next": "beta",
|
||||||
|
"@payloadcms/plugin-cloud": "beta",
|
||||||
|
"@payloadcms/richtext-lexical": "beta",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"graphql": "^16.8.1",
|
||||||
|
"next": "15.0.0-rc.0",
|
||||||
|
"payload": "beta",
|
||||||
|
"react": "^19.0.0-rc-f994737d14-20240522",
|
||||||
|
"react-dom": "^19.0.0-rc-f994737d14-20240522",
|
||||||
|
"@payloadcms/storage-vercel-blob": "beta"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.12.12",
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-config-next": "^14.2.3",
|
||||||
|
"typescript": "^5.4.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.20.2 || >=20.6.0"
|
||||||
|
},
|
||||||
|
"pnpm": {
|
||||||
|
"overrides": {
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"@types/react": "npm:types-react@19.0.0-beta.2",
|
||||||
|
"@types/react-dom": "npm:types-react-dom@19.0.0-beta.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user