chore(examples/multi-tenant): migrates to 2.0 (#3512)

This commit is contained in:
Jacob Fletcher
2023-10-09 14:02:44 -04:00
committed by GitHub
parent 4ff6d63c94
commit b5c56efb4b
31 changed files with 1940 additions and 1623 deletions

View File

@@ -1,5 +1,5 @@
MONGODB_URI=mongodb://127.0.0.1/payload-example-auth
PAYLOAD_SECRET=PAYLOAD_AUTH_EXAMPLE_SECRET_KEY
DATABASE_URI=mongodb://127.0.0.1/payload-example-multi-tenant
PAYLOAD_SECRET=PAYLOAD_MULTI_TENANT_EXAMPLE_SECRET_KEY
PAYLOAD_PUBLIC_SERVER_URL=http://localhost:3000
PAYLOAD_SEED=true
PAYLOAD_DROP_DATABASE=true

View File

@@ -10,7 +10,7 @@ To spin up this example locally, follow these steps:
1. Then `cd YOUR_PROJECT_REPO && cp .env.example .env`
1. Next `yarn && yarn dev`
1. Now `open http://localhost:3000/admin` to access the admin panel
1. Login with email `dev@payloadcms.com` and password `test`
1. Login with email `demo@payloadcms.com` and password `demo`
That's it! Changes made in `./src` will be reflected in your app. See the [Development](#development) section for more details on how to log in as a tenant.
@@ -79,7 +79,7 @@ To spin up this example locally, follow the [Quick Start](#quick-start).
### Seed
On boot, a seed script is included to scaffold a basic database for you to use as an example. This is done by setting the `PAYLOAD_DROP_DATABASE` and `PAYLOAD_SEED` environment variables which are included in the `.env.example` by default. You can remove these from your `.env` to prevent this behavior. You can also freshly seed your project at any time by running `yarn seed`. This seed creates a super-admin user with email `dev@payloadcms.com` and password `test` along with the following tenants:
On boot, a seed script is included to scaffold a basic database for you to use as an example. This is done by setting the `PAYLOAD_DROP_DATABASE` and `PAYLOAD_SEED` environment variables which are included in the `.env.example` by default. You can remove these from your `.env` to prevent this behavior. You can also freshly seed your project at any time by running `yarn seed`. This seed creates a super-admin user with email `demo@payloadcms.com` and password `demo` along with the following tenants:
- `ABC`
- Domains:

View File

@@ -18,6 +18,9 @@
"lint:fix": "eslint --fix --ext .ts,.tsx src"
},
"dependencies": {
"@payloadcms/bundler-webpack": "^1.0.0-beta.5",
"@payloadcms/db-mongodb": "^1.0.0-beta.8",
"@payloadcms/richtext-slate": "^1.0.0-beta.4",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"payload": "latest"
@@ -43,4 +46,4 @@
"ts-node": "^9.1.1",
"typescript": "^4.8.4"
}
}
}

View File

