Compare commits
30 Commits
v3.0.0-bet
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bba969f0d | ||
|
|
3a43fd34c0 | ||
|
|
d9005b3f53 | ||
|
|
fab9e32175 | ||
|
|
e71c1c2ec4 | ||
|
|
81fb0515fb | ||
|
|
739dfc1434 | ||
|
|
a4e8795666 | ||
|
|
14134d637d | ||
|
|
2b698a9018 | ||
|
|
91684c8a7d | ||
|
|
fbdfe1d9dd | ||
|
|
7221725121 | ||
|
|
640348df3a | ||
|
|
4ed99e017a | ||
|
|
df6b9dd30b | ||
|
|
faf142baff | ||
|
|
f80cb9f553 | ||
|
|
d3eaa1fceb | ||
|
|
df77152851 | ||
|
|
937202b27c | ||
|
|
3581f39c31 | ||
|
|
c1d9c81b68 | ||
|
|
20355a4dd4 | ||
|
|
cf66d7f09b | ||
|
|
30afe81462 | ||
|
|
18ee6e8867 | ||
|
|
9f78a93403 | ||
|
|
bd046e2437 | ||
|
|
e9004a93a4 |
44
.github/workflows/main.yml
vendored
44
.github/workflows/main.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/pr-title.yml
vendored
2
.github/workflows/pr-title.yml
vendored
@@ -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]).+$
|
||||
|
||||
@@ -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
|
||||
|
||||
7
examples/hierarchy/.eslintrc.cjs
Normal file
7
examples/hierarchy/.eslintrc.cjs
Normal file
@@ -0,0 +1,7 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
project: ['./tsconfig.json'],
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
}
|
||||
45
examples/hierarchy/.gitignore
vendored
45
examples/hierarchy/.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
module.exports = {
|
||||
printWidth: 100,
|
||||
parser: 'typescript',
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
arrowParens: 'avoid',
|
||||
}
|
||||
6
examples/hierarchy/.prettierrc.json
Normal file
6
examples/hierarchy/.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 100,
|
||||
"semi": false
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
8
examples/hierarchy/next.config.mjs
Normal file
8
examples/hierarchy/next.config.mjs
Normal file
@@ -0,0 +1,8 @@
|
||||
import { withPayload } from '@payloadcms/next/withPayload'
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
// Your Next.js config here
|
||||
}
|
||||
|
||||
export default withPayload(nextConfig)
|
||||
@@ -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
5880
examples/hierarchy/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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)
|
||||
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
0
examples/hierarchy/src/app/(payload)/custom.scss
Normal file
0
examples/hierarchy/src/app/(payload)/custom.scss
Normal file
16
examples/hierarchy/src/app/(payload)/layout.tsx
Normal file
16
examples/hierarchy/src/app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import configPromise from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import { RootLayout } from '@payloadcms/next/layouts'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import React from 'react'
|
||||
|
||||
import './custom.scss'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
|
||||
|
||||
export default Layout
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -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()
|
||||
@@ -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
@@ -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
|
||||
|
||||
7
examples/virtual-fields/.eslintrc.cjs
Normal file
7
examples/virtual-fields/.eslintrc.cjs
Normal file
@@ -0,0 +1,7 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
project: ['./tsconfig.json'],
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
}
|
||||
46
examples/virtual-fields/.gitignore
vendored
46
examples/virtual-fields/.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -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
5184
examples/virtual-fields/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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)
|
||||
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
16
examples/virtual-fields/src/app/(payload)/layout.tsx
Normal file
16
examples/virtual-fields/src/app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import configPromise from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import { RootLayout } from '@payloadcms/next/layouts'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import React from 'react'
|
||||
|
||||
import './custom.scss'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
|
||||
|
||||
export default Layout
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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'),
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
];
|
||||
]
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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: [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
7
examples/whitelabel/.eslintrc.cjs
Normal file
7
examples/whitelabel/.eslintrc.cjs
Normal file
@@ -0,0 +1,7 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
project: ['./tsconfig.json'],
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
}
|
||||
43
examples/whitelabel/.gitignore copy
Normal file
43
examples/whitelabel/.gitignore copy
Normal file
@@ -0,0 +1,43 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
.yarn/install-state.gz
|
||||
|
||||
/.idea/*
|
||||
!/.idea/runConfigurations
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
.env
|
||||
|
||||
/media
|
||||
1
examples/whitelabel/.npmrc copy
Normal file
1
examples/whitelabel/.npmrc copy
Normal file
@@ -0,0 +1 @@
|
||||
legacy-peer-deps=true
|
||||
5
examples/whitelabel/next-env.d.ts
vendored
Normal file
5
examples/whitelabel/next-env.d.ts
vendored
Normal 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.
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/nodemon.json",
|
||||
"ext": "ts",
|
||||
"exec": "ts-node src/server.ts -- -I",
|
||||
"stdin": false
|
||||
@@ -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
5184
examples/whitelabel/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 842 B After Width: | Height: | Size: 842 B |
|
Before Width: | Height: | Size: 346 KiB After Width: | Height: | Size: 346 KiB |
@@ -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
|
||||
@@ -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)
|
||||
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
0
examples/whitelabel/src/app/(payload)/custom.scss
Normal file
0
examples/whitelabel/src/app/(payload)/custom.scss
Normal file
16
examples/whitelabel/src/app/(payload)/layout.tsx
Normal file
16
examples/whitelabel/src/app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import configPromise from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import { RootLayout } from '@payloadcms/next/layouts'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import React from 'react'
|
||||
|
||||
import './custom.scss'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
|
||||
|
||||
export default Layout
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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'),
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
@@ -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);
|
||||
@@ -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
66
package.json
66
package.json
@@ -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/*"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
})
|
||||
```
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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": []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
@@ -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,
|
||||
) => {
|
||||
@@ -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!')
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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]
|
||||
@@ -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()
|
||||
@@ -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'
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user