Compare commits

..

1 Commits

Author SHA1 Message Date
Paul
b76844dac9 templates: set packageManager pnpm version for vercel templates (#11992)
There have been issues with deploying our templates to Vercel when we
rely on `engines.pnpm` configuration.

Vercel's deployments work best when we specify a `packageManager` in
`package.json` since we ship our templates without lockfiles that would
help Vercel determine the right package manager to use.

This PR adjusts the script so that it adds a `packageManager` with the
latest version of `pnpm` to our Vercel templates and removes the
`engines.pnpm` only for those variants.
2025-04-04 18:30:04 +01:00
9 changed files with 97 additions and 148 deletions

View File

@@ -68,9 +68,9 @@
"tailwindcss": "^3.4.3",
"typescript": "5.7.3"
},
"packageManager": "pnpm@10.3.0",
"engines": {
"node": "^18.20.2 || >=20.9.0"
"node": "^18.20.2 || >=20.9.0",
"pnpm": "^9"
},
"pnpm": {
"onlyBuiltDependencies": [

View File

@@ -6,27 +6,27 @@
"type": "module",
"scripts": {
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"ci": "payload migrate && pnpm build",
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
"generate:types": "cross-env NODE_OPTIONS=--no-deprecation 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",
"ci": "payload migrate && pnpm build"
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
},
"dependencies": {
"@payloadcms/next": "3.31.0",
"@payloadcms/payload-cloud": "3.31.0",
"@payloadcms/richtext-lexical": "3.31.0",
"@payloadcms/db-postgres": "3.32.0",
"@payloadcms/next": "3.32.0",
"@payloadcms/payload-cloud": "3.32.0",
"@payloadcms/richtext-lexical": "3.32.0",
"cross-env": "^7.0.3",
"graphql": "^16.8.1",
"next": "15.2.3",
"payload": "3.31.0",
"payload": "3.32.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"sharp": "0.32.6",
"@payloadcms/db-postgres": "3.31.0"
"sharp": "0.32.6"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",

View File

@@ -6,27 +6,27 @@
"type": "module",
"scripts": {
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"ci": "payload migrate && pnpm build",
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
"generate:types": "cross-env NODE_OPTIONS=--no-deprecation 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",
"ci": "payload migrate && pnpm build"
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
},
"dependencies": {
"@payloadcms/next": "3.31.0",
"@payloadcms/payload-cloud": "3.31.0",
"@payloadcms/richtext-lexical": "3.31.0",
"@payloadcms/db-vercel-postgres": "3.32.0",
"@payloadcms/next": "3.32.0",
"@payloadcms/payload-cloud": "3.32.0",
"@payloadcms/richtext-lexical": "3.32.0",
"@payloadcms/storage-vercel-blob": "3.32.0",
"cross-env": "^7.0.3",
"graphql": "^16.8.1",
"next": "15.2.3",
"payload": "3.31.0",
"payload": "3.32.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"@payloadcms/db-vercel-postgres": "3.31.0",
"@payloadcms/storage-vercel-blob": "3.31.0"
"react-dom": "19.0.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
@@ -38,9 +38,9 @@
"prettier": "^3.4.2",
"typescript": "5.7.3"
},
"packageManager": "pnpm@10.7.1",
"engines": {
"node": "^18.20.2 || >=20.9.0",
"pnpm": "^9"
"node": "^18.20.2 || >=20.9.0"
},
"pnpm": {
"onlyBuiltDependencies": [

View File

@@ -7,6 +7,7 @@
"scripts": {
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"postbuild": "next-sitemap --config next-sitemap.config.cjs",
"ci": "payload migrate && pnpm build",
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"dev:prod": "cross-env NODE_OPTIONS=--no-deprecation rm -rf .next && pnpm build && pnpm start",
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
@@ -16,21 +17,22 @@
"lint:fix": "cross-env NODE_OPTIONS=--no-deprecation next lint --fix",
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
"reinstall": "cross-env NODE_OPTIONS=--no-deprecation rm -rf node_modules && rm pnpm-lock.yaml && pnpm --ignore-workspace install",
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
"ci": "payload migrate && pnpm build"
"start": "cross-env NODE_OPTIONS=--no-deprecation next start"
},
"dependencies": {
"@payloadcms/admin-bar": "3.31.0",
"@payloadcms/live-preview-react": "3.31.0",
"@payloadcms/next": "3.31.0",
"@payloadcms/payload-cloud": "3.31.0",
"@payloadcms/plugin-form-builder": "3.31.0",
"@payloadcms/plugin-nested-docs": "3.31.0",
"@payloadcms/plugin-redirects": "3.31.0",
"@payloadcms/plugin-search": "3.31.0",
"@payloadcms/plugin-seo": "3.31.0",
"@payloadcms/richtext-lexical": "3.31.0",
"@payloadcms/ui": "3.31.0",
"@payloadcms/admin-bar": "3.32.0",
"@payloadcms/db-vercel-postgres": "3.32.0",
"@payloadcms/live-preview-react": "3.32.0",
"@payloadcms/next": "3.32.0",
"@payloadcms/payload-cloud": "3.32.0",
"@payloadcms/plugin-form-builder": "3.32.0",
"@payloadcms/plugin-nested-docs": "3.32.0",
"@payloadcms/plugin-redirects": "3.32.0",
"@payloadcms/plugin-search": "3.32.0",
"@payloadcms/plugin-seo": "3.32.0",
"@payloadcms/richtext-lexical": "3.32.0",
"@payloadcms/storage-vercel-blob": "3.32.0",
"@payloadcms/ui": "3.32.0",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-select": "^2.0.0",
@@ -43,16 +45,14 @@
"lucide-react": "^0.378.0",
"next": "15.2.3",
"next-sitemap": "^4.2.3",
"payload": "3.31.0",
"payload": "3.32.0",
"prism-react-renderer": "^2.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-hook-form": "7.45.4",
"sharp": "0.32.6",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"@payloadcms/db-vercel-postgres": "3.31.0",
"@payloadcms/storage-vercel-blob": "3.31.0"
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
@@ -70,7 +70,7 @@
"tailwindcss": "^3.4.3",
"typescript": "5.7.3"
},
"packageManager": "pnpm@10.3.0",
"packageManager": "pnpm@10.7.1",
"engines": {
"node": "^18.20.2 || >=20.9.0"
},

View File

@@ -604,63 +604,6 @@ export default buildConfigWithDefaults({
},
],
},
{
slug: 'array-default-id',
versions: { drafts: true },
fields: [
{
type: 'tabs',
tabs: [
{
label: 'General',
fields: [
{
name: 'name',
type: 'text',
required: true,
},
],
},
{
label: 'Content',
fields: [
// ...
{
name: 'myItems',
labels: {
singular: 'item',
plural: 'items',
},
type: 'array',
required: false,
defaultValue: Array(4).fill({ name: '', description: '' }),
fields: [
{
name: 'name',
type: 'text',
required: true,
},
{
name: 'description',
type: 'text',
required: true,
},
],
},
],
},
// ...
],
},
// {
// name: 'array',
// type: 'array',
// fields: [{ type: 'text', name: 'text' }],
// defaultValue: Array(100).fill({ text: 'text-1' }),
// // defaultValue: Array.from({ length: 4 }, () => ({ text: 'text-1' })),
// },
],
},
],
globals: [
{

View File

@@ -1627,18 +1627,6 @@ describe('database', () => {
expect(result.select).toStrictEqual('default')
expect(result.point).toStrictEqual({ coordinates: [10, 20], type: 'Point' })
})
it('defaultValue should work with arrays', async () => {
const res_1 = await payload.create({ draft: true, collection: 'array-default-id', data: {} })
expect(res_1.array).toHaveLength(4)
expect(res_1.array[0]?.text).toBe('text-1')
expect(res_1.array[1]?.text).toBe('text-1')
// const res_2 = await payload.create({ draft: true, collection: 'array-default-id', data: {} })
// expect(res_2.array).toHaveLength(2)
// expect(res_2.array[0]?.text).toBe('text-1')
// expect(res_2.array[1]?.text).toBe('text-2')
})
})
describe('Schema generation', () => {

View File

@@ -80,7 +80,6 @@ export interface Config {
'fake-custom-ids': FakeCustomId;
'relationships-migration': RelationshipsMigration;
'compound-indexes': CompoundIndex;
'array-default-id': ArrayDefaultId;
users: User;
'payload-locked-documents': PayloadLockedDocument;
'payload-preferences': PayloadPreference;
@@ -101,7 +100,6 @@ export interface Config {
'fake-custom-ids': FakeCustomIdsSelect<false> | FakeCustomIdsSelect<true>;
'relationships-migration': RelationshipsMigrationSelect<false> | RelationshipsMigrationSelect<true>;
'compound-indexes': CompoundIndexesSelect<false> | CompoundIndexesSelect<true>;
'array-default-id': ArrayDefaultIdSelect<false> | ArrayDefaultIdSelect<true>;
users: UsersSelect<false> | UsersSelect<true>;
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
@@ -421,21 +419,6 @@ export interface CompoundIndex {
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "array-default-id".
*/
export interface ArrayDefaultId {
id: string;
array?:
| {
text?: string | null;
id?: string | null;
}[]
| null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users".
@@ -512,10 +495,6 @@ export interface PayloadLockedDocument {
relationTo: 'compound-indexes';
value: string | CompoundIndex;
} | null)
| ({
relationTo: 'array-default-id';
value: string | ArrayDefaultId;
} | null)
| ({
relationTo: 'users';
value: string | User;
@@ -816,20 +795,6 @@ export interface CompoundIndexesSelect<T extends boolean = true> {
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "array-default-id_select".
*/
export interface ArrayDefaultIdSelect<T extends boolean = true> {
array?:
| T
| {
text?: T;
id?: T;
};
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users_select".

View File

@@ -45,6 +45,13 @@ type TemplateVariation = {
skipReadme?: boolean
storage: StorageAdapterType
vercelDeployButtonLink?: string
/**
* Identify where this template is intended to be deployed.
* Useful for making some modifications like PNPM's engines config for Vercel.
*
* @default 'default'
*/
targetDeployment?: 'default' | 'vercel'
}
main().catch((error) => {
@@ -72,6 +79,7 @@ async function main() {
sharp: false,
skipDockerCompose: true,
storage: 'vercelBlobStorage',
targetDeployment: 'vercel',
vercelDeployButtonLink:
`https://vercel.com/new/clone?repository-url=` +
encodeURI(
@@ -95,6 +103,7 @@ async function main() {
skipDockerCompose: true,
skipReadme: true,
storage: 'vercelBlobStorage',
targetDeployment: 'vercel',
vercelDeployButtonLink:
`https://vercel.com/new/clone?repository-url=` +
encodeURI(
@@ -122,6 +131,7 @@ async function main() {
},
sharp: false,
storage: 'vercelBlobStorage',
targetDeployment: 'vercel',
vercelDeployButtonLink:
`https://vercel.com/new/clone?repository-url=` +
encodeURI(
@@ -186,6 +196,7 @@ async function main() {
skipReadme = false,
storage,
vercelDeployButtonLink,
targetDeployment = 'default',
} = variation
header(`Generating ${name}...`)
@@ -239,12 +250,12 @@ async function main() {
}
// Fetch latest npm version of payload package:
const version = await getLatestPayloadVersion()
const payloadVersion = await getLatestPackageVersion({ packageName: 'payload' })
// Bump package.json versions
await bumpPackageJson({
templateDir: destDir,
latestVersion: version,
latestVersion: payloadVersion,
})
if (generateLockfile) {
@@ -284,6 +295,13 @@ async function main() {
})
}
if (targetDeployment) {
await handleDeploymentTarget({
targetDeployment,
destDir,
})
}
// Generate importmap
log('Generating import map')
execSyncSafe(`pnpm --ignore-workspace generate:importmap`, { cwd: destDir })
@@ -337,6 +355,30 @@ ${description}
log('Generated README.md')
}
async function handleDeploymentTarget({
targetDeployment,
destDir,
}: {
targetDeployment: TemplateVariation['targetDeployment']
destDir: string
}) {
if (targetDeployment === 'vercel') {
// Add Vercel specific settings to package.json
const packageJsonPath = path.join(destDir, 'package.json')
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'))
if (packageJson.engines?.pnpm) {
delete packageJson.engines.pnpm
}
const pnpmVersion = await getLatestPackageVersion({ packageName: 'pnpm' })
packageJson.packageManager = `pnpm@${pnpmVersion}`
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2))
}
}
async function writeEnvExample({
dbType,
destDir,
@@ -450,9 +492,20 @@ async function bumpPackageJson({
)
}
async function getLatestPayloadVersion() {
async function getLatestPackageVersion({
packageName = 'payload',
}: {
/**
* Package name to fetch the latest version for based on the NPM registry URL
*
* Eg. for `'payload'`, it will fetch the version from `https://registry.npmjs.org/payload`
*
* @default 'payload'
*/
packageName?: string
}) {
try {
const response = await fetch('https://registry.npmjs.org/payload')
const response = await fetch(`https://registry.npmjs.org/${packageName}`)
const data = await response.json()
const latestVersion = data['dist-tags'].latest

View File

@@ -31,7 +31,7 @@
}
],
"paths": {
"@payload-config": ["./test/database/config.ts"],
"@payload-config": ["./test/_community/config.ts"],
"@payloadcms/admin-bar": ["./packages/admin-bar/src"],
"@payloadcms/live-preview": ["./packages/live-preview/src"],
"@payloadcms/live-preview-react": ["./packages/live-preview-react/src/index.ts"],