@@ -1,6 +1,6 @@
import type { Access } from 'payload/config'
import { checkUserRoles } from '../../utilities/checkUserRoles'
import { checkUserRoles } from '../../../utilities/checkUserRoles'
// the user must be an admin of the document's tenant
export const tenantAdmins: Access = ({ req: { user } }) => {

View File

@@ -1,6 +1,6 @@
import type { Access } from 'payload/types'
import { isSuperAdmin } from '../../utilities/isSuperAdmin'
import { isSuperAdmin } from '../../../utilities/isSuperAdmin'
export const tenants: Access = ({ req: { user }, data }) =>
// individual documents

View File

@@ -1,7 +1,7 @@
import type { CollectionConfig } from 'payload/types'
import richText from '../fields/richText'
import { tenant } from '../fields/tenant'
import richText from '../../fields/richText'
import { tenant } from '../../fields/tenant'
import { loggedIn } from './access/loggedIn'
import { tenantAdmins } from './access/tenantAdmins'
import { tenants } from './access/tenants'

View File

@@ -1,6 +1,6 @@
import type { Access } from 'payload/config'
import { isSuperAdmin } from '../../utilities/isSuperAdmin'
import { isSuperAdmin } from '../../../utilities/isSuperAdmin'
// the user must be an admin of the tenant being accessed
export const tenantAdmins: Access = ({ req: { user } }) => {

View File

@@ -1,6 +1,6 @@
import type { CollectionConfig } from 'payload/types'
import { superAdmins } from '../access/superAdmins'
import { superAdmins } from '../../access/superAdmins'
import { tenantAdmins } from './access/tenantAdmins'
export const Tenants: CollectionConfig = {

View File

@@ -1,7 +1,7 @@
import type { Access } from 'payload/config'
import type { User } from 'payload/generated-types'
import { isSuperAdmin } from '../../utilities/isSuperAdmin'
import { isSuperAdmin } from '../../../utilities/isSuperAdmin'
import { User } from '../../../payload-types'
export const adminsAndSelf: Access<any, User> = async ({ req: { user } }) => {
if (user) {

View File

@@ -1,6 +1,6 @@
import type { FieldAccess } from 'payload/types'
import { checkUserRoles } from '../../utilities/checkUserRoles'
import { checkUserRoles } from '../../../utilities/checkUserRoles'
import { checkTenantRoles } from '../utilities/checkTenantRoles'
export const tenantAdmins: FieldAccess = args => {

View File

@@ -1,7 +1,7 @@
import type { CollectionConfig } from 'payload/types'
import { anyone } from '../access/anyone'
import { superAdminFieldAccess } from '../access/superAdmins'
import { anyone } from '../../access/anyone'
import { superAdminFieldAccess } from '../../access/superAdmins'
import { adminsAndSelf } from './access/adminsAndSelf'
import { tenantAdmins } from './access/tenantAdmins'
import { loginAfterCreate } from './hooks/loginAfterCreate'

View File

@@ -1,6 +1,6 @@
import type { PayloadRequest } from 'payload/dist/types'
import { isSuperAdmin } from '../../utilities/isSuperAdmin'
import { isSuperAdmin } from '../../../utilities/isSuperAdmin'
const logs = false

View File

@@ -1,5 +0,0 @@
import type { RichTextElement } from 'payload/dist/fields/config/types'
const elements: RichTextElement[] = ['blockquote', 'h2', 'h3', 'h4', 'h5', 'h6', 'link']
export default elements

View File

@@ -1,86 +0,0 @@
import type { RichTextElement, RichTextField, RichTextLeaf } from 'payload/dist/fields/config/types'
import deepMerge from '../../utilities/deepMerge'
import link from '../link'
import elements from './elements'
import leaves from './leaves'
type RichText = (
overrides?: Partial<RichTextField>,
additions?: {
elements?: RichTextElement[]
leaves?: RichTextLeaf[]
},
) => RichTextField
const richText: RichText = (
overrides,
additions = {
elements: [],
leaves: [],
},
) =>
deepMerge<RichTextField, Partial<RichTextField>>(
{
name: 'richText',
type: 'richText',
required: true,
admin: {
upload: {
collections: {
media: {
fields: [
{
type: 'richText',
name: 'caption',
label: 'Caption',
admin: {
elements: [...elements],
leaves: [...leaves],
},
},
{
type: 'radio',
name: 'alignment',
label: 'Alignment',
options: [
{
label: 'Left',
value: 'left',
},
{
label: 'Center',
value: 'center',
},
{
label: 'Right',
value: 'right',
},
],
},
{
name: 'enableLink',
type: 'checkbox',
label: 'Enable Link',
},
link({
appearances: false,
disableLabel: true,
overrides: {
admin: {
condition: (_, data) => Boolean(data?.enableLink),
},
},
}),
],
},
},
},
elements: [...elements, ...(additions.elements || [])],
leaves: [...leaves, ...(additions.leaves || [])],
},
},
overrides,
)
export default richText

View File

@@ -0,0 +1,3 @@
module.exports = {
config: () => null,
}

View File

@@ -0,0 +1,5 @@
import type { RichTextElement } from '@payloadcms/richtext-slate'
const elements: RichTextElement[] = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'link']
export default elements

View File

@@ -0,0 +1,92 @@
import { slateEditor } from '@payloadcms/richtext-slate'
import type { RichTextElement, RichTextLeaf } from '@payloadcms/richtext-slate/dist/types'
import type { RichTextField } from 'payload/types'
import deepMerge from '../../utilities/deepMerge'
import link from '../link'
import elements from './elements'
import leaves from './leaves'
type RichText = (
overrides?: Partial<RichTextField>,
additions?: {
elements?: RichTextElement[]
leaves?: RichTextLeaf[]
},
) => RichTextField
const richText: RichText = (
overrides,
additions = {
elements: [],
leaves: [],
},
) =>
deepMerge<RichTextField, Partial<RichTextField>>(
{
name: 'richText',
type: 'richText',
required: true,
editor: slateEditor({
admin: {
upload: {
collections: {
media: {
fields: [
{
type: 'richText',
name: 'caption',
label: 'Caption',
editor: slateEditor({
admin: {
elements: [...elements],
leaves: [...leaves],
},
}),
},
{
type: 'radio',
name: 'alignment',
label: 'Alignment',
options: [
{
label: 'Left',
value: 'left',
},
{
label: 'Center',
value: 'center',
},
{
label: 'Right',
value: 'right',
},
],
},
{
name: 'enableLink',
type: 'checkbox',
label: 'Enable Link',
},
link({
appearances: false,
disableLabel: true,
overrides: {
admin: {
condition: (_, data) => Boolean(data?.enableLink),
},
},
}),
],
},
},
},
elements: [...elements, ...(additions.elements || [])],
leaves: [...leaves, ...(additions.leaves || [])],
},
}),
},
overrides,
)
export default richText

View File

@@ -1,4 +1,4 @@
import type { RichTextLeaf } from 'payload/dist/fields/config/types'
import { RichTextLeaf } from '@payloadcms/richtext-slate'
const defaultLeaves: RichTextLeaf[] = ['bold', 'italic', 'underline']

View File

@@ -1,4 +1,5 @@
/* tslint:disable */
/* eslint-disable */
/**
* This file was automatically generated by Payload.
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
@@ -10,6 +11,8 @@ export interface Config {
users: User
tenants: Tenant
pages: Page
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
globals: {}
}
@@ -17,18 +20,20 @@ export interface User {
id: string
firstName?: string
lastName?: string
roles: Array<'super-admin' | 'user'>
tenants?: Array<{
roles: ('super-admin' | 'user')[]
tenants?: {
tenant: string | Tenant
roles: Array<'admin' | 'user'>
roles: ('admin' | 'user')[]
id?: string
}>
}[]
lastLoggedInTenant?: string | Tenant
updatedAt: string
createdAt: string
email?: string
email: string
resetPasswordToken?: string
resetPasswordExpiration?: string
salt?: string
hash?: string
loginAttempts?: number
lockUntil?: string
password?: string
@@ -36,10 +41,10 @@ export interface User {
export interface Tenant {
id: string
name: string
domains: Array<{
domains?: {
domain: string
id?: string
}>
}[]
updatedAt: string
createdAt: string
}
@@ -48,9 +53,47 @@ export interface Page {
title: string
slug?: string
tenant?: string | Tenant
richText: Array<{
richText: {
[k: string]: unknown
}>
}[]
updatedAt: string
createdAt: string
}
export interface PayloadPreference {
id: string
user: {
relationTo: 'users'
value: string | User
}
key?: string
value?:
| {
[k: string]: unknown
}
| unknown[]
| string
| number
| boolean
| null
updatedAt: string
createdAt: string
}
export interface PayloadMigration {
id: string
name?: string
batch?: number
updatedAt: string
createdAt: string
}
declare module 'payload' {
export interface GeneratedTypes {
collections: {
users: User
tenants: Tenant
pages: Page
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
}
}

View File

@@ -1,3 +1,6 @@
import { webpackBundler } from '@payloadcms/bundler-webpack'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { slateEditor } from '@payloadcms/richtext-slate'
import dotenv from 'dotenv'
import path from 'path'
@@ -13,6 +16,23 @@ import { Users } from './collections/Users'
export default buildConfig({
collections: [Users, Tenants, Pages],
admin: {
bundler: webpackBundler(),
webpack: config => ({
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
dotenv: path.resolve(__dirname, './dotenv.js'),
},
},
}),
},
editor: slateEditor({}),
db: mongooseAdapter({
url: process.env.DATABASE_URI,
}),
typescript: {
outputFile: path.resolve(__dirname, 'payload-types.ts'),
},

View File

@@ -5,8 +5,8 @@ export const seed = async (payload: Payload): Promise<void> => {
await payload.create({
collection: 'users',
data: {
email: 'dev@payloadcms.com',
password: 'test',
email: 'demo@payloadcms.com',
password: 'demo',
roles: ['super-admin'],
},
})

View File

@@ -1,4 +1,4 @@
import type { User } from '../../payload-types'
import type { User } from '../payload-types'
export const checkUserRoles = (allRoles: User['roles'] = [], user: User = undefined): boolean => {
if (user) {

View File

@@ -1,5 +1,4 @@
import type { User } from 'payload/generated-types'
import { User } from '../payload-types'
import { checkUserRoles } from './checkUserRoles'
export const isSuperAdmin = (user: User): boolean => checkUserRoles(['super-admin'], user)

View File

@@ -16,7 +16,6 @@
"sourceMap": true,
"resolveJsonModule": true,
"paths": {
"payload/generated-types": ["./src/payload-types.ts"],
"node_modules/*": ["./node_modules/*"]
},
},

File diff suppressed because it is too large Load Diff