Compare commits

..

30 Commits

Author SHA1 Message Date
Elliot DeNolf
5bba969f0d chore(release): v3.0.0-beta.19 [skip ci] 2024-04-26 17:08:50 -04:00
Jarrod Flesch
3a43fd34c0 chore: fixes bad auto import (#6070) 2024-04-26 16:45:24 -04:00
Jarrod Flesch
d9005b3f53 chore: file uploads, broken import path (#6069) 2024-04-26 16:26:11 -04:00
Jarrod Flesch
fab9e32175 fix: correct createPayloadRequest routeParams (#6059) 2024-04-26 16:13:21 -04:00
Jarrod Flesch
e71c1c2ec4 fix: formData handling on Vercel (#6067) 2024-04-26 16:10:14 -04:00
Dan Ribbens
81fb0515fb fix: bulk publish from collection list (#6065) 2024-04-26 15:46:02 -04:00
Elliot DeNolf
739dfc1434 chore: convert all errors to named exports (#6061) 2024-04-26 13:24:18 -04:00
Jacob Fletcher
a4e8795666 fix(deps): dedupes react (#6064) 2024-04-26 13:22:12 -04:00
Elliot DeNolf
14134d637d fix: properly handle external file url (#6060) 2024-04-26 12:02:07 -04:00
Elliot DeNolf
2b698a9018 chore: add more valid pr scopes [skip ci] 2024-04-26 11:55:01 -04:00
Elliot DeNolf
91684c8a7d ci: app build with packed (#6051) 2024-04-26 00:19:44 -04:00
Elliot DeNolf
fbdfe1d9dd chore: set -ex on pack and build step 2024-04-25 23:56:16 -04:00
Elliot DeNolf
7221725121 chore: start mongo for build 2024-04-25 23:46:48 -04:00
Elliot DeNolf
640348df3a chore: use --ignore-workspace in template install 2024-04-25 23:37:05 -04:00
Elliot DeNolf
4ed99e017a ci: add app-build-with-packed job 2024-04-25 23:28:28 -04:00
Elliot DeNolf
df6b9dd30b ci(scripts): update pack-all-to-dest 2024-04-25 23:25:31 -04:00
Elliot DeNolf
faf142baff chore: sort package.json files (#6050) 2024-04-25 22:41:55 -04:00
Elliot DeNolf
f80cb9f553 chore: clean up package.json descriptions and keywords 2024-04-25 22:39:03 -04:00
Elliot DeNolf
d3eaa1fceb chore: add sort-package-json to lint-staged 2024-04-25 22:23:58 -04:00
Elliot DeNolf
df77152851 chore: add sort-package-json, sort all package.json files 2024-04-25 22:19:37 -04:00
Elliot DeNolf
937202b27c fix(deps): remove monorepo deps 2024-04-25 22:12:44 -04:00
Paul
3581f39c31 chore: update whitelabel example (#6049) 2024-04-25 17:24:42 -03:00
Paul
c1d9c81b68 chore: update virtual fields example (#6043) 2024-04-25 16:13:10 -03:00
Jarrod Flesch
20355a4dd4 fix: version restoration (#6040) 2024-04-25 14:15:12 -04:00
Elliot DeNolf
cf66d7f09b docs: new packages (#6041) 2024-04-25 13:14:52 -04:00
Elliot DeNolf
30afe81462 docs: add docs for all new storage packages 2024-04-25 13:08:32 -04:00
Elliot DeNolf
18ee6e8867 docs: add docs for email-nodemailer 2024-04-25 13:08:18 -04:00
Paul
9f78a93403 chore: update hierarchy example (#6036) 2024-04-25 12:54:17 -03:00
Dan Ribbens
bd046e2437 fix(db-postgres): use locales suffix (#6032) 2024-04-25 11:07:52 -04:00
Elliot DeNolf
e9004a93a4 ci(scripts): safer package details retrieval 2024-04-25 10:50:41 -04:00
167 changed files with 18781 additions and 16707 deletions

View File

@@ -294,6 +294,50 @@ jobs:
if-no-files-found: ignore
retention-days: 1
app-build-with-packed:
runs-on: ubuntu-latest
needs: build
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: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0
with:
mongodb-version: 6.0
- name: Pack and build app
run: |
set -ex
pnpm run script:pack --dest templates/blank-3.0
cd templates/blank-3.0
cp .env.example .env
ls -la
pnpm add ./*.tgz
pnpm install --ignore-workspace
cat package.json
pnpm run build
tests-type-generation:
if: false # This should be replaced with gen on a real Payload project
runs-on: ubuntu-latest

View File

@@ -50,6 +50,7 @@ jobs:
plugin-form-builder
plugin-nested-docs
plugin-redirects
plugin-relationship-object-ids
plugin-search
plugin-sentry
plugin-seo
@@ -66,6 +67,7 @@ jobs:
ui
templates
examples
deps
# Disallow uppercase letters at the beginning of the subject
subjectPattern: ^(?![A-Z]).+$

View File

@@ -1,2 +1,2 @@
DATABASE_URI=mongodb://127.0.0.1/payload-template-blank
DATABASE_URI=mongodb://127.0.0.1/payload-template-blank-3-0
PAYLOAD_SECRET=YOUR_SECRET_HERE

View File

@@ -0,0 +1,7 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
},
}

View File

@@ -1,6 +1,43 @@
build
dist
/media
node_modules
# 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

View File

@@ -1,8 +0,0 @@
module.exports = {
printWidth: 100,
parser: 'typescript',
semi: false,
singleQuote: true,
trailingComma: 'all',
arrowParens: 'avoid',
}

View File

@@ -0,0 +1,6 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"semi": false
}

View File

@@ -1,8 +1,10 @@
# Payload Hierarchy Example
# Payload Blank Template
This example demonstrates how to achieve a virtual hierarchy between documents in your [Payload](https://github.com/payloadcms/payload) application.
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).
## Quick Start
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:
@@ -14,33 +16,15 @@ To spin up the project locally, follow these steps:
That's it! Changes made in `./src` will be reflected in your app.
## How it works
### Docker
This example achieves parent/child relationships between your documents through the use of virtual fields. When you query a document with the `?children=true` query param, an afterRead hook is used to populate the documents within its own tree.
Alternatively, you can use [Docker](https://www.docker.com) to spin up this project locally. To do so, follow these steps:
For more information on how virtual fields, see the [Official Virtual Fields Example](https://github.com/payloadcms/payload/tree/main/examples/virtual-fields).
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
### Collections
See the [Collections](https://payloadcms.com/docs/configuration/collections) docs for details on how to extend any of this functionality.
- #### Users
The `users` collection is a default payload users collection.
- #### Entities
The `entities` collection can define a parent as any other entity. It has a virtual field that will also populate children when it is called via the API using a query `children=true`. See [Virtual Fields](https://github.com/payloadcms/payload/tree/main/examples/virtual-fields) for more details on how virtual fields work.
The virtual field retrieves __all__ children which includes other entities and people.
- #### People
The `people` collection is a collection that can define an array of parent entities. It also has an allocation field. This is for demonstrating attaching data to a parent-child relationship.
## Development
To spin up this example locally, follow the [Quick Start](#quick-start).
That's it! The Docker instance will help you get up and running quickly while also standardizing the development environment across your teams.
## Production

View 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)

View File

@@ -2,34 +2,38 @@
"name": "hierarchy",
"description": "A hierarchy example with Payload",
"version": "1.0.0",
"main": "dist/server.js",
"license": "MIT",
"type": "module",
"scripts": {
"dev": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts nodemon",
"build:payload": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload build",
"build:server": "tsc",
"build": "yarn copyfiles && yarn build:payload && yarn build:server",
"serve": "cross-env PAYLOAD_CONFIG_PATH=dist/payload.config.js NODE_ENV=production node dist/server.js",
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png}\" dist/",
"generate:types": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:types",
"generate:graphQLSchema": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:graphQLSchema",
"payload": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload"
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
"generate:types": "payload generate:types"
},
"engines": {
"node": ">=18.19.0"
},
"dependencies": {
"@payloadcms/bundler-webpack": "^1.0.0",
"@payloadcms/db-mongodb": "^1.0.0",
"@payloadcms/plugin-cloud": "^3.0.0",
"@payloadcms/richtext-slate": "^1.0.0",
"@payloadcms/db-mongodb": "beta",
"@payloadcms/next": "beta",
"@payloadcms/plugin-cloud": "beta",
"@payloadcms/richtext-lexical": "beta",
"cross-env": "^7.0.3",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"payload": "^2.0.0"
"next": "14.3.0-canary.7",
"payload": "beta",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sharp": "0.32.6"
},
"devDependencies": {
"@types/express": "^4.17.9",
"copyfiles": "^2.4.1",
"nodemon": "^2.0.6",
"ts-node": "^9.1.1",
"typescript": "^4.8.4"
"@types/node": "^20.11.25",
"@types/react": "^18.2.64",
"@types/react-dom": "^18.2.21",
"dotenv": "^16.4.5",
"tsx": "^4.7.1",
"typescript": "^5.4.2"
}
}

5880
examples/hierarchy/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
import config from '@payload-config'
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import { RootPage } from '@payloadcms/next/views'
type Args = {
params: {
segments: string[]
}
searchParams: {
[key: string]: string | string[]
}
}
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
export default Page

View File

@@ -0,0 +1,9 @@
/* 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_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)

View 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_PLAYGROUND_GET } from '@payloadcms/next/routes'
export const GET = GRAPHQL_PLAYGROUND_GET(config)

View 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)

View 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

View File

@@ -1,4 +1,4 @@
import { CollectionConfig } from 'payload/types'
import type { CollectionConfig } from 'payload/types'
export const Entities: CollectionConfig = {
slug: 'entities',
@@ -18,7 +18,6 @@ export const Entities: CollectionConfig = {
{
name: 'children',
type: 'relationship',
relationTo: ['entities', 'people'],
access: {
create: () => false,
update: () => false,
@@ -26,40 +25,40 @@ export const Entities: CollectionConfig = {
hooks: {
afterRead: [
async ({ data, req }) => {
if (!req.query.children || !data) return
const { id } = data
if (!req.query.children) return
const people = await req.payload.find({
req,
collection: 'people',
depth: 0,
limit: 0,
pagination: false,
req,
where: {
'parents.parent': { equals: id },
},
limit: 0,
depth: 0,
pagination: false,
})
const entities = await req.payload.find({
req,
collection: 'entities',
depth: 0,
limit: 0,
pagination: false,
req,
where: {
parent: { equals: id },
},
limit: 0,
depth: 0,
pagination: false,
})
return [
...entities.docs.map(entity => {
...entities.docs.map((entity) => {
return {
relationTo: 'entity',
value: entity,
}
}),
...people.docs.map(person => {
...people.docs.map((person) => {
return {
relationTo: 'people',
value: person,
@@ -69,6 +68,7 @@ export const Entities: CollectionConfig = {
},
],
},
relationTo: ['entities', 'people'],
},
{
name: 'parent',

View File

@@ -1,4 +1,4 @@
import { CollectionConfig } from 'payload/types'
import type { CollectionConfig } from 'payload/types'
export const People: CollectionConfig = {
slug: 'people',
@@ -23,8 +23,8 @@ export const People: CollectionConfig = {
{
name: 'allocation',
type: 'number',
min: 0,
max: 100,
min: 0,
},
],
},

View File

@@ -1,15 +1,13 @@
import { CollectionConfig } from 'payload/types'
import type { CollectionConfig } from 'payload/types'
const Users: CollectionConfig = {
export const Users: CollectionConfig = {
slug: 'users',
auth: true,
admin: {
useAsTitle: 'email',
},
auth: true,
fields: [
// Email added by default
// Add more fields as needed
],
}
export default Users

View File

@@ -1,30 +1,39 @@
import path from 'path'
import { payloadCloud } from '@payloadcms/plugin-cloud'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { webpackBundler } from '@payloadcms/bundler-webpack'
import { slateEditor } from '@payloadcms/richtext-slate'
// import { payloadCloud } from '@payloadcms/plugin-cloud'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import path from 'path'
import { buildConfig } from 'payload/config'
// import sharp from 'sharp'
import { fileURLToPath } from 'url'
import Users from './collections/Users'
import { Entities } from './collections/Entities'
import { People } from './collections/People'
import { Users } from './collections/Users'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
export default buildConfig({
admin: {
user: Users.slug,
bundler: webpackBundler(),
},
editor: slateEditor({}),
collections: [Users, Entities, People],
typescript: {
outputFile: path.resolve(__dirname, 'payload-types.ts'),
},
graphQL: {
schemaOutputFile: path.resolve(__dirname, 'generated-schema.graphql'),
},
plugins: [payloadCloud()],
collections: [Entities, People, Users],
editor: lexicalEditor({}),
// plugins: [payloadCloud()], // TODO: Re-enable when cloud supports 3.0
db: mongooseAdapter({
url: process.env.DATABASE_URI,
url: process.env.DATABASE_URI || '',
}),
secret: process.env.PAYLOAD_SECRET || '',
typescript: {
outputFile: path.resolve(dirname, 'payload-types.ts'),
},
// Sharp is now an optional dependency -
// if you want to resize images, crop, set focal point, etc.
// 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,
})

View File

@@ -1,27 +0,0 @@
import express from 'express'
import payload from 'payload'
require('dotenv').config()
const app = express()
// Redirect root to Admin panel
app.get('/', (_, res) => {
res.redirect('/admin')
})
const start = async () => {
// Initialize Payload
await payload.init({
secret: process.env.PAYLOAD_SECRET,
express: app,
onInit: async () => {
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`)
},
})
// Add your own express routes here
app.listen(3000)
}
start()

View File

@@ -1,22 +1,28 @@
{
"compilerOptions": {
"target": "es5",
"baseUrl": ".",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src",
"jsx": "react",
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"payload/generated-types": ["./src/payload-types.ts"]
"@/*": ["./src/*"],
"@payload-config": ["./src/payload.config.ts"]
}
},
"include": ["src"],
"exclude": ["node_modules", "dist", "build"],
"ts-node": {
"transpileOnly": true,
"swc": true
}
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,3 @@
MONGODB_URI=mongodb://127.0.0.1/payload-example-vitual-fields
PAYLOAD_SECRET=ENTER-STRING-HERE
PAYLOAD_PUBLIC_SERVER_URL=http://localhost:8000
DATABASE_URI=mongodb://127.0.0.1/payload-template-blank-3-0
PAYLOAD_SECRET=YOUR_SECRET_HERE
PAYLOAD_PUBLIC_SEED=true

View File

@@ -0,0 +1,7 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
},
}

View File

@@ -1,5 +1,43 @@
build
dist
node_modules
package-lock.json
# 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

View File

@@ -4,26 +4,31 @@
"main": "dist/server.js",
"license": "MIT",
"scripts": {
"dev": "cross-env PAYLOAD_PUBLIC_SEED=true PAYLOAD_DROP_DATABASE=true PAYLOAD_CONFIG_PATH=src/payload.config.ts nodemon",
"build:payload": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload build",
"build:server": "tsc",
"build": "yarn copyfiles && yarn build:payload && yarn build:server",
"serve": "cross-env PAYLOAD_CONFIG_PATH=dist/payload.config.js NODE_ENV=production node dist/server.js",
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png}\" dist/",
"generate:types": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:types",
"generate:graphQLSchema": "PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:graphQLSchema"
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
"generate:types": "payload generate:types"
},
"dependencies": {
"dotenv": "^8.2.0",
"express": "^4.17.1",
"payload": "latest"
"@payloadcms/db-mongodb": "beta",
"@payloadcms/next": "beta",
"@payloadcms/richtext-lexical": "beta",
"cross-env": "^7.0.3",
"next": "^14.3.0-canary.7",
"payload": "beta",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sharp": "0.32.6"
},
"devDependencies": {
"@types/express": "^4.17.9",
"copyfiles": "^2.4.1",
"cross-env": "^7.0.3",
"nodemon": "^2.0.6",
"ts-node": "^9.1.1",
"typescript": "^4.8.4"
"@types/node": "^20.11.25",
"@types/react": "^18.2.64",
"@types/react-dom": "^18.2.21",
"dotenv": "^16.4.5",
"tsx": "^4.7.1",
"typescript": "^5.4.2"
}
}

5184
examples/virtual-fields/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
import config from '@payload-config'
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import { RootPage } from '@payloadcms/next/views'
type Args = {
params: {
segments: string[]
}
searchParams: {
[key: string]: string | string[]
}
}
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
export default Page

View File

@@ -0,0 +1,9 @@
/* 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_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)

View 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_PLAYGROUND_GET } from '@payloadcms/next/routes'
export const GET = GRAPHQL_PLAYGROUND_GET(config)

View 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)

View 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

View File

@@ -1,14 +1,15 @@
import payload from 'payload';
import { CollectionConfig, FieldHook } from 'payload/types';
import type { CollectionConfig, FieldHook } from 'payload/types'
const getTotalPrice: FieldHook = async ({ data }) => {
const { price, salesTaxPercentage, fees } = data.tickets;
const totalPrice = Math.round(price * (1 + (salesTaxPercentage / 100))) + fees;
const getTotalPrice: FieldHook = ({ data }) => {
if (!data) return 0
return totalPrice;
};
const { fees, price, salesTaxPercentage } = data.tickets
const totalPrice = Math.round(price * (1 + salesTaxPercentage / 100)) + fees
const Events: CollectionConfig = {
return totalPrice
}
export const Events: CollectionConfig = {
slug: 'events',
admin: {
defaultColumns: ['title', 'date', 'location'],
@@ -31,9 +32,9 @@ const Events: CollectionConfig = {
{
name: 'location',
type: 'relationship',
relationTo: 'locations',
maxDepth: 0,
hasMany: false,
maxDepth: 0,
relationTo: 'locations',
},
],
},
@@ -82,12 +83,14 @@ const Events: CollectionConfig = {
readOnly: true,
},
hooks: {
beforeChange: [({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.totalPrice = undefined;
}],
afterRead: [getTotalPrice],
beforeChange: [
({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.totalPrice = undefined
},
],
},
},
],
@@ -95,6 +98,4 @@ const Events: CollectionConfig = {
],
},
],
};
export default Events;
}

View File

@@ -1,30 +1,33 @@
/* eslint-disable import/no-extraneous-dependencies */
import payload from 'payload';
import { CollectionConfig, FieldHook } from 'payload/types';
import type { CollectionConfig, FieldHook } from 'payload/types'
const formatLocation: FieldHook = async ({ data }) => {
return `${data.city}${data.state ? `, ${data.state},` : ','} ${data.country}`;
};
const formatLocation: FieldHook = ({ data }) => {
if (!data) return ''
return `${data.city}${data.state ? `, ${data.state},` : ','} ${data.country}`
}
const getLocationStaff: FieldHook = async ({ data }) => {
const staff = await payload.find({
const getLocationStaff: FieldHook = async ({ data, req }) => {
if (!data) return null
const staff = await req.payload.find({
collection: 'staff',
where: {
location: {
equals: data.id,
},
},
});
})
if (staff.docs) {
return staff.docs.map((doc) => doc.id);
return staff.docs.map((doc) => doc.id)
}
return null;
};
return null
}
const getNextEvent: FieldHook = async ({ data }) => {
const eventsByDate = await payload.find({
const getNextEvent: FieldHook = async ({ data, req }) => {
if (!data) return null
const eventsByDate = await req.payload.find({
collection: 'events',
sort: 'date',
where: {
@@ -32,30 +35,32 @@ const getNextEvent: FieldHook = async ({ data }) => {
equals: data.id,
},
},
});
})
if (eventsByDate?.docs) {
return eventsByDate.docs[0]?.id;
return eventsByDate.docs[0]?.id
}
return null;
};
return null
}
const getAllEvents: FieldHook = async ({ data }) => {
const allEvents = await payload.find({
const getAllEvents: FieldHook = async ({ data, req }) => {
if (!data) return null
const allEvents = await req.payload.find({
collection: 'events',
where: {
location: {
equals: data.id,
},
},
});
if (allEvents.docs) return allEvents.docs.map((doc) => doc.id);
})
if (allEvents.docs) return allEvents.docs.map((doc) => doc.id)
return null;
};
return null
}
const Locations: CollectionConfig = {
export const Locations: CollectionConfig = {
slug: 'locations',
admin: {
defaultColumns: ['location', 'nextEvent'],
@@ -64,18 +69,7 @@ const Locations: CollectionConfig = {
fields: [
{
name: 'location',
label: false,
type: 'text',
hooks: {
beforeChange: [({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.location = undefined;
}],
afterRead: [
formatLocation,
],
},
access: {
create: () => false,
update: () => false,
@@ -83,6 +77,17 @@ const Locations: CollectionConfig = {
admin: {
hidden: true,
},
hooks: {
afterRead: [formatLocation],
beforeChange: [
({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.location = undefined
},
],
},
label: false,
},
{
type: 'row',
@@ -105,10 +110,7 @@ const Locations: CollectionConfig = {
},
{
name: 'events',
maxDepth: 0,
type: 'relationship',
relationTo: 'events',
hasMany: true,
access: {
create: () => false,
update: () => false,
@@ -116,21 +118,23 @@ const Locations: CollectionConfig = {
admin: {
readOnly: true,
},
hasMany: true,
hooks: {
beforeChange: [({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.events = undefined;
}],
afterRead: [getAllEvents],
beforeChange: [
({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.events = undefined
},
],
},
maxDepth: 0,
relationTo: 'events',
},
{
name: 'staff',
type: 'relationship',
relationTo: 'staff',
hasMany: true,
maxDepth: 0,
access: {
create: () => false,
update: () => false,
@@ -138,37 +142,42 @@ const Locations: CollectionConfig = {
admin: {
readOnly: true,
},
hasMany: true,
hooks: {
beforeChange: [({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.staff = undefined;
}],
afterRead: [getLocationStaff],
beforeChange: [
({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.staff = undefined
},
],
},
maxDepth: 0,
relationTo: 'staff',
},
{
name: 'nextEvent',
type: 'relationship',
relationTo: 'events',
admin: {
position: 'sidebar',
readOnly: true,
},
access: {
create: () => false,
update: () => false,
},
hooks: {
beforeChange: [({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.nextEvent = undefined;
}],
afterRead: [getNextEvent],
admin: {
position: 'sidebar',
readOnly: true,
},
hooks: {
afterRead: [getNextEvent],
beforeChange: [
({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.nextEvent = undefined
},
],
},
relationTo: 'events',
},
],
};
export default Locations;
}

View File

@@ -1,10 +1,11 @@
import { CollectionConfig, FieldHook } from 'payload/types';
import type { CollectionConfig, FieldHook } from 'payload/types'
const populateFullTitle: FieldHook = async ({ data }) => (
`${data.title} ${data.firstName} ${data.lastName}`
);
const populateFullTitle: FieldHook = ({ data }) => {
if (!data) return ''
return `${data.title} ${data.firstName} ${data.lastName}`
}
const Staff: CollectionConfig = {
export const Staff: CollectionConfig = {
slug: 'staff',
admin: {
defaultColumns: ['fullTitle', 'location'],
@@ -18,19 +19,19 @@ const Staff: CollectionConfig = {
create: () => false,
update: () => false,
},
hooks: {
beforeChange: [({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.fullTitle = undefined;
}],
afterRead: [
populateFullTitle,
],
},
admin: {
hidden: true,
},
hooks: {
afterRead: [populateFullTitle],
beforeChange: [
({ siblingData }) => {
// Mutate the sibling data to prevent DB storage
// eslint-disable-next-line no-param-reassign
siblingData.fullTitle = undefined
},
],
},
},
{
name: 'title',
@@ -50,12 +51,10 @@ const Staff: CollectionConfig = {
{
name: 'location',
type: 'relationship',
relationTo: 'locations',
maxDepth: 0,
hasMany: true,
maxDepth: 0,
relationTo: 'locations',
required: true,
},
],
};
export default Staff;
}

View File

@@ -1,18 +1,16 @@
import { CollectionConfig } from 'payload/types';
import type { CollectionConfig } from 'payload/types'
const Users: CollectionConfig = {
export const Users: CollectionConfig = {
slug: 'users',
auth: true,
admin: {
useAsTitle: 'email',
},
access: {
read: () => true,
},
admin: {
useAsTitle: 'email',
},
auth: true,
fields: [
// Email added by default
// Add more fields as needed
],
};
export default Users;
}

View File

@@ -1,24 +1,16 @@
import React from 'react';
import React from 'react'
const BeforeLogin: React.FC = () => {
export const BeforeLogin: React.FC = () => {
if (process.env.PAYLOAD_PUBLIC_SEED === 'true') {
return (
<div>
<h3>Virtual Fields Demo</h3>
<p>
Log in with the email
{' '}
<strong>dev@payloadcms.com</strong>
{' '}
and the password
{' '}
<strong>test</strong>
.
Log in with the email <strong>dev@payloadcms.com</strong> and the password{' '}
<strong>test</strong>.
</p>
</div>
);
)
}
return null;
};
export default BeforeLogin;
return null
}

View File

@@ -1,29 +1,38 @@
import { buildConfig } from 'payload/config';
import path from 'path';
import Events from './collections/Events';
import Locations from './collections/Location';
import Staff from './collections/Staff';
import Users from './collections/Users';
import BeforeLogin from './components/BeforeLogin';
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 { Events } from './collections/Events'
import { Locations } from './collections/Location'
import { Staff } from './collections/Staff'
import { Users } from './collections/Users'
import { BeforeLogin } from './components/BeforeLogin'
import { seedData } from './seed'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
export default buildConfig({
serverURL: 'http://localhost:3000',
admin: {
user: Users.slug,
components: {
beforeLogin: [BeforeLogin],
},
user: Users.slug,
},
collections: [
Events,
Locations,
Staff,
Users,
],
collections: [Events, Locations, Staff, Users],
editor: lexicalEditor({}),
serverURL: 'http://localhost:3000',
// plugins: [payloadCloud()], // TODO: Re-enable when cloud supports 3.0
db: mongooseAdapter({
url: process.env.DATABASE_URI || '',
}),
onInit: async (payload) => {
await seedData(payload)
},
secret: process.env.PAYLOAD_SECRET || '',
typescript: {
outputFile: path.resolve(__dirname, 'payload-types.ts'),
outputFile: path.resolve(dirname, 'payload-types.ts'),
},
graphQL: {
schemaOutputFile: path.resolve(__dirname, 'generated-schema.graphql'),
},
});
})

View File

@@ -1,45 +1,45 @@
export const eventsOne = [
{
title: 'Event 1',
date: '2023-02-01T00:00:00.000Z',
pricing: {
price: 10,
fees: 5,
price: 10,
},
tickets: {
fees: 3.5,
price: 100,
salesTaxPercentage: 10,
fees: 3.50,
},
title: 'Event 1',
},
{
title: 'Event 2',
date: '2023-03-01T00:00:00.000Z',
tickets: {
fees: 5,
price: 20,
salesTaxPercentage: 20,
fees: 5,
},
title: 'Event 2',
},
];
]
export const eventsTwo = [
{
title: 'Event 3',
date: '2023-03-31T23:00:00.000Z',
tickets: {
fees: 2,
price: 10,
salesTaxPercentage: 10,
fees: 2,
},
title: 'Event 3',
},
{
title: 'Event 4',
date: '2023-04-30T23:00:00.000Z',
tickets: {
fees: 5,
price: 50,
salesTaxPercentage: 10,
fees: 5,
},
title: 'Event 4',
},
];
]

View File

@@ -1,28 +1,27 @@
import payload from 'payload';
import { MongoClient } from 'mongodb';
import { eventsOne, eventsTwo } from './events';
import { locationOne, locationTwo } from './locations';
import { staffOne, staffTwo } from './staff';
import type { Payload } from 'payload'
export async function seedData() {
import { eventsOne, eventsTwo } from './events'
import { locationOne, locationTwo } from './locations'
import { staffOne, staffTwo } from './staff'
export async function seedData(payload: Payload) {
await payload.create({
collection: 'users',
data: {
email: 'dev@payloadcms.com',
password: 'test',
},
});
})
const { id: locationOneID } = await payload.create({
collection: 'locations',
data: locationOne,
});
})
const { id: locationTwoID } = await payload.create({
collection: 'locations',
data: locationTwo,
});
})
await payload.create({
collection: 'staff',
@@ -30,8 +29,7 @@ export async function seedData() {
...staffOne,
location: [locationOneID],
},
});
})
await payload.create({
collection: 'staff',
@@ -39,30 +37,31 @@ export async function seedData() {
...staffTwo,
location: [locationTwoID],
},
});
})
eventsOne.map((event) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
payload.create({
collection: 'events',
data: {
...event,
location: locationOneID,
},
});
return null;
});
})
return null
})
eventsTwo.map((event) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
payload.create({
collection: 'events',
data: {
...event,
location: locationTwoID,
},
});
})
return null;
});
return null
})
}

View File

@@ -1,12 +1,12 @@
export const locationOne = {
city: 'Grand Rapids',
country: 'USA',
state: 'MI',
events: [],
};
state: 'MI',
}
export const locationTwo = {
city: 'London',
country: 'UK',
events: [],
};
}

View File

@@ -1,11 +1,11 @@
export const staffOne = {
title: 'Mr',
firstName: 'John',
lastName: 'Doe',
};
title: 'Mr',
}
export const staffTwo = {
title: 'Miss',
firstName: 'Jane',
lastName: 'Doe',
};
title: 'Miss',
}

View File

@@ -1,37 +0,0 @@
import express from 'express';
import payload from 'payload';
import path from 'path';
import { seedData } from './seed';
require('dotenv').config({
path: path.resolve(__dirname, '../.env'),
});
const app = express();
// Redirect all traffic at root to admin UI
app.get('/', (_, res) => {
res.redirect('/admin');
});
const start = async () => {
// Initialize Payload
await payload.init({
secret: process.env.PAYLOAD_SECRET,
mongoURL: process.env.MONGODB_URI,
express: app,
onInit: async () => {
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`);
},
});
if (process.env.PAYLOAD_PUBLIC_SEED === 'true') {
payload.logger.info('---- SEEDING DATABASE ----');
await seedData();
payload.logger.info('---- SEED COMPLETE ----');
}
app.listen(3000);
};
start();

View File

@@ -1,18 +1,44 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"baseUrl": ".",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src",
"jsx": "react"
"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": ["src"],
"exclude": ["node_modules", "dist", "build"],
"ts-node": {
"transpileOnly": true
}
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}

View File

@@ -1,3 +1,3 @@
MONGODB_URI=mongodb://127.0.0.1/payload-example-whitelabel
DATABASE_URI=mongodb://127.0.0.1/payload-example-whitelabel
PAYLOAD_SECRET=ENTER-STRING-HERE
PAYLOAD_PUBLIC_SERVER_URL=http://localhost:8000

View File

@@ -0,0 +1,7 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
},
}

View 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

View File

@@ -0,0 +1 @@
legacy-peer-deps=true

5
examples/whitelabel/next-env.d.ts vendored Normal file
View File

@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

View File

@@ -1,5 +1,4 @@
{
"$schema": "https://json.schemastore.org/nodemon.json",
"ext": "ts",
"exec": "ts-node src/server.ts -- -I",
"stdin": false

View File

@@ -4,26 +4,31 @@
"main": "dist/server.js",
"license": "MIT",
"scripts": {
"dev": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts nodemon",
"build:payload": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload build",
"build:server": "tsc",
"build": "yarn copyfiles && yarn build:payload && yarn build:server",
"serve": "cross-env PAYLOAD_CONFIG_PATH=dist/payload.config.js NODE_ENV=production node dist/server.js",
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png}\" dist/",
"generate:types": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:types",
"generate:graphQLSchema": "PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:graphQLSchema"
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
"devsafe": "rm -rf .next && cross-env NODE_OPTIONS=--no-deprecation next dev",
"build": "cross-env NODE_OPTIONS=--no-deprecation next build",
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
"generate:types": "payload generate:types"
},
"dependencies": {
"dotenv": "^8.2.0",
"express": "^4.17.1",
"payload": "latest"
"@payloadcms/db-mongodb": "beta",
"@payloadcms/next": "beta",
"@payloadcms/richtext-lexical": "beta",
"cross-env": "^7.0.3",
"next": "^14.3.0-canary.7",
"payload": "beta",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sharp": "0.32.6"
},
"devDependencies": {
"@types/express": "^4.17.9",
"copyfiles": "^2.4.1",
"cross-env": "^7.0.3",
"nodemon": "^2.0.6",
"ts-node": "^9.1.1",
"typescript": "^4.8.4"
"@types/node": "^20.11.25",
"@types/react": "^18.2.64",
"@types/react-dom": "^18.2.21",
"dotenv": "^16.4.5",
"tsx": "^4.7.1",
"typescript": "^5.4.2"
}
}

5184
examples/whitelabel/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 842 B

After

Width:  |  Height:  |  Size: 842 B

View File

Before

Width:  |  Height:  |  Size: 346 KiB

After

Width:  |  Height:  |  Size: 346 KiB

View File

@@ -0,0 +1,17 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
import config from '@payload-config'
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import { RootPage } from '@payloadcms/next/views'
type Args = {
params: {
segments: string[]
}
searchParams: {
[key: string]: string | string[]
}
}
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
export default Page

View File

@@ -0,0 +1,9 @@
/* 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_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)

View 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_PLAYGROUND_GET } from '@payloadcms/next/routes'
export const GET = GRAPHQL_PLAYGROUND_GET(config)

View 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)

View 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

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React from 'react'
const css = `
html[data-theme="dark"] .text {
@@ -13,27 +13,25 @@ const css = `
width: 50px;
height: 50px;
}
`;
`
export const Icon = () => {
return (
<svg
className="graphic-icon"
width="430"
fill="none"
height="435"
viewBox="0 0 430 435"
fill="none"
width="430"
xmlns="http://www.w3.org/2000/svg"
>
<style>
{css}
</style>
<style>{css}</style>
<rect
className="bg"
width="430"
fill="#0C0C0C"
height="434"
transform="translate(0 0.154785)"
fill="#0C0C0C"
width="430"
/>
<path
className="text"
@@ -41,5 +39,5 @@ export const Icon = () => {
fill="white"
/>
</svg>
);
};
)
}

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React from 'react'
const css = `
html[data-theme="dark"] path {
@@ -8,25 +8,20 @@ const css = `
.graphic-logo {
width: 150px;
height: auto;
}`;
}`
export const Logo = () => {
return (
<svg
className="graphic-logo"
xmlns="http://www.w3.org/2000/svg"
fill="#0F0F0F"
viewBox="0 0 518 563"
xmlns="http://www.w3.org/2000/svg"
>
<style type="text/css">
{css}
</style>
<g
transform="translate(0,563) scale(0.1,-0.1)"
fill="#000000"
stroke="none"
>
<path d="M440 3060 l0 -2170 2150 0 2150 0 0 2170 0 2170 -2150 0 -2150 0 0
<style type="text/css">{css}</style>
<g fill="#000000" stroke="none" transform="translate(0,563) scale(0.1,-0.1)">
<path
d="M440 3060 l0 -2170 2150 0 2150 0 0 2170 0 2170 -2150 0 -2150 0 0
-2170z m1855 301 c52 -24 88 -63 117 -126 19 -42 23 -71 26 -182 4 -151 -8
-213 -58 -281 -55 -77 -140 -107 -230 -83 -66 18 -105 53 -141 128 -31 61 -33
74 -37 189 -5 145 16 233 69 298 60 72 169 97 254 57z m766 8 c74 -25 126 -85
@@ -39,15 +34,17 @@ export const Logo = () => {
264 -19 144 13 296 79 366 60 63 167 84 247 47z m-2505 -296 l0 -305 165 0
165 0 0 -35 0 -35 -210 0 -210 0 0 340 0 340 45 0 45 0 0 -305z"
/>
<path d="M2140 3286 c-80 -44 -114 -265 -64 -418 44 -135 193 -147 254 -22 22
<path
d="M2140 3286 c-80 -44 -114 -265 -64 -418 44 -135 193 -147 254 -22 22
44 24 63 24 184 1 122 -2 140 -23 183 -13 26 -36 56 -51 67 -33 23 -102 26
-140 6z"
/>
<path d="M3667 3280 c-14 -11 -36 -41 -49 -68 -20 -42 -23 -61 -23 -177 0
<path
d="M3667 3280 c-14 -11 -36 -41 -49 -68 -20 -42 -23 -61 -23 -177 0
-120 2 -134 27 -187 30 -65 64 -88 129 -88 35 0 48 6 79 38 52 52 63 98 58
257 -3 117 -6 134 -28 173 -14 24 -37 50 -52 58 -40 21 -110 18 -141 -6z"
/>
</g>
</svg>
);
};
)
}

View File

@@ -1,12 +1,16 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { buildConfig } from 'payload/config';
import path from 'path';
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 { Icon } from './graphics/Icon';
import { Logo } from './graphics/Logo';
import { Icon } from './graphics/Icon'
import { Logo } from './graphics/Logo'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
export default buildConfig({
serverURL: 'http://localhost:3000',
admin: {
// Add your own logo and icon here
components: {
@@ -22,10 +26,13 @@ export default buildConfig({
titleSuffix: '- Your App Name',
},
},
db: mongooseAdapter({
url: process.env.DATABASE_URI || '',
}),
editor: lexicalEditor({}),
secret: process.env.PAYLOAD_SECRET || '',
serverURL: 'http://localhost:3000',
typescript: {
outputFile: path.resolve(__dirname, 'payload-types.ts'),
outputFile: path.resolve(dirname, 'payload-types.ts'),
},
graphQL: {
schemaOutputFile: path.resolve(__dirname, 'generated-schema.graphql'),
},
});
})

View File

@@ -1,30 +0,0 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable @typescript-eslint/no-var-requires */
import express from 'express';
import payload from 'payload';
import path from 'path';
require('dotenv').config();
const app = express();
// Redirect root to Admin panel
app.get('/', (_, res) => {
res.redirect('/admin');
});
app.use('/assets', express.static(path.resolve(__dirname, '../assets')));
// Initialize Payload
payload.init({
secret: process.env.PAYLOAD_SECRET,
mongoURL: process.env.MONGODB_URI,
express: app,
onInit: () => {
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`);
},
});
// Add your own express routes here
app.listen(3000);

View File

@@ -1,18 +1,44 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"baseUrl": ".",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src",
"jsx": "react"
"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": ["src"],
"exclude": ["node_modules", "dist", "build"],
"ts-node": {
"transpileOnly": true
}
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,14 @@
{
"name": "payload-monorepo",
"version": "3.0.0-beta.18",
"version": "3.0.0-beta.19",
"private": true,
"type": "module",
"workspaces:": [
"packages/*",
"test/*"
],
"scripts": {
"build": "pnpm run build:core",
"obliterate-playwright-cache": "rm -rf ~/Library/Caches/ms-playwright && find /System/Volumes/Data/private/var/folders -type d -name 'playwright*' -exec rm -rf {} +",
"build:all": "turbo build",
"build:core": "turbo build --filter \"!@payloadcms/plugin-*\"",
"build:plugins": "turbo build --filter \"@payloadcms/plugin-*\"",
"build:app": "next build",
"build:app:analyze": "cross-env ANALYZE=true next build",
"build:core": "turbo build --filter \"!@payloadcms/plugin-*\"",
"build:create-payload-app": "turbo build --filter create-payload-app",
"build:db-mongodb": "turbo build --filter db-mongodb",
"build:db-postgres": "turbo build --filter db-postgres",
@@ -34,20 +28,21 @@
"build:plugin-sentry": "turbo build --filter plugin-sentry",
"build:plugin-seo": "turbo build --filter plugin-seo",
"build:plugin-stripe": "turbo build --filter plugin-stripe",
"build:plugins": "turbo build --filter \"@payloadcms/plugin-*\"",
"build:richtext-lexical": "turbo build --filter richtext-lexical",
"build:richtext-slate": "turbo build --filter richtext-slate",
"build:tests": "pnpm --filter payload-test-suite run typecheck",
"build:translations": "turbo build --filter translations",
"build:ui": "turbo build --filter ui",
"clean": "turbo clean",
"clean:cache": "rimraf node_modules/.cache && rimraf packages/payload/node_modules/.cache && rimraf .next",
"clean:build": "find . \\( -type d \\( -name dist -o -name .cache -o -name .next -o -name .turbo \\) -o -type f -name tsconfig.tsbuildinfo \\) -not -path '*/node_modules/*' -exec rm -rf {} +",
"clean:all": "find . \\( -type d \\( -name node_modules -o -name dist -o -name .cache -o -name .next -o -name .turbo \\) -o -type f -name tsconfig.tsbuildinfo \\) -exec rm -rf {} +",
"clean:build": "find . \\( -type d \\( -name dist -o -name .cache -o -name .next -o -name .turbo \\) -o -type f -name tsconfig.tsbuildinfo \\) -not -path '*/node_modules/*' -exec rm -rf {} +",
"clean:cache": "rimraf node_modules/.cache && rimraf packages/payload/node_modules/.cache && rimraf .next",
"dev": "cross-env NODE_OPTIONS=--no-deprecation node ./test/dev.js",
"devsafe": "rimraf .next && pnpm dev",
"dev:generate-graphql-schema": "cross-env NODE_OPTIONS=--no-deprecation tsx ./test/generateGraphQLSchema.ts",
"dev:generate-types": "cross-env NODE_OPTIONS=--no-deprecation tsx ./test/generateTypes.ts",
"dev:postgres": "cross-env NODE_OPTIONS=--no-deprecation PAYLOAD_DATABASE=postgres node ./test/dev.js",
"devsafe": "rimraf .next && pnpm dev",
"docker:restart": "pnpm docker:stop --remove-orphans && pnpm docker:start",
"docker:start": "docker compose -f packages/plugin-cloud-storage/docker-compose.yml up -d",
"docker:stop": "docker compose -f packages/plugin-cloud-storage/docker-compose.yml down",
@@ -55,22 +50,31 @@
"generate:types": "PAYLOAD_CONFIG_PATH=./test/_community/config.ts node --no-deprecation ./packages/payload/bin.js generate:types",
"lint": "eslint \"packages/**/*.ts\"",
"lint-staged": "lint-staged",
"obliterate-playwright-cache": "rm -rf ~/Library/Caches/ms-playwright && find /System/Volumes/Data/private/var/folders -type d -name 'playwright*' -exec rm -rf {} +",
"prepare": "husky install",
"pretest": "pnpm build",
"reinstall": "pnpm clean:all && pnpm install",
"script:pack": "tsx scripts/pack-all-to-dest.ts",
"release:alpha": "tsx ./scripts/release.ts --bump prerelease --tag alpha",
"release:beta": "tsx ./scripts/release.ts --bump prerelease --tag beta",
"script:pack": "tsx scripts/pack-all-to-dest.ts",
"pretest": "pnpm build",
"test": "pnpm test:int && pnpm test:components && pnpm test:e2e",
"test:components": "cross-env NODE_OPTIONS=--no-deprecation jest --config=jest.components.config.js",
"test:e2e": "cross-env NODE_OPTIONS=--no-deprecation NODE_NO_WARNINGS=1 tsx ./test/runE2E.ts",
"test:e2e:debug": "cross-env NODE_OPTIONS=--no-deprecation NODE_NO_WARNINGS=1 PWDEBUG=1 DISABLE_LOGGING=true playwright test",
"test:e2e:headed": "cross-env NODE_OPTIONS=--no-deprecation NODE_NO_WARNINGS=1 DISABLE_LOGGING=true playwright test --headed",
"test:int:postgres": "cross-env NODE_OPTIONS=--no-deprecation NODE_NO_WARNINGS=1 PAYLOAD_DATABASE=postgres DISABLE_LOGGING=true jest --forceExit --detectOpenHandles --config=test/jest.config.js --runInBand",
"test:int": "cross-env NODE_OPTIONS=--no-deprecation NODE_NO_WARNINGS=1 DISABLE_LOGGING=true jest --forceExit --detectOpenHandles --config=test/jest.config.js --runInBand",
"test:int:postgres": "cross-env NODE_OPTIONS=--no-deprecation NODE_NO_WARNINGS=1 PAYLOAD_DATABASE=postgres DISABLE_LOGGING=true jest --forceExit --detectOpenHandles --config=test/jest.config.js --runInBand",
"test:unit": "cross-env NODE_OPTIONS=--no-deprecation NODE_NO_WARNINGS=1 DISABLE_LOGGING=true jest --forceExit --detectOpenHandles --config=jest.config.js --runInBand",
"translateNewKeys": "pnpm --filter payload run translateNewKeys"
},
"lint-staged": {
"**/package.json": "sort-package-json",
"*.{md,mdx,yml,json}": "prettier --write",
"*.{js,jsx,ts,tsx}": [
"prettier --write",
"eslint --cache --fix"
]
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.525.0",
"@next/bundle-analyzer": "^14.1.0",
@@ -78,6 +82,7 @@
"@payloadcms/eslint-config": "workspace:*",
"@payloadcms/live-preview-react": "workspace:*",
"@playwright/test": "1.43.0",
"@sentry/react": "^7.77.0",
"@swc/cli": "^0.1.62",
"@swc/jest": "0.2.36",
"@testing-library/jest-dom": "6.4.2",
@@ -140,8 +145,8 @@
"prettier": "^3.0.3",
"prompts": "2.4.2",
"qs": "6.11.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"read-stream": "^2.1.1",
"rimraf": "3.0.2",
"semver": "^7.5.4",
@@ -150,6 +155,7 @@
"simple-git": "^3.24.0",
"slash": "3.0.0",
"slate": "0.91.4",
"sort-package-json": "^2.10.0",
"swc-plugin-transform-remove-imports": "^1.12.1",
"tempfile": "^3.0.0",
"tempy": "^1.0.1",
@@ -167,19 +173,12 @@
"node": ">=18.20.2",
"pnpm": "^8.15.7"
},
"lint-staged": {
"*.{md,mdx,yml,json}": "prettier --write",
"*.{js,jsx,ts,tsx}": [
"prettier --write",
"eslint --cache --fix"
]
},
"dependencies": {
"@sentry/react": "^7.77.0",
"ajv": "^8.12.0",
"passport-strategy": "1.0.0"
},
"pnpm": {
"allowedDeprecatedVersions": {
"abab": "2",
"domexception": "4",
"uuid": "3.4.0"
},
"overrides": {
"copyfiles": "$copyfiles",
"cross-env": "$cross-env",
@@ -191,13 +190,12 @@
"react-dom": "$react-dom",
"typescript": "$typescript"
},
"allowedDeprecatedVersions": {
"uuid": "3.4.0",
"abab": "2",
"domexception": "4"
},
"patchedDependencies": {
"playwright@1.43.0": "patches/playwright@1.43.0.patch"
}
}
},
"workspaces:": [
"packages/*",
"test/*"
]
}

View File

@@ -1,31 +1,38 @@
{
"name": "create-payload-app",
"version": "3.0.0-beta.18",
"license": "MIT",
"type": "module",
"version": "3.0.0-beta.19",
"homepage": "https://payloadcms.com",
"bin": {
"create-payload-app": "bin/cli.js"
},
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/create-payload-app"
},
"scripts": {
"build": "pnpm pack-template-files && pnpm typecheck && pnpm build:swc",
"typecheck": "tsc",
"pack-template-files": "tsx src/scripts/pack-template-files.ts",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
"clean": "rimraf {dist,*.tsbuildinfo}",
"test": "jest",
"prepublishOnly": "pnpm clean && pnpm build"
"license": "MIT",
"type": "module",
"exports": {
"./commands": {
"import": "./src/lib/init-next.ts",
"require": "./src/lib/init-next.ts",
"types": "./src/lib/init-next.ts"
}
},
"bin": {
"create-payload-app": "bin/cli.js"
},
"files": [
"package.json",
"dist",
"bin"
],
"scripts": {
"build": "pnpm pack-template-files && pnpm typecheck && pnpm build:swc",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
"clean": "rimraf {dist,*.tsbuildinfo}",
"pack-template-files": "tsx src/scripts/pack-template-files.ts",
"prepublishOnly": "pnpm clean && pnpm build",
"test": "jest",
"typecheck": "tsc"
},
"dependencies": {
"@clack/prompts": "^0.7.0",
"@sindresorhus/slugify": "^1.1.0",
@@ -49,12 +56,5 @@
"@types/fs-extra": "^9.0.12",
"@types/jest": "^27.0.3",
"@types/node": "20.12.5"
},
"exports": {
"./commands": {
"import": "./src/lib/init-next.ts",
"require": "./src/lib/init-next.ts",
"types": "./src/lib/init-next.ts"
}
}
}

View File

@@ -1,22 +1,34 @@
{
"name": "@payloadcms/db-mongodb",
"version": "3.0.0-beta.18",
"version": "3.0.0-beta.19",
"description": "The officially supported MongoDB database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/db-mongodb"
},
"license": "MIT",
"homepage": "https://payloadcms.com",
"type": "module",
"author": {
"email": "info@payloadcms.com",
"name": "Payload",
"email": "info@payloadcms.com",
"url": "https://payloadcms.com"
},
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",
"require": "./src/index.ts",
"types": "./src/index.ts"
}
},
"main": "./src/index.ts",
"types": "./src/types.ts",
"files": [
"dist",
"mock.js",
"predefinedMigrations"
],
"scripts": {
"build": "pnpm build:swc && pnpm build:types",
"build:swc": "swc ./src -d ./dist --config-file .swcrc-build",
@@ -44,27 +56,15 @@
"peerDependencies": {
"payload": "workspace:*"
},
"exports": {
".": {
"import": "./src/index.ts",
"require": "./src/index.ts",
"types": "./src/index.ts"
}
},
"publishConfig": {
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
}
}
},
"files": [
"dist",
"mock.js",
"predefinedMigrations"
]
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts"
}
}

View File

@@ -1,22 +1,38 @@
{
"name": "@payloadcms/db-postgres",
"version": "3.0.0-beta.18",
"version": "3.0.0-beta.19",
"description": "The officially supported Postgres database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/db-postgres"
},
"license": "MIT",
"homepage": "https://payloadcms.com",
"type": "module",
"author": {
"email": "info@payloadcms.com",
"name": "Payload",
"email": "info@payloadcms.com",
"url": "https://payloadcms.com"
},
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",
"require": "./src/index.ts",
"types": "./src/index.ts"
},
"./types": {
"import": "./src/types.ts",
"require": "./src/types.ts",
"types": "./src/types.ts"
}
},
"main": "./src/index.ts",
"types": "./src/types.ts",
"files": [
"dist",
"mock.js"
],
"scripts": {
"build": "pnpm build:swc && pnpm build:types",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
@@ -43,21 +59,7 @@
"peerDependencies": {
"payload": "workspace:*"
},
"exports": {
".": {
"import": "./src/index.ts",
"require": "./src/index.ts",
"types": "./src/index.ts"
},
"./types": {
"import": "./src/types.ts",
"require": "./src/types.ts",
"types": "./src/types.ts"
}
},
"publishConfig": {
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
@@ -69,10 +71,8 @@
"require": "./dist/types.js",
"types": "./dist/types.d.ts"
}
}
},
"files": [
"dist",
"mock.js"
]
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts"
}
}

View File

@@ -53,7 +53,7 @@ export const buildFindManyArgs = ({
}
}
if (adapter.tables[`${tableName}_rels`]) {
if (adapter.tables[`${tableName}${adapter.relationshipsSuffix}`]) {
result.with._rels = {
columns: {
id: false,
@@ -63,7 +63,7 @@ export const buildFindManyArgs = ({
}
}
if (adapter.tables[`${tableName}_locales`]) {
if (adapter.tables[`${tableName}${adapter.localesSuffix}`]) {
result.with._locales = _locales
}

View File

@@ -71,9 +71,9 @@ export const insertArrays = async ({ adapter, arrays, db, parentRows }: Args): P
}
// Insert locale rows
if (adapter.tables[`${tableName}_locales`] && row.locales.length > 0) {
if (adapter.tables[`${tableName}${adapter.localesSuffix}`] && row.locales.length > 0) {
if (!row.locales[0]._parentID) {
row.locales = row.locales.map((localeRow, i) => {
row.locales = row.locales.map((localeRow) => {
if (typeof localeRow._getParentID === 'function') {
localeRow._parentID = localeRow._getParentID(insertedRows)
delete localeRow._getParentID
@@ -81,7 +81,10 @@ export const insertArrays = async ({ adapter, arrays, db, parentRows }: Args): P
return localeRow
})
}
await db.insert(adapter.tables[`${tableName}_locales`]).values(row.locales).returning()
await db
.insert(adapter.tables[`${tableName}${adapter.localesSuffix}`])
.values(row.locales)
.returning()
}
// If there are sub arrays, call this function recursively

View File

@@ -1 +1,72 @@
# Nodemailer Email Adapter
# Nodemailer Email Adapter for Payload
This adapter allows you to send emails using the [Nodemailer](https://nodemailer.com/) library.
It abstracts all of the email functionality that was in Payload by default in 2.x into a separate package.
**NOTE:** Configuring email in Payload 3.0 is now completely optional. However, you will receive a startup warning that email is not configured and also a message if you attempt to send an email.
## Installation
```sh
pnpm add @payloadcms/email-nodemailer` nodemailer
```
## Usage
### Using nodemailer.createTransport
```ts
import { nodemailerAdapter } from '@payloadcms/email-nodemailer'
import nodemailer from 'nodemailer'
export default buildConfig({
email: nodemailerAdapter({
defaultFromAddress: 'info@payloadcms.com',
defaultFromName: 'Payload',
// Any Nodemailer transport
transport: await nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: 587,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
}),
}),
})
```
### Using transportOptions
```ts
import { nodemailerAdapter } from '@payloadcms/email-nodemailer'
export default buildConfig({
email: nodemailerAdapter({
defaultFromAddress: 'info@payloadcms.com',
defaultFromName: 'Payload',
// Nodemailer transportOptions
transportOptions: {
host: process.env.SMTP_HOST,
port: 587,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
},
}),
})
```
During development, if you pass nothing to `nodemailerAdapter`, it will use the [ethereal.email](https://ethereal.email) service.
This will log the ethereal.email details to console on startup.
```ts
import { nodemailerAdapter } from '@payloadcms/email-nodemailer'
export default buildConfig({
email: nodemailerAdapter(), // This will be the old ethereal.email functionality
})
```

View File

@@ -1,32 +1,16 @@
{
"name": "@payloadcms/email-nodemailer",
"version": "3.0.0-beta.18",
"version": "3.0.0-beta.19",
"description": "Payload Nodemailer Email Adapter",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/email-nodemailer"
},
"license": "MIT",
"homepage": "https://payloadcms.com",
"author": "Payload CMS, Inc.",
"main": "./src/index.ts",
"types": "./src/index.ts",
"type": "module",
"scripts": {
"build": "pnpm build:swc && pnpm build:types",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"build:clean": "find . \\( -type d \\( -name build -o -name dist -o -name .cache \\) -o -type f -name tsconfig.tsbuildinfo \\) -exec rm -rf {} + && pnpm build",
"clean": "rimraf {dist,*.tsbuildinfo}",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},
"dependencies": {
"nodemailer": "6.9.10"
},
"peerDependencies": {
"payload": "workspace:*"
},
"exports": {
".": {
"import": "./src/index.ts",
@@ -34,6 +18,32 @@
"types": "./src/index.ts"
}
},
"main": "./src/index.ts",
"types": "./src/index.ts",
"files": [
"dist"
],
"scripts": {
"build": "pnpm build:swc && pnpm build:types",
"build:clean": "find . \\( -type d \\( -name build -o -name dist -o -name .cache \\) -o -type f -name tsconfig.tsbuildinfo \\) -exec rm -rf {} + && pnpm build",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"clean": "rimraf {dist,*.tsbuildinfo}",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},
"dependencies": {
"nodemailer": "6.9.10"
},
"devDependencies": {
"@types/nodemailer": "6.4.14",
"payload": "workspace:*"
},
"peerDependencies": {
"payload": "workspace:*"
},
"engines": {
"node": ">=18.20.2"
},
"publishConfig": {
"exports": {
".": {
@@ -45,15 +55,5 @@
"main": "./dist/index.js",
"registry": "https://registry.npmjs.org/",
"types": "./dist/index.d.ts"
},
"engines": {
"node": ">=18.20.2"
},
"files": [
"dist"
],
"devDependencies": {
"payload": "workspace:*",
"@types/nodemailer": "6.4.14"
}
}

View File

@@ -2,16 +2,17 @@
"name": "@payloadcms/eslint-config",
"version": "1.1.1",
"description": "Payload styles for ESLint and Prettier",
"license": "MIT",
"keywords": [],
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/eslint-config-payload"
},
"license": "MIT",
"author": {
"email": "info@payloadcms.com",
"name": "Payload",
"email": "info@payloadcms.com",
"url": "https://payloadcms.com"
},
"main": "index.js",
@@ -28,11 +29,10 @@
"eslint-plugin-jest-dom": "5.1.0",
"eslint-plugin-jsx-a11y": "6.8.0",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-payload": "workspace:*",
"eslint-plugin-perfectionist": "2.7.0",
"eslint-plugin-react": "7.34.1",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-regexp": "2.3.0",
"eslint-plugin-payload": "workspace:*"
},
"keywords": []
"eslint-plugin-regexp": "2.3.0"
}
}

View File

@@ -2,16 +2,17 @@
"name": "eslint-plugin-payload",
"version": "1.0.0",
"description": "Payload plugins for ESLint",
"license": "MIT",
"keywords": [],
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/eslint-plugin-payload"
},
"license": "MIT",
"author": {
"email": "info@payloadcms.com",
"name": "Payload",
"email": "info@payloadcms.com",
"url": "https://payloadcms.com"
},
"main": "index.js",
@@ -32,6 +33,5 @@
"eslint-plugin-react": "7.34.1",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-regexp": "2.3.0"
},
"keywords": []
}
}

View File

@@ -1,15 +1,25 @@
{
"name": "@payloadcms/graphql",
"version": "3.0.0-beta.18",
"main": "./src/index.ts",
"types": "./src/index.d.ts",
"type": "module",
"version": "3.0.0-beta.19",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/graphql"
},
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",
"require": "./src/index.ts",
"types": "./src/index.ts"
}
},
"main": "./src/index.ts",
"types": "./src/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "pnpm build:swc && pnpm build:types",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
@@ -17,12 +27,9 @@
"clean": "rimraf {dist,*.tsbuildinfo}",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},
"exports": {
".": {
"import": "./src/index.ts",
"require": "./src/index.ts",
"types": "./src/index.ts"
}
"dependencies": {
"graphql-scalars": "1.22.2",
"pluralize": "8.0.0"
},
"devDependencies": {
"@payloadcms/eslint-config": "workspace:*",
@@ -31,26 +38,19 @@
"payload": "workspace:*",
"ts-essentials": "7.0.3"
},
"dependencies": {
"graphql-scalars": "1.22.2",
"pluralize": "8.0.0"
},
"peerDependencies": {
"payload": "workspace:*",
"graphql": "^16.8.1"
"graphql": "^16.8.1",
"payload": "workspace:*"
},
"publishConfig": {
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
}
}
},
"files": [
"dist"
]
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts"
}
}

View File

@@ -2,17 +2,26 @@
"name": "@payloadcms/live-preview-react",
"version": "0.2.0",
"description": "The official live preview React SDK for Payload",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/live-preview-react"
},
"license": "MIT",
"homepage": "https://payloadcms.com",
"author": "Payload CMS, Inc.",
"type": "module",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
}
},
"main": "./src/index.ts",
"types": "./src/index.ts",
"type": "module",
"files": [
"dist"
],
"scripts": {
"build": "pnpm copyfiles && pnpm build:swc && pnpm build:types",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
@@ -32,12 +41,6 @@
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
}
},
"publishConfig": {
"exports": {
".": {
@@ -49,8 +52,5 @@
"main": "./dist/index.js",
"registry": "https://registry.npmjs.org/",
"types": "./dist/index.d.ts"
},
"files": [
"dist"
]
}
}

View File

@@ -2,17 +2,26 @@
"name": "@payloadcms/live-preview-vue",
"version": "0.1.0",
"description": "The official live preview Vue SDK for Payload",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/live-preview-vue"
},
"license": "MIT",
"homepage": "https://payloadcms.com",
"author": "Payload CMS, Inc.",
"type": "module",
"exports": {
".": {
"default": "./src/index.ts",
"types": "./src/index.ts"
}
},
"main": "./src/index.ts",
"types": "./src/index.ts",
"type": "module",
"files": [
"dist"
],
"scripts": {
"build": "pnpm copyfiles && pnpm build:swc && pnpm build:types",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
@@ -26,18 +35,12 @@
},
"devDependencies": {
"@payloadcms/eslint-config": "workspace:*",
"vue": "^3.0.0",
"payload": "workspace:*"
"payload": "workspace:*",
"vue": "^3.0.0"
},
"peerDependencies": {
"vue": "^3.0.0"
},
"exports": {
".": {
"default": "./src/index.ts",
"types": "./src/index.ts"
}
},
"publishConfig": {
"exports": {
".": {
@@ -49,8 +52,5 @@
"main": "./dist/index.js",
"registry": "https://registry.npmjs.org/",
"types": "./dist/index.d.ts"
},
"files": [
"dist"
]
}
}

View File

@@ -2,17 +2,26 @@
"name": "@payloadcms/live-preview",
"version": "0.2.2",
"description": "The official live preview JavaScript SDK for Payload",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/live-preview"
},
"license": "MIT",
"homepage": "https://payloadcms.com",
"author": "Payload CMS, Inc.",
"type": "module",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
}
},
"main": "./src/index.ts",
"types": "./src/index.ts",
"type": "module",
"files": [
"dist"
],
"scripts": {
"build": "pnpm copyfiles && pnpm build:swc && pnpm build:types",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
@@ -25,12 +34,6 @@
"@payloadcms/eslint-config": "workspace:*",
"payload": "workspace:*"
},
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
}
},
"publishConfig": {
"exports": {
".": {
@@ -42,8 +45,5 @@
"main": "./dist/index.js",
"registry": "https://registry.npmjs.org/",
"types": "./dist/index.d.ts"
},
"files": [
"dist"
]
}
}

View File

@@ -1,27 +1,13 @@
{
"name": "@payloadcms/next",
"version": "3.0.0-beta.18",
"main": "./src/index.js",
"types": "./src/index.js",
"type": "module",
"version": "3.0.0-beta.19",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/next"
},
"scripts": {
"build:cjs": "swc ./src/withPayload.js -o ./dist/cjs/withPayload.cjs --config-file .swcrc-cjs",
"build": "pnpm copyfiles && pnpm build:swc && pnpm build:cjs && pnpm build:types && pnpm build:webpack && rm dist/prod/index.js",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"build:webpack": "webpack --config webpack.config.js",
"clean": "rimraf {dist,*.tsbuildinfo}",
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" \"src/app/api/**\" dist/",
"fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
"lint": "eslint \"src/**/*.{ts,tsx}\"",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},
"type": "module",
"exports": {
".": {
"import": "./src/index.js",
@@ -38,6 +24,40 @@
"types": "./src/exports/*.ts"
}
},
"main": "./src/index.js",
"types": "./src/index.js",
"files": [
"dist"
],
"scripts": {
"build": "pnpm copyfiles && pnpm build:swc && pnpm build:cjs && pnpm build:types && pnpm build:webpack && rm dist/prod/index.js",
"build:cjs": "swc ./src/withPayload.js -o ./dist/cjs/withPayload.cjs --config-file .swcrc-cjs",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"build:webpack": "webpack --config webpack.config.js",
"clean": "rimraf {dist,*.tsbuildinfo}",
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" \"src/app/api/**\" dist/",
"fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
"lint": "eslint \"src/**/*.{ts,tsx}\"",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},
"dependencies": {
"@dnd-kit/core": "6.0.8",
"@payloadcms/graphql": "workspace:*",
"@payloadcms/translations": "workspace:*",
"@payloadcms/ui": "workspace:*",
"@types/busboy": "^1.5.3",
"busboy": "^1.6.0",
"deep-equal": "2.2.2",
"graphql-http": "^1.22.0",
"graphql-playground-html": "1.6.30",
"path-to-regexp": "^6.2.1",
"qs": "6.11.2",
"react-diff-viewer-continued": "3.2.6",
"react-toastify": "8.2.0",
"sass": "^1.71.1",
"ws": "^8.16.0"
},
"devDependencies": {
"@next/eslint-plugin-next": "^14.1.0",
"@payloadcms/eslint-config": "workspace:*",
@@ -58,33 +78,17 @@
"webpack": "^5.78.0",
"webpack-cli": "^5.1.4"
},
"dependencies": {
"@dnd-kit/core": "6.0.8",
"@payloadcms/graphql": "workspace:*",
"@payloadcms/translations": "workspace:*",
"@payloadcms/ui": "workspace:*",
"@types/busboy": "^1.5.3",
"busboy": "^1.6.0",
"deep-equal": "2.2.2",
"graphql-playground-html": "1.6.30",
"path-to-regexp": "^6.2.1",
"qs": "6.11.2",
"react-diff-viewer-continued": "3.2.6",
"react-toastify": "8.2.0",
"sass": "^1.71.1",
"graphql-http": "^1.22.0",
"ws": "^8.16.0"
},
"peerDependencies": {
"file-type": "16.5.4",
"graphql": "^16.8.1",
"http-status": "1.6.2",
"next": "^14.3.0-canary.7",
"payload": "workspace:*",
"graphql": "^16.8.1"
"payload": "workspace:*"
},
"engines": {
"node": ">=18.20.2"
},
"publishConfig": {
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
"./css": {
"import": "./dist/prod/styles.css",
@@ -101,12 +105,8 @@
"types": "./dist/exports/*.d.ts"
}
},
"registry": "https://registry.npmjs.org/"
},
"engines": {
"node": ">=18.20.2"
},
"files": [
"dist"
]
"main": "./dist/index.js",
"registry": "https://registry.npmjs.org/",
"types": "./dist/index.d.ts"
}
}

View File

@@ -1,7 +1,7 @@
export { addDataAndFileToRequest } from '../utilities/addDataAndFileToRequest.js'
export { addLocalesToRequestFromData, sanitizeLocales } from '../utilities/addLocalesToRequest.js'
export { traverseFields } from '../utilities/buildFieldSchemaMap/traverseFields.js'
export { createPayloadRequest as createBasePayloadRequest } from '../utilities/createPayloadRequest.js'
export { createPayloadRequest } from '../utilities/createPayloadRequest.js'
export { getNextRequestI18n } from '../utilities/getNextRequestI18n.js'
export { getPayloadHMR, reload } from '../utilities/getPayloadHMR.js'
export { headersWithCors } from '../utilities/headersWithCors.js'

View File

@@ -1,4 +1,4 @@
import type { FileShape, NextFileUploadOptions } from './index.js'
import type { FetchAPIFileUploadOptions, FileShape } from './index.js'
import {
checkAndMakeDir,
@@ -12,7 +12,7 @@ import {
type MoveFile = (
filePath: string,
options: FileFactoryOptions,
fileUploadOptions: NextFileUploadOptions,
fileUploadOptions: FetchAPIFileUploadOptions,
) => (resolve: () => void, reject: () => void) => void
/**
@@ -45,7 +45,7 @@ type FileFactoryOptions = {
}
type FileFactory = (
options: FileFactoryOptions,
fileUploadOptions: NextFileUploadOptions,
fileUploadOptions: FetchAPIFileUploadOptions,
) => FileShape
export const fileFactory: FileFactory = (options, fileUploadOptions) => {
// see: https://github.com/richardgirges/express-fileupload/issues/14

View File

@@ -2,12 +2,12 @@ import crypto from 'crypto'
import fs, { WriteStream } from 'fs'
import path from 'path'
import type { NextFileUploadOptions } from './index.js'
import type { FetchAPIFileUploadOptions } from './index.js'
import { checkAndMakeDir, debugLog, deleteFile, getTempFilename } from './utilities.js'
type Handler = (
options: NextFileUploadOptions,
options: FetchAPIFileUploadOptions,
fieldname: string,
filename: string,
) => {

View File

@@ -34,7 +34,7 @@ export type FileShape = {
truncated: boolean
}
export type NextFileUploadOptions = {
export type FetchAPIFileUploadOptions = {
/**
* Returns a HTTP 413 when the file is bigger than the size limit if `true`.
* Otherwise, it will add a `truncated = true` to the resulting file structure.
@@ -132,7 +132,7 @@ export type NextFileUploadOptions = {
useTempFiles?: boolean | undefined
} & Partial<BusboyConfig>
type NextFileUploadResponseFile = {
type FetchAPIFileUploadResponseFile = {
data: Buffer
mimetype: string
name: string
@@ -140,20 +140,20 @@ type NextFileUploadResponseFile = {
tempFilePath?: string
}
export type NextFileUploadResponse = {
export type FetchAPIFileUploadResponse = {
error?: {
code: number
message: string
}
fields: Record<string, string>
files: Record<string, NextFileUploadResponseFile>
files: Record<string, FetchAPIFileUploadResponseFile>
}
type NextFileUpload = (args: {
options?: NextFileUploadOptions
type FetchAPIFileUpload = (args: {
options?: FetchAPIFileUploadOptions
request: Request
}) => Promise<NextFileUploadResponse>
export const nextFileUpload: NextFileUpload = async ({ options, request }) => {
}) => Promise<FetchAPIFileUploadResponse>
export const fetchAPIFileUpload: FetchAPIFileUpload = async ({ options, request }) => {
const uploadOptions = { ...DEFAULT_OPTIONS, ...options }
if (!isEligibleRequest(request)) {
debugLog(uploadOptions, 'Request is not eligible for file upload!')

View File

@@ -2,7 +2,7 @@ import Busboy from 'busboy'
import httpStatus from 'http-status'
import { APIError } from 'payload/errors'
import type { NextFileUploadOptions, NextFileUploadResponse } from './index.js'
import type { FetchAPIFileUploadOptions, FetchAPIFileUploadResponse } from './index.js'
import { fileFactory } from './fileFactory.js'
import { memHandler, tempFileHandler } from './handlers.js'
@@ -13,9 +13,9 @@ import { buildFields, debugLog, isFunc, parseFileName } from './utilities.js'
const waitFlushProperty = Symbol('wait flush property symbol')
type ProcessMultipart = (args: {
options: NextFileUploadOptions
options: FetchAPIFileUploadOptions
request: Request
}) => Promise<NextFileUploadResponse>
}) => Promise<FetchAPIFileUploadResponse>
export const processMultipart: ProcessMultipart = async ({ options, request }) => {
let parsingRequest = true
@@ -29,7 +29,7 @@ export const processMultipart: ProcessMultipart = async ({ options, request }) =
failedResolvingFiles = rej
})
const result: NextFileUploadResponse = {
const result: FetchAPIFileUploadResponse = {
fields: undefined,
files: undefined,
}

View File

@@ -7,10 +7,10 @@ export const processNested = function (data) {
keys = Object.keys(data)
for (let i = 0; i < keys.length; i++) {
let key = keys[i],
const key = keys[i],
value = data[key],
current = d,
keyParts = key.replace(new RegExp(/\[/g), '.').replace(new RegExp(/\]/g), '').split('.')
let current = d
for (let index = 0; index < keyParts.length; index++) {
const k = keyParts[index]

View File

@@ -2,7 +2,7 @@ import fs from 'fs'
import path from 'path'
import { Readable } from 'stream'
import type { NextFileUploadOptions } from './index.js'
import type { FetchAPIFileUploadOptions } from './index.js'
// Parameters for safe file name parsing.
const SAFE_FILE_NAME_REGEX = /[^\w-]/g
@@ -16,7 +16,7 @@ let tempCounter = 0
/**
* Logs message to console if options.debug option set to true.
*/
export const debugLog = (options: NextFileUploadOptions, msg: string) => {
export const debugLog = (options: FetchAPIFileUploadOptions, msg: string) => {
const opts = options || {}
if (!opts.debug) return false
console.log(`Next-file-upload: ${msg}`) // eslint-disable-line
@@ -108,7 +108,7 @@ export const buildFields: BuildFields = (instance, field, value) => {
* Creates a folder if it does not exist
* for file specified in the path variable
*/
type CheckAndMakeDir = (fileUploadOptions: NextFileUploadOptions, filePath: string) => boolean
type CheckAndMakeDir = (fileUploadOptions: FetchAPIFileUploadOptions, filePath: string) => boolean
export const checkAndMakeDir: CheckAndMakeDir = (fileUploadOptions, filePath) => {
if (!fileUploadOptions.createParentPath) return false
// Check whether folder for the file exists.
@@ -271,7 +271,7 @@ export const parseFileNameExtension: ParseFileNameExtension = (preserveExtension
/**
* Parse file name and extension.
*/
type ParseFileName = (opts: NextFileUploadOptions, fileName: string) => string
type ParseFileName = (opts: FetchAPIFileUploadOptions, fileName: string) => string
export const parseFileName: ParseFileName = (opts, fileName) => {
// Check fileName argument
if (!fileName || typeof fileName !== 'string') return getTempFilename()

View File

@@ -6,7 +6,7 @@ import httpStatus from 'http-status'
import path from 'path'
import { APIError } from 'payload/errors'
import { streamFile } from '../../../next-stream-file/index.js'
import { streamFile } from '../../../fetchAPI-stream-file/index.js'
import { headersWithCors } from '../../../utilities/headersWithCors.js'
import { routeError } from '../routeError.js'
import { checkFileAccess } from './checkFileAccess.js'

View File

@@ -149,7 +149,10 @@ const handleCustomEndpoints = ({
})
if (customEndpoint) {
payloadRequest.routeParams = handlerParams
payloadRequest.routeParams = {
...payloadRequest.routeParams,
...handlerParams,
}
return customEndpoint.handler(payloadRequest)
}
}
@@ -211,9 +214,6 @@ export const GET =
try {
req = await createPayloadRequest({
config,
params: {
collection: slug1,
},
request,
})
@@ -227,6 +227,7 @@ export const GET =
collection = req.payload.collections?.[slug1]
if (collection) {
req.routeParams.collection = slug1
const disableEndpoints = endpointsAreDisabled({
endpoints: collection.config.endpoints,
request,
@@ -295,12 +296,12 @@ export const GET =
}
} else if (slug1 === 'globals') {
const globalConfig = req.payload.config.globals.find((global) => global.slug === slug2)
req.routeParams.global = globalConfig.slug
const disableEndpoints = endpointsAreDisabled({
endpoints: globalConfig.endpoints,
request,
})
if (disableEndpoints) return disableEndpoints
const customEndpointResponse = await handleCustomEndpoints({
@@ -391,7 +392,6 @@ export const POST =
try {
req = await createPayloadRequest({
config,
params: { collection: slug1 },
request,
})
@@ -405,6 +405,7 @@ export const POST =
if (disableEndpoints) return disableEndpoints
if (collection) {
req.routeParams.collection = slug1
const disableEndpoints = endpointsAreDisabled({
endpoints: collection.config.endpoints,
request,
@@ -466,6 +467,8 @@ export const POST =
}
} else if (slug1 === 'globals' && slug2) {
const globalConfig = req.payload.config.globals.find((global) => global.slug === slug2)
req.routeParams.global = globalConfig.slug
const disableEndpoints = endpointsAreDisabled({
endpoints: globalConfig.endpoints,
request,
@@ -553,9 +556,6 @@ export const DELETE =
try {
req = await createPayloadRequest({
config,
params: {
collection: slug1,
},
request,
})
collection = req.payload.collections?.[slug1]
@@ -567,6 +567,8 @@ export const DELETE =
if (disableEndpoints) return disableEndpoints
if (collection) {
req.routeParams.collection = slug1
const disableEndpoints = endpointsAreDisabled({
endpoints: collection.config.endpoints,
request,
@@ -635,9 +637,6 @@ export const PATCH =
try {
req = await createPayloadRequest({
config,
params: {
collection: slug1,
},
request,
})
collection = req.payload.collections?.[slug1]
@@ -649,6 +648,8 @@ export const PATCH =
if (disableEndpoints) return disableEndpoints
if (collection) {
req.routeParams.collection = slug1
const disableEndpoints = endpointsAreDisabled({
endpoints: collection.config.endpoints,
request,

View File

@@ -1,8 +1,13 @@
import type { PayloadRequest, PayloadRequestData } from 'payload/types'
import type { NextFileUploadOptions } from '../next-fileupload/index.js'
import { APIError } from 'payload/errors'
import { nextFileUpload } from '../next-fileupload/index.js'
import type { FetchAPIFileUploadOptions } from '../fetchAPI-multipart/index.js'
import { fetchAPIFileUpload } from '../fetchAPI-multipart/index.js'
const KB = 1024
const MB = KB * KB
type ReturnType = PayloadRequest & PayloadRequestData
type AddDataAndFileToRequest = (args: { request: PayloadRequest }) => Promise<ReturnType>
@@ -10,38 +15,66 @@ type AddDataAndFileToRequest = (args: { request: PayloadRequest }) => Promise<Re
/**
* Mutates the Request to contain 'data' and 'file' if present
*/
export const addDataAndFileToRequest: AddDataAndFileToRequest = async ({ request }) => {
const config = request.payload.config
let data: Record<string, any> | undefined = undefined
let file: PayloadRequestData['file'] = undefined
export const addDataAndFileToRequest: AddDataAndFileToRequest = async ({
request: incomingRequest,
}) => {
const config = incomingRequest.payload.config
if (
request.method &&
['PATCH', 'POST', 'PUT'].includes(request.method.toUpperCase()) &&
request.body
incomingRequest.method &&
['PATCH', 'POST', 'PUT'].includes(incomingRequest.method.toUpperCase()) &&
incomingRequest.body
) {
const [contentType] = (request.headers.get('Content-Type') || '').split(';')
const [contentType] = (incomingRequest.headers.get('Content-Type') || '').split(';')
const mutableRequest = incomingRequest as ReturnType
const bodyByteSize = parseInt(incomingRequest.headers.get('Content-Length') || '0', 10)
if (contentType === 'application/json') {
const bodyByteSize = parseInt(request.headers.get('Content-Length') || '0', 10)
const upperByteLimit =
typeof config.upload?.limits?.fieldSize === 'number'
? config.upload.limits.fields
: undefined
if ((upperByteLimit && bodyByteSize <= upperByteLimit) || upperByteLimit === undefined) {
try {
data = await request.json()
} catch (error) {
data = {}
let data = {}
try {
data = await mutableRequest.json()
} catch (error) {
mutableRequest.payload.logger.error(error)
} finally {
mutableRequest.data = data
mutableRequest.json = () => Promise.resolve(data)
}
} else if (bodyByteSize && contentType.includes('multipart/')) {
// body is <= 4MB
if (bodyByteSize <= 4 * MB) {
const formData = await mutableRequest.formData()
mutableRequest.formData = async () => Promise.resolve(formData)
const payloadData = formData.get('_payload')
if (typeof payloadData === 'string') {
mutableRequest.data = JSON.parse(payloadData)
}
const formFile = formData.get('file')
if (formFile instanceof Blob) {
const maxFileSizeLimit = config.upload.limits?.fileSize ?? undefined
if (
maxFileSizeLimit === undefined ||
(maxFileSizeLimit && formFile.size <= maxFileSizeLimit)
) {
const fileBytes = await formFile.arrayBuffer()
const buffer = Buffer.from(fileBytes)
mutableRequest.file = {
name: formFile.name,
data: buffer,
mimetype: formFile.type,
size: formFile.size,
}
} else if (config.upload?.abortOnLimit) {
throw new APIError('File size limit has been reached', 413)
}
}
} else {
throw new Error('Request body size exceeds the limit')
}
} else {
if (request.headers.has('Content-Length') && request.headers.get('Content-Length') !== '0') {
const { error, fields, files } = await nextFileUpload({
options: config.upload as NextFileUploadOptions,
request: request as Request,
// body is > 4MB
const { error, fields, files } = await fetchAPIFileUpload({
options: config.upload as FetchAPIFileUploadOptions,
request: mutableRequest as Request,
})
if (error) {
@@ -49,22 +82,17 @@ export const addDataAndFileToRequest: AddDataAndFileToRequest = async ({ request
}
if (files?.file) {
file = files.file
mutableRequest.file = files.file
}
if (fields?._payload && typeof fields._payload === 'string') {
data = JSON.parse(fields._payload)
mutableRequest.data = JSON.parse(fields._payload)
}
}
}
return mutableRequest
}
const mutableRequest = request as ReturnType
if (data) {
mutableRequest.data = data
mutableRequest.json = () => Promise.resolve(data)
}
if (file) mutableRequest.file = file
return mutableRequest
return incomingRequest
}

View File

@@ -1,8 +1,8 @@
import type { Collection, PayloadRequestWithData, SanitizedConfig } from 'payload/types'
import type { NextFileUploadOptions } from '../next-fileupload/index.js'
import type { FetchAPIFileUploadOptions } from '../fetchAPI-multipart/index.js'
import { nextFileUpload } from '../next-fileupload/index.js'
import { fetchAPIFileUpload } from '../fetchAPI-multipart/index.js'
type GetDataAndFile = (args: {
collection: Collection
@@ -44,8 +44,8 @@ export const getDataAndFile: GetDataAndFile = async ({
}
} else {
if (request.headers.has('Content-Length') && request.headers.get('Content-Length') !== '0') {
const { error, fields, files } = await nextFileUpload({
options: config.upload as NextFileUploadOptions,
const { error, fields, files } = await fetchAPIFileUpload({
options: config.upload as FetchAPIFileUploadOptions,
request,
})

View File

@@ -1,14 +1,16 @@
@import '../../.././scss/styles.scss';
.restore-version {
cursor: pointer;
&__modal {
// @include blur-bg;
@include blur-bg;
display: flex;
align-items: center;
height: 100%;
&__toggle {
// @extend %btn-reset;
@extend %btn-reset;
}
.btn {

Some files were not shown because too many files have changed in this diff Show More