Compare commits

..

1 Commits

Author SHA1 Message Date
Dan Ribbens
44231b55cb fix(db-mongodb): error querying with invalid value on date field 2024-01-15 13:48:56 -05:00
358 changed files with 4957 additions and 16691 deletions

View File

@@ -2,9 +2,9 @@ name: build
on:
pull_request:
types: [ opened, reopened, synchronize ]
types: [opened, reopened, synchronize]
push:
branches: [ 'main' ]
branches: ['main']
jobs:
changes:
@@ -15,25 +15,25 @@ jobs:
needs_build: ${{ steps.filter.outputs.needs_build }}
templates: ${{ steps.filter.outputs.templates }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 25
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
needs_build:
- '.github/workflows/**'
- 'packages/**'
- 'test/**'
- 'pnpm-lock.yaml'
- 'package.json'
templates:
- 'templates/**'
- name: Log all filter results
run: |
echo "needs_build: ${{ steps.filter.outputs.needs_build }}"
echo "templates: ${{ steps.filter.outputs.templates }}"
- uses: actions/checkout@v4
with:
fetch-depth: 25
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
needs_build:
- '.github/workflows/**'
- 'packages/**'
- 'test/**'
- 'pnpm-lock.yaml'
- 'package.json'
templates:
- 'templates/**'
- name: Log all filter results
run: |
echo "needs_build: ${{ steps.filter.outputs.needs_build }}"
echo "templates: ${{ steps.filter.outputs.templates }}"
core-build:
needs: changes
@@ -85,15 +85,11 @@ jobs:
strategy:
fail-fast: false
matrix:
database: [mongoose, postgres, postgres-custom-schema, postgres-uuid, supabase]
database: [mongoose, postgres]
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: payloadtests
AWS_ENDPOINT_URL: http://127.0.0.1:4566
AWS_ACCESS_KEY_ID: localstack
AWS_SECRET_ACCESS_KEY: localstack
AWS_REGION: us-east-1
steps:
- name: Use Node.js 18
@@ -113,9 +109,6 @@ jobs:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- name: Start LocalStack
run: pnpm docker:start
- name: Start PostgreSQL
uses: CasperWA/postgresql-action@v1.2
with:
@@ -123,40 +116,15 @@ jobs:
postgresql db: ${{ env.POSTGRES_DB }}
postgresql user: ${{ env.POSTGRES_USER }}
postgresql password: ${{ env.POSTGRES_PASSWORD }}
if: startsWith(matrix.database, 'postgres')
- name: Install Supabase CLI
uses: supabase/setup-cli@v1
with:
version: latest
if: matrix.database == 'supabase'
- name: Initialize Supabase
run: |
supabase init
supabase start
if: matrix.database == 'supabase'
- name: Wait for PostgreSQL
run: sleep 30
if: startsWith(matrix.database, 'postgres')
if: matrix.database == 'postgres'
- run: sleep 30
- name: Configure PostgreSQL
run: |
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "CREATE ROLE runner SUPERUSER LOGIN;"
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "SELECT version();"
echo "POSTGRES_URL=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" >> $GITHUB_ENV
if: startsWith(matrix.database, 'postgres')
- name: Configure PostgreSQL with custom schema
run: |
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "CREATE SCHEMA custom;"
if: matrix.database == 'postgres-custom-schema'
- name: Configure Supabase
run: |
echo "POSTGRES_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres" >> $GITHUB_ENV
if: matrix.database == 'supabase'
if: matrix.database == 'postgres'
- name: Component Tests
run: pnpm test:components
@@ -174,7 +142,7 @@ jobs:
strategy:
fail-fast: false
matrix:
part: [ 1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 8/8 ]
part: [1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 8/8]
steps:
- name: Use Node.js 18
@@ -322,7 +290,7 @@ jobs:
strategy:
fail-fast: false
matrix:
template: [ blank, website, ecommerce ]
template: [blank, website, ecommerce]
steps:
- uses: actions/checkout@v4

2
.gitignore vendored
View File

@@ -6,9 +6,7 @@ dist
test-results
.devcontainer
.localstack
/migrations
.localstack
# Created by https://www.toptal.com/developers/gitignore/api/node,macos,windows,webstorm,sublimetext,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=node,macos,windows,webstorm,sublimetext,visualstudiocode

View File

@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Dev Fields" type="NodeJSConfigurationType" application-parameters="fields" path-to-js-file="node_modules/.pnpm/nodemon@3.0.3/node_modules/nodemon/bin/nodemon.js" working-dir="$PROJECT_DIR$">
<configuration default="false" name="Run Dev Fields" type="NodeJSConfigurationType" application-parameters="fields" path-to-js-file="node_modules/.pnpm/nodemon@3.0.1/node_modules/nodemon/bin/nodemon.js" working-dir="$PROJECT_DIR$">
<method v="2" />
</configuration>
</component>

View File

@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Dev _community" type="NodeJSConfigurationType" application-parameters="_community" path-to-js-file="node_modules/.pnpm/nodemon@3.0.3/node_modules/nodemon/bin/nodemon.js" working-dir="$PROJECT_DIR$">
<configuration default="false" name="Run Dev _community" type="NodeJSConfigurationType" application-parameters="_community" path-to-js-file="node_modules/.pnpm/nodemon@3.0.1/node_modules/nodemon/bin/nodemon.js" working-dir="$PROJECT_DIR$">
<method v="2" />
</configuration>
</component>

View File

@@ -1,153 +1,3 @@
## [2.12.0](https://github.com/payloadcms/payload/compare/v2.11.2...v2.12.0) (2024-04-03)
### Features
* **plugin-seo:** adds Norwegian translation ([#5621](https://github.com/payloadcms/payload/issues/5621)) ([589b492](https://github.com/payloadcms/payload/commit/589b492b2e6bc578e6f17649ff6d936ffd88b8b5))
* **richtext-*:** add ability to provide custom Field and Error components ([#5574](https://github.com/payloadcms/payload/issues/5574)) ([02d2c51](https://github.com/payloadcms/payload/commit/02d2c517176a775c6eeb4b164d9e6b45d8f5e4c1))
### Bug Fixes
* **db-postgres:** error on delete having joins ([#5459](https://github.com/payloadcms/payload/issues/5459)) ([9169230](https://github.com/payloadcms/payload/commit/916923071a2c28077326bfd2059d1665ef47e94f))
* image resize tiff files ([#5415](https://github.com/payloadcms/payload/issues/5415)) ([8184e00](https://github.com/payloadcms/payload/commit/8184e0005af1b6da93d0921c31547515a4ce6343))
* number field with hasMany accept defaultValue array ([#5618](https://github.com/payloadcms/payload/issues/5618)) ([a3ae416](https://github.com/payloadcms/payload/commit/a3ae4160850290c194bb228e1fbeb8c7533cead3))
* regression of filterOptions using different transaction ([#5169](https://github.com/payloadcms/payload/issues/5169)) ([3ceb6ef](https://github.com/payloadcms/payload/commit/3ceb6efd32cfa9556c6656469fa43d61d7679b1d))
* **richtext-lexical:** Blocks: generated output schema is not fully correct ([#5259](https://github.com/payloadcms/payload/issues/5259)) ([e7f6bfb](https://github.com/payloadcms/payload/commit/e7f6bfbe9da4cab42c7ec7019371d5e79af17ec9))
* **richtext-lexical:** checklist html converter incorrectly outputting children ([#5570](https://github.com/payloadcms/payload/issues/5570)) ([2e5400f](https://github.com/payloadcms/payload/commit/2e5400fa7a5ac7441e00134a7f4299022228f64f))
* **richtext-lexical:** disable instanceof HTMLImageElement check as it causes issues when used on the server ([2164dcc](https://github.com/payloadcms/payload/commit/2164dcc594b5c16d7111b71cdb01f5f7aaa7e127))
* **richtext-lexical:** Link: add open-in-new-tab to html converter ([23df60d](https://github.com/payloadcms/payload/commit/23df60dba5682255ce6f60e3ee8e6901f6a70c7b))
* **richtext-lexical:** properly center add- and drag-block handles ([#5568](https://github.com/payloadcms/payload/issues/5568)) ([48dc116](https://github.com/payloadcms/payload/commit/48dc116f57113c3124ff93a50fa1189053e21d76))
* sets beforeValidateHook req type to required ([#5608](https://github.com/payloadcms/payload/issues/5608)) ([e10d5df](https://github.com/payloadcms/payload/commit/e10d5df0b2dd21b86cce44d0e36b31e9d3411b39))
## [2.11.2](https://github.com/payloadcms/payload/compare/v2.11.1...v2.11.2) (2024-02-23)
### Features
* **db-postgres:** configurable custom schema to use ([#5047](https://github.com/payloadcms/payload/issues/5047)) ([e8f2ca4](https://github.com/payloadcms/payload/commit/e8f2ca484ee56cd7767d5111e46ebd24752ff8de))
### Bug Fixes
* Add Context Provider in EditMany Component ([#5005](https://github.com/payloadcms/payload/issues/5005)) ([70e57fe](https://github.com/payloadcms/payload/commit/70e57fef184f7fcf56344ea755465f246f2253a5))
* **db-mongodb:** unique sparse for not required fields ([#5114](https://github.com/payloadcms/payload/issues/5114)) ([815bdfa](https://github.com/payloadcms/payload/commit/815bdfac0b0afbff2a20e54d5aee64b90f6b3a77))
* **db-postgres:** set _parentID for array nested localized fields ([#5117](https://github.com/payloadcms/payload/issues/5117)) ([ceca5c4](https://github.com/payloadcms/payload/commit/ceca5c4e97f53f1346797a31b6abfc0375e98215))
* disabling API Key does not remove the key ([#5145](https://github.com/payloadcms/payload/issues/5145)) ([7a7f0ed](https://github.com/payloadcms/payload/commit/7a7f0ed7e8132253be607c111c160163b84bd770))
* handle thrown errors in config-level afterError hook ([#5147](https://github.com/payloadcms/payload/issues/5147)) ([32ed95e](https://github.com/payloadcms/payload/commit/32ed95e1ee87409db234f1b7bd6d2e462fd9ed5d))
* only replace the drawer content with full edit component if it exists ([#5144](https://github.com/payloadcms/payload/issues/5144)) ([0a07f60](https://github.com/payloadcms/payload/commit/0a07f607b9fb1217ad956cd05b2a84a4042a19ca))
* transaction error from access endpoint ([#5156](https://github.com/payloadcms/payload/issues/5156)) ([ad42d54](https://github.com/payloadcms/payload/commit/ad42d541b342ed56463b81cee6d6307df6f06d7f))
## [2.11.1](https://github.com/payloadcms/payload/compare/v2.11.0...v2.11.1) (2024-02-16)
### Features
* **db-postgres:** adds idType to use uuid or serial id columns ([#3864](https://github.com/payloadcms/payload/issues/3864)) ([d6c2578](https://github.com/payloadcms/payload/commit/d6c25783cfa97983bf9db27ceb5ccd39a62c62f1))
* **db-postgres:** reconnect after disconnection from database ([#5086](https://github.com/payloadcms/payload/issues/5086)) ([bf942fd](https://github.com/payloadcms/payload/commit/bf942fdfa6ea9c26cf05295cc9db646bf31fa622))
* **plugin-search:** add req to beforeSync args for transactions ([#5068](https://github.com/payloadcms/payload/issues/5068)) ([98b87e2](https://github.com/payloadcms/payload/commit/98b87e22782c0a788f79326f22be05a6b176ad74))
* **richtext-lexical:** add justify aligment to AlignFeature ([#4035](https://github.com/payloadcms/payload/issues/4035)) ([#4868](https://github.com/payloadcms/payload/issues/4868)) ([6d6823c](https://github.com/payloadcms/payload/commit/6d6823c3e5609a58eeeeb8d043945a762f9463df))
* **richtext-lexical:** AddBlock handle for all nodes, even if they aren't empty paragraphs ([#5063](https://github.com/payloadcms/payload/issues/5063)) ([00fc034](https://github.com/payloadcms/payload/commit/00fc0343dabf184d5bab418d47c403b3ad11698f))
* **richtext-lexical:** Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground ([#5066](https://github.com/payloadcms/payload/issues/5066)) ([0d18822](https://github.com/payloadcms/payload/commit/0d18822062275c1826c8e2c3da2571a2b3483310))
### Bug Fixes
* **db-mongodb:** find versions pagination ([#5091](https://github.com/payloadcms/payload/issues/5091)) ([5d4022f](https://github.com/payloadcms/payload/commit/5d4022f1445e2809c01cb1dd599280f0a56cdc6e))
* **db-postgres:** query using blockType ([#5044](https://github.com/payloadcms/payload/issues/5044)) ([35c2a08](https://github.com/payloadcms/payload/commit/35c2a085efa6d5ad59779960874bc9728a17e3a0))
* filterOptions errors cause transaction to abort ([#5079](https://github.com/payloadcms/payload/issues/5079)) ([5f3d016](https://github.com/payloadcms/payload/commit/5f3d0169bee21e1c0963dbd7ede9fe5f1c46a5a5))
* **plugin-form-builder:** hooks do not respect transactions ([#5069](https://github.com/payloadcms/payload/issues/5069)) ([82e9d31](https://github.com/payloadcms/payload/commit/82e9d31127c8df83c5bed92a5ffdab76d331900f))
* remove collection findByID caching ([#5034](https://github.com/payloadcms/payload/issues/5034)) ([1ac943e](https://github.com/payloadcms/payload/commit/1ac943ed5e8416883b863147fdf3c23380955559))
* **richtext-lexical:** do not remove adjacent paragraph node when inserting certain nodes in empty editor ([#5061](https://github.com/payloadcms/payload/issues/5061)) ([6323965](https://github.com/payloadcms/payload/commit/6323965c652ea68dffeb716957b124d165b9ce96))
* **uploads:** account for serverURL when retrieving external file ([#5102](https://github.com/payloadcms/payload/issues/5102)) ([25cee8b](https://github.com/payloadcms/payload/commit/25cee8bb102bf80b3a4bfb4b4e46712722cc7f0d))
### ⚠ BREAKING CHANGES: @payloadcms/richtext-lexical
* **richtext-lexical:** Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground (#5066)
- You HAVE to make sure that any versions of the lexical packages (IF you have any installed) match the lexical version which richtext-lexical uses: v0.13.1. If you do not do this, you may be plagued by React useContext / "cannot find active editor state" errors
- Updates to lexical's API, e.g. the removal of INTERNAL_isPointSelection, could be breaking depending on your code. Please consult the [lexical changelog](https://github.com/facebook/lexical/blob/main/CHANGELOG.md).
## [2.11.0](https://github.com/payloadcms/payload/compare/v2.10.1...v2.11.0) (2024-02-09)
### Features
* exposes collapsible provider with more functionality ([#5043](https://github.com/payloadcms/payload/issues/5043)) ([df39602](https://github.com/payloadcms/payload/commit/df39602758ae8dc3765bb48e51f7a657babfa559))
## [2.10.1](https://github.com/payloadcms/payload/compare/v2.10.0...v2.10.1) (2024-02-09)
### Bug Fixes
* clearable cells handle null values ([#5038](https://github.com/payloadcms/payload/issues/5038)) ([f6d7da7](https://github.com/payloadcms/payload/commit/f6d7da751039df25066b51bb91d6453e1a4efd82))
* **db-mongodb:** handle null values with exists ([#5037](https://github.com/payloadcms/payload/issues/5037)) ([cdc4cb9](https://github.com/payloadcms/payload/commit/cdc4cb971b9180ba2ed09741f5af1a3c18292828))
* **db-postgres:** handle nested docs with drafts ([#5012](https://github.com/payloadcms/payload/issues/5012)) ([da184d4](https://github.com/payloadcms/payload/commit/da184d40ece74bffb224002eb5df8f6987d65043))
* ensures docs with the same id are shown in relationship field select ([#4859](https://github.com/payloadcms/payload/issues/4859)) ([e1813fb](https://github.com/payloadcms/payload/commit/e1813fb884e0dc84203fcbab87527a99a4d3a5d7))
* query relationships by explicit id field ([#5022](https://github.com/payloadcms/payload/issues/5022)) ([a0a58e7](https://github.com/payloadcms/payload/commit/a0a58e7fd20dff54d210c968f4d5defd67441bdd))
* **richtext-lexical:** make editor reactive to initialValue changes ([#5010](https://github.com/payloadcms/payload/issues/5010)) ([2315781](https://github.com/payloadcms/payload/commit/2315781f1891ddde4b4c5f2f0cfa1c17af85b7a9))
## [2.10.0](https://github.com/payloadcms/payload/compare/v2.9.0...v2.10.0) (2024-02-06)
### Features
* add more options to addFieldStatePromise so that it can be used for field flattening ([#4799](https://github.com/payloadcms/payload/issues/4799)) ([8725d41](https://github.com/payloadcms/payload/commit/8725d411645bb0270376e235669f46be2227ecc0))
* extend transactions to cover after and beforeOperation hooks ([#4960](https://github.com/payloadcms/payload/issues/4960)) ([1e8a6b7](https://github.com/payloadcms/payload/commit/1e8a6b7899f7b1e6451cc4d777602208478b483c))
* previousValue and previousSiblingDoc args added to beforeChange field hooks ([#4958](https://github.com/payloadcms/payload/issues/4958)) ([5d934ba](https://github.com/payloadcms/payload/commit/5d934ba02d07d98f781ce983228858ee5ce5c226))
* re-use existing logger instance passed to payload.init ([#3124](https://github.com/payloadcms/payload/issues/3124)) ([471d211](https://github.com/payloadcms/payload/commit/471d2113a790dc0d54b2f8ed84e6899310efd600))
* **richtext-lexical:** Blocks: generate type definitions for blocks fields ([#4529](https://github.com/payloadcms/payload/issues/4529)) ([90d7ee3](https://github.com/payloadcms/payload/commit/90d7ee3e6535d51290fc734b284ff3811dbda1f8))
* use deletion success message from server if provided ([#4966](https://github.com/payloadcms/payload/issues/4966)) ([e3c8105](https://github.com/payloadcms/payload/commit/e3c8105cc2ed6fdf8007d97cd7b5556fc71ed724))
### Bug Fixes
* **db-postgres:** filtering relationships with drafts enabled ([#4998](https://github.com/payloadcms/payload/issues/4998)) ([c3a3942](https://github.com/payloadcms/payload/commit/c3a39429697e9d335e9be199e7caafb82eb26219))
* **db-postgres:** handle schema changes with supabase ([#4968](https://github.com/payloadcms/payload/issues/4968)) ([5d3659d](https://github.com/payloadcms/payload/commit/5d3659d48ad8bbf5d96fbcd80434d2287cab97e0))
* **db-postgres:** indexes not created for non unique field names ([#4967](https://github.com/payloadcms/payload/issues/4967)) ([64f705c](https://github.com/payloadcms/payload/commit/64f705c3c94148972f67e8175e718015760d6430))
* **db-postgres:** indexes not creating for relationships, arrays, hasmany and blocks ([#4976](https://github.com/payloadcms/payload/issues/4976)) ([47106d5](https://github.com/payloadcms/payload/commit/47106d5a1af2ebd073fbbc6e474174c3d3835e5c))
* **db-postgres:** localized field sort count ([#4997](https://github.com/payloadcms/payload/issues/4997)) ([f3876c2](https://github.com/payloadcms/payload/commit/f3876c2a39efe19a1864213306725aadcc14f130))
* ensures docPermissions fallback to collection permissions on create ([#4969](https://github.com/payloadcms/payload/issues/4969)) ([afa2b94](https://github.com/payloadcms/payload/commit/afa2b942e0aad90c55744ae13e0ffe1cefa4585d))
* **migrations:** safely create migration file when no name passed ([#4995](https://github.com/payloadcms/payload/issues/4995)) ([0740d50](https://github.com/payloadcms/payload/commit/0740d5095ee1aef13e4e37f6b174d529f0f2d993))
* **plugin-seo:** tabbedUI with email field causes duplicate field ([#4944](https://github.com/payloadcms/payload/issues/4944)) ([db22cbd](https://github.com/payloadcms/payload/commit/db22cbdf21a39ed0604ab96c57ca4242eac82ce7))
## [2.9.0](https://github.com/payloadcms/payload/compare/v2.8.2...v2.9.0) (2024-01-26)
### Features
* forceAcceptWarning migration arg added to accept prompts ([#4874](https://github.com/payloadcms/payload/issues/4874)) ([eba53ba](https://github.com/payloadcms/payload/commit/eba53ba60afd7c5d37389377ed06a9b556058d49))
### Bug Fixes
* afterLogin hook write conflicts ([#4904](https://github.com/payloadcms/payload/issues/4904)) ([3eb681e](https://github.com/payloadcms/payload/commit/3eb681e847e9c55eaaa69c22bea4f4e66c7eac36))
* **db-postgres:** migrate down error ([#4861](https://github.com/payloadcms/payload/issues/4861)) ([dfba522](https://github.com/payloadcms/payload/commit/dfba5222f3abf3f236dc9212a28e1aec7d7214d5))
* **db-postgres:** query unset relation ([#4862](https://github.com/payloadcms/payload/issues/4862)) ([8ce15c8](https://github.com/payloadcms/payload/commit/8ce15c8b07800397a50dcf790c263ed5b3cfad53))
* migrate down missing filter for latest batch ([#4860](https://github.com/payloadcms/payload/issues/4860)) ([b99d24f](https://github.com/payloadcms/payload/commit/b99d24fcfa698c493ea01c41621201abe18fabe3))
* **plugin-cloud-storage:** slow get file performance large collections ([#4927](https://github.com/payloadcms/payload/issues/4927)) ([f73d503](https://github.com/payloadcms/payload/commit/f73d503fecdfa5cefdc26ab9aad60b00563f881e))
* remove No Options dropdown from hasMany fields ([#4899](https://github.com/payloadcms/payload/issues/4899)) ([e5a7907](https://github.com/payloadcms/payload/commit/e5a7907a72c1371447ac2f71fce213ed22246092))
* upload input drawer does not show draft versions ([#4903](https://github.com/payloadcms/payload/issues/4903)) ([6930c4e](https://github.com/payloadcms/payload/commit/6930c4e9f2200853121391ad8f8df48ea66c40a4))
## [2.8.2](https://github.com/payloadcms/payload/compare/v2.8.1...v2.8.2) (2024-01-16)
### Features
* **db-postgres:** support drizzle logging config ([#4809](https://github.com/payloadcms/payload/issues/4809)) ([371353f](https://github.com/payloadcms/payload/commit/371353f1535fbab4ebd9f56fc14fd10a30eec289))
* **plugin-form-builder:** add validation for form ID when creating a submission ([#4730](https://github.com/payloadcms/payload/pull/4730))
* **plugin-seo:** add support for interfaceName and fieldOverrides ([#4695](https://github.com/payloadcms/payload/pull/4695))
### Bug Fixes
* **db-mongodb:** mongodb versions creating duplicates ([#4825](https://github.com/payloadcms/payload/issues/4825)) ([a861311](https://github.com/payloadcms/payload/commit/a861311c5a98126700f98f9a2ab380782e754717))
* **db-mongodb:** transactionOptions=false typeErrors ([82383a5](https://github.com/payloadcms/payload/commit/82383a5b5f52785115c0feb970da70e91971b7ca))
* **db-postgres:** Remove duplicate keys from response ([#4747](https://github.com/payloadcms/payload/issues/4747)) ([eb9e771](https://github.com/payloadcms/payload/commit/eb9e771a9ca03636486d36654f215b73435574cb))
* **db-postgres:** validateExistingBlockIsIdentical with arrays ([3b88adc](https://github.com/payloadcms/payload/commit/3b88adc7d0594af63ce190c40c9ee3905df67a31))
* **db-postgres:** validateExistingBlockIsIdentical with other tables ([0647c87](https://github.com/payloadcms/payload/commit/0647c870f15dc1b122734b678c2abeb6f56377d4))
* **plugin-seo:** fix missing spread operator in URL generator function ([#4723](https://github.com/payloadcms/payload/pull/4723))
* removes max-width from field-types class & correctly sets it on uploads ([#4829](https://github.com/payloadcms/payload/issues/4829)) ([ee5390a](https://github.com/payloadcms/payload/commit/ee5390aaca37a4154cde8392b60f091ec3e5175c))
## [2.8.1](https://github.com/payloadcms/payload/compare/v2.8.0...v2.8.1) (2024-01-12)

View File

@@ -635,37 +635,6 @@ export const CustomArrayManager = () => {
]}
/>
### useCollapsible
The `useCollapsible` hook allows you to control parent collapsibles:
| Property | Description |
|---------------------------|--------------------------------------------------------------------------------------------------------------------|
| **`collapsed`** | State of the collapsible. `true` if open, `false` if collapsed |
| **`isVisible`** | If nested, determine if the nearest collapsible is visible. `true` if no parent is closed, `false` otherwise |
| **`toggle`** | Toggles the state of the nearest collapsible |
| **`withinCollapsible`** | Determine when you are within another collaspible | |
**Example:**
```tsx
import React from 'react'
import { useCollapsible } from 'payload/components/utilities'
const CustomComponent: React.FC = () => {
const { collapsed, toggle } = useCollapsible()
return (
<div>
<p className="field-type">I am {collapsed ? 'closed' : 'open'}</p>
<button onClick={toggle} type="button">
Toggle
</button>
</div>
)
}
```
### useDocumentInfo
The `useDocumentInfo` hook provides lots of information about the document currently being edited, including the following:

View File

@@ -37,12 +37,11 @@ export default buildConfig({
### Options
| Option | Description |
|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `pool` | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres`. |
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
| `migrationDir` | Customize the directory that migrations are stored. |
| `schemaName` | A string for the postgres schema to use, defaults to 'public'. |
| Option | Description |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pool` | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres`. |
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
| `migrationDir` | Customize the directory that migrations are stored. |
### Access to Drizzle

View File

@@ -28,7 +28,7 @@ This field uses the `monaco-react` editor syntax highlighting.
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`index`** | Build a an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |

View File

@@ -46,7 +46,6 @@ export const Page: CollectionConfig = {
- [Date](/docs/fields/date) - date / time field that saves a timestamp
- [Email](/docs/fields/email) - validates the entry is a properly formatted email
- [Group](/docs/fields/group) - nest fields within an object
- [JSON](/docs/fields/json) - saves actual JSON in the database
- [Number](/docs/fields/number) - field that enforces that its value be a number
- [Point](/docs/fields/point) - geometric coordinates for location data
- [Radio](/docs/fields/radio) - radio button group, allowing only one value to be selected

View File

@@ -38,7 +38,7 @@ caption="Admin panel screenshot of a Relationship field"
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`index`** | Build a an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |

View File

@@ -75,7 +75,6 @@ import { CollectionBeforeOperationHook } from 'payload/types'
const beforeOperationHook: CollectionBeforeOperationHook = async ({
args, // original arguments passed into the operation
operation, // name of the operation
req, // full express request
}) => {
return args // return modified operation arguments as necessary
}
@@ -210,7 +209,6 @@ import { CollectionAfterOperationHook } from 'payload/types'
const afterOperationHook: CollectionAfterOperationHook = async ({
args, // arguments passed into the operation
operation, // name of the operation
req, // full express request
result, // the result of the operation, before modifications
}) => {
return result // return modified result as necessary
@@ -292,11 +290,13 @@ For auth-enabled Collections, this hook runs after successful `forgotPassword` o
```ts
import { CollectionAfterForgotPasswordHook } from 'payload/types'
const afterForgotPasswordHook: CollectionAfterForgotPasswordHook = async ({
args, // arguments passed into the operation
context,
collection, // The collection which this hook is being run on
}) => {...}
const afterLoginHook: CollectionAfterForgotPasswordHook = async ({
req, // full express request
user, // user being logged in
token, // user token
}) => {
return user
}
```
## TypeScript

View File

@@ -6,8 +6,7 @@ desc: Hooks can be added to any fields, and optionally modify the return value o
keywords: hooks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
---
Field-level hooks offer incredible potential for encapsulating your logic. They help to isolate concerns and package up
functionalities to be easily reusable across your projects.
Field-level hooks offer incredible potential for encapsulating your logic. They help to isolate concerns and package up functionalities to be easily reusable across your projects.
**Example use cases include:**
@@ -47,8 +46,7 @@ const ExampleField: Field = {
## Arguments and return values
All field-level hooks are formatted to accept the same arguments, although some arguments may be `undefined` based on
which field hook you are utilizing.
All field-level hooks are formatted to accept the same arguments, although some arguments may be `undefined` based on which field hook you are utilizing.
<Banner type="success">
<strong>Tip:</strong>
@@ -71,10 +69,10 @@ Field Hooks receive one `args` argument that contains the following properties:
| **`operation`** | A string relating to which operation the field type is currently executing within. Useful within `beforeValidate`, `beforeChange`, and `afterChange` hooks to differentiate between `create` and `update` operations. |
| **`originalDoc`** | The full original document in `update` operations. In the `afterChange` hook, this is the resulting document of the operation. |
| **`previousDoc`** | The document before changes were applied, only in `afterChange` hooks. |
| **`previousSiblingDoc`** | The sibling data of the document before changes being applied, only in `beforeChange` and `afterChange` hook. |
| **`previousSiblingDoc`** | The sibling data from the previous document in `afterChange` hook. |
| **`req`** | The Express `request` object. It is mocked for Local API operations. |
| **`value`** | The value of the field. |
| **`previousValue`** | The previous value of the field, before changes, only in `beforeChange` and `afterChange` hooks. |
| **`previousValue`** | The previous value of the field, before changes were applied, only in `afterChange` hooks. |
| **`context`** | Context passed to this hook. More info can be found under [Context](/docs/hooks/context) |
| **`field`** | The field which the hook is running against. |
| **`collection`** | The collection which the field belongs to. If the field belongs to a global, this will be null. |
@@ -82,8 +80,7 @@ Field Hooks receive one `args` argument that contains the following properties:
#### Return value
All field hooks can optionally modify the return value of the field before the operation continues. Field Hooks may
optionally return the value that should be used within the field.
All field hooks can optionally modify the return value of the field before the operation continues. Field Hooks may optionally return the value that should be used within the field.
<Banner type="warning">
<strong>Important</strong>
@@ -95,14 +92,11 @@ optionally return the value that should be used within the field.
## Examples of Field Hooks
To better illustrate how field-level hooks can be applied, here are some specific examples. These demonstrate the
flexibility and potential of field hooks in different contexts. Remember, these examples are just a starting point - the
true potential of field-level hooks lies in their adaptability to a wide array of use cases.
To better illustrate how field-level hooks can be applied, here are some specific examples. These demonstrate the flexibility and potential of field hooks in different contexts. Remember, these examples are just a starting point - the true potential of field-level hooks lies in their adaptability to a wide array of use cases.
### beforeValidate
Runs before the `update` operation. This hook allows you to pre-process or format field data before it undergoes
validation.
Runs before the `update` operation. This hook allows you to pre-process or format field data before it undergoes validation.
```ts
import { Field } from 'payload/types'
@@ -119,15 +113,11 @@ const usernameField: Field = {
}
```
In this example, the `beforeValidate` hook is used to process the `username` field. The hook takes the incoming value of
the field and transforms it by trimming whitespace and converting it to lowercase. This ensures that the username is
stored in a consistent format in the database.
In this example, the `beforeValidate` hook is used to process the `username` field. The hook takes the incoming value of the field and transforms it by trimming whitespace and converting it to lowercase. This ensures that the username is stored in a consistent format in the database.
### beforeChange
Immediately following validation, `beforeChange` hooks will run within `create` and `update` operations. At this stage,
you can be confident that the field data that will be saved to the document is valid in accordance to your field
validations.
Immediately following validation, `beforeChange` hooks will run within `create` and `update` operations. At this stage, you can be confident that the field data that will be saved to the document is valid in accordance to your field validations.
```ts
import { Field } from 'payload/types'
@@ -146,14 +136,11 @@ const emailField: Field = {
}
```
In the `emailField`, the `beforeChange` hook checks the `operation` type. If the operation is `create`, it performs
additional validation or transformation on the email field value. This allows for operation-specific logic to be applied
to the field.
In the `emailField`, the `beforeChange` hook checks the `operation` type. If the operation is `create`, it performs additional validation or transformation on the email field value. This allows for operation-specific logic to be applied to the field.
### afterChange
The `afterChange` hook is executed after a field's value has been changed and saved in the database. This hook is useful
for post-processing or triggering side effects based on the new value of the field.
The `afterChange` hook is executed after a field's value has been changed and saved in the database. This hook is useful for post-processing or triggering side effects based on the new value of the field.
```ts
import { Field } from 'payload/types'
@@ -178,15 +165,11 @@ const membershipStatusField: Field = {
}
```
In this example, the `afterChange` hook is used with a `membershipStatusField`, which allows users to select their
membership level (Standard, Premium, VIP). The hook monitors changes in the membership status. When a change occurs, it
logs the update and can be used to trigger further actions, such as tracking conversion from one tier to another or
notifying them about changes in their membership benefits.
In this example, the `afterChange` hook is used with a `membershipStatusField`, which allows users to select their membership level (Standard, Premium, VIP). The hook monitors changes in the membership status. When a change occurs, it logs the update and can be used to trigger further actions, such as tracking conversion from one tier to another or notifying them about changes in their membership benefits.
### afterRead
The `afterRead` hook is invoked after a field value is read from the database. This is ideal for formatting or
transforming the field data for output.
The `afterRead` hook is invoked after a field value is read from the database. This is ideal for formatting or transforming the field data for output.
```ts
import { Field } from 'payload/types'
@@ -203,9 +186,8 @@ const dateField: Field = {
}
```
Here, the `afterRead` hook for the `dateField` is used to format the date into a more readable format
using `toLocaleDateString()`. This hook modifies the way the date is presented to the user, making it more
user-friendly.
Here, the `afterRead` hook for the `dateField` is used to format the date into a more readable format using `toLocaleDateString()`. This hook modifies the way the date is presented to the user, making it more user-friendly.
## TypeScript

View File

@@ -79,7 +79,7 @@ import { GlobalAfterChangeHook } from 'payload/types'
const afterChangeHook: GlobalAfterChangeHook = async ({
doc, // full document data
previousDoc, // document data before updating the global
previousDoc, // document data before updating the collection
req, // full express request
}) => {
return data

View File

@@ -36,7 +36,7 @@ If your Hook simply performs a side-effect, such as updating a CRM, it might be
#### Server-only execution
Payload Hooks are only triggered on the server. You can safely [remove your hooks](/docs/admin/webpack#aliasing-server-only-modules) from your Admin panel's client-side code by customizing the Webpack config, which not only keeps your Admin bundles' filesize small but also ensures that any server-side only code does not cause problems within browser environments.
Payload Hooks do not have any effect within the Payload Admin panel. You can safely [remove your hooks](/docs/admin/webpack#aliasing-server-only-modules) from your Admin panel's code by customizing the Webpack config, which not only keeps your Admin bundles' filesize small but also ensures that any server-side only code does not cause problems within browser environments.
## Hook Types

View File

@@ -290,5 +290,5 @@ If you&apos;ve configured tests for your package, integrate them into your workf
The best way to share and allow others to use your plugin once it is complete is to publish an NPM package. This process is straightforward and well documented, find out more about [creating and publishing a NPM package here](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
##### Add payload-plugin topic tag:
Apply the tag **payload-plugin** to your GitHub repository. This will boost the visibility of your plugin and ensure it gets listed with [existing payload plugins](https://github.com/topics/payload-plugin).
##### Use [Semantic Versioning](https://semver.org/) (SemVer):
With the SemVer system you release version numbers that reflect the nature of changes (major, minor, patch). Ensure all major versions reference their Payload compatibility.
##### Use [Semantic Versioning](https://semver.org/) (SemVar):
With the SemVar system you release version numbers that reflect the nature of changes (major, minor, patch). Ensure all major versions reference their Payload compatibility.

View File

@@ -98,7 +98,7 @@ formBuilder({
#### `beforeEmail`
The `beforeEmail` property is a [beforeChange](https://payloadcms.com/docs/hooks/globals#beforechange) hook that is called just after emails are prepared, but before they are sent. This is a great place to inject your own HTML template to add custom styles.
The `beforeEmail` property is a [beforeChange](<[beforeChange](https://payloadcms.com/docs/hooks/globals#beforechange)>) hook that is called just after emails are prepared, but before they are sent. This is a great place to inject your own HTML template to add custom styles.
```ts
// payload.config.ts

View File

@@ -218,7 +218,7 @@ const examplePageConfig: CollectionConfig = {
This plugin supports localization by default. If the `localization` property is set in your Payload config,
the `breadcrumbs` field is automatically localized. For more details on how localization works in Payload, see
the [Localization](https://payloadcms.com/docs/configuration/localization) docs.
the [Localization](https://payloadcms.com/docs/localization/overview) docs.
## TypeScript
@@ -235,5 +235,5 @@ official [Nested Docs Plugin Example](https://github.com/payloadcms/payload/tree
demonstrates exactly how to configure this plugin in Payload and implement it on your front-end.
The [Templates Directory](https://github.com/payloadcms/payload/tree/main/templates) also contains an
official [Website Template](https://github.com/payloadcms/payload/tree/main/templates/website)
and [E-commerce Template](https://github.com/payloadcms/payload/tree/main/templates/ecommerce), both of which use this
and [E-commerce Template](https://github.com/payloadcms/payload/tree/main/templates/ecommere), both of which use this
plugin.

View File

@@ -13,7 +13,7 @@ This plugin allows you to easily manage redirects for your application from with
For example, if you have a page at `/about` and you want to change it to `/about-us`, you can create a redirect from the old page to the new one, then you can use this data to write HTTP redirects into your front-end application. This will ensure that users are redirected to the correct page without penalty because search engines are notified of the change at the request level. This is a very lightweight plugin that will allow you to integrate managed redirects for any front-end framework.
<Banner type="info">
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-redirects). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%25redirects&template=bug_report.md&title=plugin-redirects%3A) with as much detail as possible.
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-redirects). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%redirects&template=bug_report.md&title=plugin-redirects%3A) with as much detail as possible.
</Banner>
##### Core features

View File

@@ -113,7 +113,7 @@ This plugin automatically creates the `search` collection, but you can override
#### `beforeSync`
Before creating or updating a search record, the `beforeSync` function runs. This is an [afterChange](https://payloadcms.com/docs/hooks/globals#afterchange) hook that allows you to modify the data or provide fallbacks before its search record is created or updated.
Before creating or updating a search record, the `beforeSync` function runs. This is an [afterChange](<[afterChange](https://payloadcms.com/docs/hooks/globals#afterchange)>) hook that allows you to modify the data or provide fallbacks before its search record is created or updated.
```ts
// payload.config.ts

View File

@@ -159,39 +159,6 @@ A function called by the search preview component to display the actual URL of y
}
```
#### `interfaceName`
Rename the meta group interface name that is generated for TypeScript and GraphQL.
```ts
// payload.config.ts
{
// ...
seoPlugin({
interfaceName: 'customInterfaceNameSEO'
})
}
```
#### `fieldOverrides`
Pass any valid field props to the base fields: Title, Description or Image.
```ts
// payload.config.ts
seoPlugin({
// ...
fieldOverrides: {
title: {
required: true,
},
description: {
localized: true,
},
},
})
```
## TypeScript
All types can be directly imported:
@@ -207,7 +174,7 @@ import {
## Examples
The [Templates Directory](https://github.com/payloadcms/payload/tree/main/templates) contains an official [Website Template](https://github.com/payloadcms/payload/tree/main/templates/website) and [E-commerce Template](https://github.com/payloadcms/payload/tree/main/templates/ecommerce) which demonstrates exactly how to configure this plugin in Payload and implement it on your front-end.
The [Templates Directory](https://github.com/payloadcms/payload/tree/main/templates) contains an official [Website Template](https://github.com/payloadcms/payload/tree/main/templates/website) and [E-commerce Template](https://github.com/payloadcms/payload/tree/main/templates/ecommere) which demonstrates exactly how to configure this plugin in Payload and implement it on your front-end.
## Screenshots

View File

@@ -20,7 +20,7 @@ To prevent DDoS, brute-force, and similar attacks, you can set IP-based rate lim
| Option | Description |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **`window`** | Time in milliseconds to track requests per IP. Defaults to `900000` (15 minutes). |
| **`window`** | Time in milliseconds to track requests per IP. Defaults to `90000` (15 minutes). |
| **`max`** | Number of requests served from a single IP before limiting. Defaults to `500`. |
| **`skip`** | Express middleware function that can return true (or promise resulting in true) that will bypass limit. |
| **`trustProxy`** | True or false, to enable to allow requests to pass through a proxy such as a load balancer or an `nginx` reverse proxy. |

View File

@@ -176,7 +176,7 @@ Next, take a look at the [features we've already built](https://github.com/paylo
Lexical saves data in JSON, but can also generate its HTML representation via two main methods:
1. **Outputting HTML from the Collection:** Create a new field in your collection to convert saved JSON content to HTML. Payload generates and outputs the HTML for use in your frontend.
2. **Generating HTML on any server** Convert JSON to HTML on-demand on the server.
2. **Generating HTML on the Frontend:** Convert JSON to HTML on-demand, either in your frontend or elsewhere.
The editor comes with built-in HTML serializers, simplifying the process of converting JSON to HTML.
@@ -213,7 +213,7 @@ const Pages: CollectionConfig = {
```
The `lexicalHTML()` function creates a new field that automatically converts the referenced lexical richText field into HTML through an afterRead hook.
#### Generating HTML anywhere on the server:
#### Generating HTML in the Frontend:
If you wish to convert JSON to HTML ad-hoc, use this code snippet:

View File

@@ -168,9 +168,7 @@ Specifying custom `Type`s let you extend your custom elements by adding addition
`collections/ExampleCollection.ts`
```ts
import type { CollectionConfig } from 'payload/types'
import { slateEditor } from '@payloadcms/richtext-slate'
import { CollectionConfig } from 'payload/types'
export const ExampleCollection: CollectionConfig = {
slug: 'example-collection',
@@ -184,59 +182,57 @@ export const ExampleCollection: CollectionConfig = {
},
],
required: true,
editor: slateEditor({
admin: {
elements: [
'h2',
'h3',
'h4',
'link',
'blockquote',
{
name: 'cta',
Button: CustomCallToActionButton,
Element: CustomCallToActionElement,
plugins: [
// any plugins that are required by this element go here
],
},
],
leaves: [
'bold',
'italic',
{
name: 'highlight',
Button: CustomHighlightButton,
Leaf: CustomHighlightLeaf,
plugins: [
// any plugins that are required by this leaf go here
],
},
],
link: {
// Inject your own fields into the Link element
fields: [
{
name: 'rel',
label: 'Rel Attribute',
type: 'select',
hasMany: true,
options: ['noopener', 'noreferrer', 'nofollow'],
},
admin: {
elements: [
'h2',
'h3',
'h4',
'link',
'blockquote',
{
name: 'cta',
Button: CustomCallToActionButton,
Element: CustomCallToActionElement,
plugins: [
// any plugins that are required by this element go here
],
},
upload: {
collections: {
media: {
fields: [
// any fields that you would like to save
// on an upload element in the `media` collection
],
},
],
leaves: [
'bold',
'italic',
{
name: 'highlight',
Button: CustomHighlightButton,
Leaf: CustomHighlightLeaf,
plugins: [
// any plugins that are required by this leaf go here
],
},
],
link: {
// Inject your own fields into the Link element
fields: [
{
name: 'rel',
label: 'Rel Attribute',
type: 'select',
hasMany: true,
options: ['noopener', 'noreferrer', 'nofollow'],
},
],
},
upload: {
collections: {
media: {
fields: [
// any fields that you would like to save
// on an upload element in the `media` collection
],
},
},
},
}),
},
},
],
}

View File

@@ -21,7 +21,7 @@
"@payloadcms/db-mongodb": "latest",
"@payloadcms/richtext-slate": "latest",
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^4.17.1",
"payload": "latest"
},
"devDependencies": {

View File

@@ -2810,11 +2810,6 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
copyfiles@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
@@ -3481,14 +3476,13 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -3669,16 +3663,6 @@ eslint@^8.19.0:
strip-ansi "^6.0.1"
text-table "^0.2.0"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
espree@^9.6.0, espree@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
@@ -3764,7 +3748,7 @@ express-rate-limit@5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@4.18.2:
express@4.18.2, express@^4.17.1:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@@ -3801,43 +3785,6 @@ express@4.18.2:
utils-merge "1.0.1"
vary "~1.1.2"
express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.11.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
ext@^1.1.2:
version "1.7.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
@@ -4561,9 +4508,9 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"

View File

@@ -98,13 +98,6 @@ On boot, a seed script is included to scaffold a basic database for you to use a
> NOTICE: seeding the database is destructive because it drops your current database to populate a fresh one from the seed template. Only run this command if you are starting a new project or can afford to lose your current data.
### Conflicting routes
>In a monorepo when routes are bootstrapped to the same host, they can conflict with Payload's own routes if they have the same name. In our template we've named the Nextjs API routes to `next` to avoid this conflict.
>
>This can happen with any other routes conflicting with Payload such as `admin` and we recommend using different names for custom routes.
>Alternatively you can also rename Payload's own routes via the [configuration](https://payloadcms.com/docs/configuration/overview).
## Production
To run Payload in production, you need to build and serve the Admin panel. To do so, follow these steps:

View File

@@ -25,7 +25,7 @@
"@payloadcms/richtext-slate": "latest",
"dotenv": "^8.2.0",
"escape-html": "^1.0.3",
"express": "^4.19.2",
"express": "^4.17.1",
"next": "^13.4.8",
"payload": "latest",
"react": "^18.2.0",

View File

@@ -0,0 +1,5 @@
import { NextResponse } from 'next/server'
export async function GET(): Promise<NextResponse> {
return NextResponse.json({ success: true })
}

View File

@@ -0,0 +1,5 @@
import { NextResponse } from 'next/server'
export async function POST(): Promise<NextResponse> {
return NextResponse.json({ success: true })
}

View File

@@ -1,10 +0,0 @@
import { NextResponse } from 'next/server'
/**
* The Next.js API routes can conflict with Payload's own routes if they share the same path
* To avoid this you can customise the path of Payload or the API route of Nextjs as we've done here
* See readme: https://github.com/payloadcms/payload/tree/main/examples/custom-server#conflicting-routes
* */
export async function GET(): Promise<NextResponse> {
return NextResponse.json({ success: true })
}

View File

@@ -1,10 +0,0 @@
import { NextResponse } from 'next/server'
/**
* The Next.js API routes can conflict with Payload's own routes if they share the same path
* To avoid this you can customise the path of Payload or the API route of Nextjs as we've done here
* See readme: https://github.com/payloadcms/payload/tree/main/examples/custom-server#conflicting-routes
* */
export async function POST(): Promise<NextResponse> {
return NextResponse.json({ success: true })
}

View File

@@ -2963,11 +2963,6 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
copyfiles@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
@@ -3639,14 +3634,13 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -3828,16 +3822,6 @@ eslint@^8.19.0:
strip-ansi "^6.0.1"
text-table "^0.2.0"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
espree@^9.6.0, espree@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
@@ -3923,7 +3907,7 @@ express-rate-limit@5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@4.18.2:
express@4.18.2, express@^4.17.1:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@@ -3960,43 +3944,6 @@ express@4.18.2:
utils-merge "1.0.1"
vary "~1.1.2"
express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.11.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
ext@^1.1.2:
version "1.7.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
@@ -4754,9 +4701,9 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"

View File

@@ -22,7 +22,7 @@
"@payloadcms/db-mongodb": "latest",
"@payloadcms/richtext-slate": "latest",
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^4.17.1",
"payload": "latest"
},
"devDependencies": {

View File

@@ -2810,11 +2810,6 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
copyfiles@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
@@ -3481,14 +3476,13 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -3669,16 +3663,6 @@ eslint@^8.19.0:
strip-ansi "^6.0.1"
text-table "^0.2.0"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
espree@^9.6.0, espree@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
@@ -3764,7 +3748,7 @@ express-rate-limit@5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@4.18.2:
express@4.18.2, express@^4.17.1:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@@ -3801,43 +3785,6 @@ express@4.18.2:
utils-merge "1.0.1"
vary "~1.1.2"
express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.11.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
ext@^1.1.2:
version "1.7.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
@@ -4561,9 +4508,9 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"

View File

@@ -18,7 +18,7 @@
},
"dependencies": {
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^4.17.1",
"payload": "latest",
"handlebars": "^4.7.7",
"inline-css": "^4.0.2"

View File

@@ -2179,7 +2179,25 @@ bl@^4.0.3:
inherits "^2.0.4"
readable-stream "^3.4.0"
body-parser@1.20.2, body-parser@^1.20.1:
body-parser@1.20.1:
version "1.20.1"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
dependencies:
bytes "3.1.2"
content-type "~1.0.4"
debug "2.6.9"
depd "2.0.0"
destroy "1.2.0"
http-errors "2.0.0"
iconv-lite "0.4.24"
on-finished "2.4.1"
qs "6.11.0"
raw-body "2.5.1"
type-is "~1.6.18"
unpipe "1.0.0"
body-parser@^1.20.1:
version "1.20.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd"
integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==
@@ -2613,10 +2631,10 @@ cookie-signature@1.0.6:
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
cookie@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookiejar@^2.1.4:
version "2.1.4"
@@ -3230,14 +3248,13 @@ es-module-lexer@^1.2.1:
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f"
integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -3363,16 +3380,6 @@ eslint@^8.19.0:
strip-ansi "^6.0.1"
text-table "^0.2.0"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
espree@^9.6.0:
version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
@@ -3456,17 +3463,17 @@ express-rate-limit@^5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@^4.18.2, express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
express@^4.17.1, express@^4.18.2:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
body-parser "1.20.1"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie "0.5.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
@@ -4251,14 +4258,14 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^1.1.5:
version "1.1.9"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.9.tgz#8dfbcc99a754d07f425310b86a99546b1151e396"
integrity sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==
version "1.1.8"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48"
integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"
@@ -6383,6 +6390,16 @@ range-parser@^1.2.1, range-parser@~1.2.1:
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raw-body@2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
dependencies:
bytes "3.1.2"
http-errors "2.0.0"
iconv-lite "0.4.24"
unpipe "1.0.0"
raw-body@2.5.2, raw-body@^2.2.0:
version "2.5.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"

View File

@@ -22,7 +22,7 @@
"@payloadcms/plugin-form-builder": "^1.0.12",
"@payloadcms/plugin-seo": "^1.0.8",
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^4.17.1",
"payload": "latest"
},
"devDependencies": {

View File

@@ -2589,11 +2589,6 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
copyfiles@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
@@ -3164,14 +3159,13 @@ es-module-lexer@^1.2.1:
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.1.tgz#c1b0dd5ada807a3b3155315911f364dc4e909db1"
integrity sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -3229,16 +3223,6 @@ eslint-scope@5.1.1:
esrecurse "^4.3.0"
estraverse "^4.1.1"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
@@ -3303,7 +3287,7 @@ express-rate-limit@5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@4.18.2:
express@4.18.2, express@^4.17.1:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@@ -3340,43 +3324,6 @@ express@4.18.2:
utils-merge "1.0.1"
vary "~1.1.2"
express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.11.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
ext@^1.1.2:
version "1.7.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
@@ -3977,9 +3924,9 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"

View File

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

View File

@@ -1,6 +0,0 @@
build
dist
/media
node_modules
.DS_Store
.env

View File

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

View File

@@ -1,58 +0,0 @@
# Payload Hierarchy Example
This example demonstrates how to achieve a virtual hierarchy between documents in your [Payload](https://github.com/payloadcms/payload) application.
## Quick Start
To spin up the project locally, follow these steps:
1. First clone the repo
1. Then `cd YOUR_PROJECT_REPO && cp .env.example .env`
1. Next `yarn && yarn dev` (or `docker-compose up`, see [Docker](#docker))
1. Now `open http://localhost:3000/admin` to access the admin panel
1. Create your first admin user using the form on the page
That's it! Changes made in `./src` will be reflected in your app.
## How it works
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.
For more information on how virtual fields, see the [Official Virtual Fields Example](https://github.com/payloadcms/payload/tree/main/examples/virtual-fields).
### 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).
## Production
To run Payload in production, you need to build and serve the Admin panel. To do so, follow these steps:
1. First invoke the `payload build` script by running `yarn build` or `npm run build` in your project root. This creates a `./build` directory with a production-ready admin bundle.
1. Then run `yarn serve` or `npm run serve` to run Node in production and serve Payload from the `./build` directory.
### Deployment
The easiest way to deploy your project is to use [Payload Cloud](https://payloadcms.com/new/import), a one-click hosting solution to deploy production-ready instances of your Payload apps directly from your GitHub repo. You can also deploy your app manually, check out the [deployment documentation](https://payloadcms.com/docs/production/deployment) for full details.
## Questions
If you have any issues or questions, reach out to us on [Discord](https://discord.com/invite/payload) or start a [GitHub discussion](https://github.com/payloadcms/payload/discussions).

View File

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

View File

@@ -1,35 +0,0 @@
{
"name": "hierarchy",
"description": "A hierarchy example with Payload",
"version": "1.0.0",
"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": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:graphQLSchema",
"payload": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload"
},
"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",
"cross-env": "^7.0.3",
"dotenv": "^8.2.0",
"express": "^4.19.2",
"payload": "^2.0.0"
},
"devDependencies": {
"@types/express": "^4.17.9",
"copyfiles": "^2.4.1",
"nodemon": "^2.0.6",
"ts-node": "^9.1.1",
"typescript": "^4.8.4"
}
}

View File

@@ -1,79 +0,0 @@
import { CollectionConfig } from 'payload/types'
export const Entities: CollectionConfig = {
slug: 'entities',
admin: {
useAsTitle: 'name',
},
fields: [
{
name: 'name',
type: 'text',
required: true,
},
// - This field is populated by setting the query parameter 'children=true'
// - This is a virtual field used to track a child relationship
// - Only relationship information is returned by this field
// - Data beyond relationships is not stored in this field
{
name: 'children',
type: 'relationship',
relationTo: ['entities', 'people'],
access: {
create: () => false,
update: () => false,
},
hooks: {
afterRead: [
async ({ data, req }) => {
const { id } = data
if (!req.query.children) return
const people = await req.payload.find({
req,
collection: 'people',
where: {
'parents.parent': { equals: id },
},
limit: 0,
depth: 0,
pagination: false,
})
const entities = await req.payload.find({
req,
collection: 'entities',
where: {
parent: { equals: id },
},
limit: 0,
depth: 0,
pagination: false,
})
return [
...entities.docs.map(entity => {
return {
relationTo: 'entity',
value: entity,
}
}),
...people.docs.map(person => {
return {
relationTo: 'people',
value: person,
}
}),
]
},
],
},
},
{
name: 'parent',
type: 'relationship',
relationTo: 'entities',
},
],
}

View File

@@ -1,32 +0,0 @@
import { CollectionConfig } from 'payload/types'
export const People: CollectionConfig = {
slug: 'people',
admin: {
useAsTitle: 'name',
},
fields: [
{
name: 'name',
type: 'text',
required: true,
},
{
name: 'parents',
type: 'array',
fields: [
{
name: 'parent',
type: 'relationship',
relationTo: 'entities',
},
{
name: 'allocation',
type: 'number',
min: 0,
max: 100,
},
],
},
],
}

View File

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

View File

@@ -1,30 +0,0 @@
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 { buildConfig } from 'payload/config'
import Users from './collections/Users'
import { Entities } from './collections/Entities'
import { People } from './collections/People'
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()],
db: mongooseAdapter({
url: process.env.DATABASE_URI,
}),
})

View File

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

View File

@@ -1,22 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true,
"outDir": "./dist",
"rootDir": "./src",
"jsx": "react",
"paths": {
"payload/generated-types": ["./src/payload-types.ts"]
}
},
"include": ["src"],
"exclude": ["node_modules", "dist", "build"],
"ts-node": {
"transpileOnly": true,
"swc": true
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@
"@payloadcms/db-mongodb": "latest",
"@payloadcms/richtext-slate": "latest",
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^4.17.1",
"payload": "latest"
},
"devDependencies": {

View File

@@ -2810,11 +2810,6 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
copyfiles@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
@@ -3481,14 +3476,13 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -3669,16 +3663,6 @@ eslint@^8.19.0:
strip-ansi "^6.0.1"
text-table "^0.2.0"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
espree@^9.6.0, espree@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
@@ -3764,7 +3748,7 @@ express-rate-limit@5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@4.18.2:
express@4.18.2, express@^4.17.1:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@@ -3801,43 +3785,6 @@ express@4.18.2:
utils-merge "1.0.1"
vary "~1.1.2"
express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.11.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
ext@^1.1.2:
version "1.7.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
@@ -4561,9 +4508,9 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"

View File

@@ -69,7 +69,7 @@ For more details on this, see the [CORS](https://payloadcms.com/docs/production/
## Front-end
If you're building a website or other front-end for your tenant, you will need specify the `tenant` in your requests. For example, if you wanted to fetch all pages for the tenant `ABC`, you would make a request to `/api/pages?where[tenant.name][equals]=ABC`.
If you're building a website or other front-end for your tenant, you will need specify the `tenant` in your requests. For example, if you wanted to fetch all pages for the tenant `ABC`, you would make a request to `/api/pages?where[tenant][slug][equals]=abc`.
For a head start on building a website for your tenant(s), check out the official [Website Template](https://github.com/payloadcms/template-website). It includes a page layout builder, preview, SEO, and much more. It is not multi-tenant, though, but you can easily take the concepts from that example and apply them here.

View File

@@ -22,7 +22,7 @@
"@payloadcms/db-mongodb": "latest",
"@payloadcms/richtext-slate": "latest",
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^4.17.1",
"payload": "latest"
},
"devDependencies": {

View File

@@ -2,27 +2,26 @@ import type { AfterLoginHook } from 'payload/dist/collections/config/types'
export const recordLastLoggedInTenant: AfterLoginHook = async ({ req, user }) => {
try {
const relatedOrg = await req.payload
.find({
collection: 'tenants',
where: {
'domains.domain': {
in: [req.headers.host],
},
const relatedOrg = await req.payload.find({
collection: 'tenants',
where: {
'domains.domain': {
in: [req.headers.host],
},
depth: 0,
limit: 1,
})
?.then(res => res.docs?.[0])
await req.payload.update({
id: user.id,
collection: 'users',
data: {
lastLoggedInTenant: relatedOrg?.id || null,
},
req,
depth: 0,
limit: 1,
})
if (relatedOrg.docs.length > 0) {
await req.payload.update({
id: user.id,
collection: 'users',
data: {
lastLoggedInTenant: relatedOrg.docs[0].id,
},
})
}
} catch (err: unknown) {
req.payload.logger.error(`Error recording last logged in tenant for user ${user.id}: ${err}`)
}

View File

@@ -30,7 +30,6 @@ export const isSuperOrTenantAdmin = async (args: { req: PayloadRequest }): Promi
},
depth: 0,
limit: 1,
req,
})
// if this tenant does not exist, deny access

View File

@@ -19,6 +19,7 @@ app.get('/', (_, res) => {
const start = async (): Promise<void> => {
await payload.init({
secret: process.env.PAYLOAD_SECRET,
mongoURL: process.env.MONGODB_URI,
express: app,
onInit: () => {
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`)

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@
"@payloadcms/richtext-slate": "latest",
"@payloadcms/plugin-nested-docs": "latest",
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^4.17.1",
"payload": "latest"
},
"devDependencies": {

View File

@@ -2862,11 +2862,6 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
copyfiles@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
@@ -3538,14 +3533,13 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -3727,16 +3721,6 @@ eslint@^8.19.0:
strip-ansi "^6.0.1"
text-table "^0.2.0"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
espree@^9.6.0, espree@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
@@ -3822,7 +3806,7 @@ express-rate-limit@5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@4.18.2:
express@4.18.2, express@^4.17.1:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@@ -3859,43 +3843,6 @@ express@4.18.2:
utils-merge "1.0.1"
vary "~1.1.2"
express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.11.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
ext@^1.1.2:
version "1.7.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
@@ -4652,9 +4599,9 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"

View File

@@ -22,7 +22,7 @@
"@payloadcms/richtext-slate": "latest",
"@payloadcms/plugin-redirects": "^1.0.0",
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^4.17.1",
"payload": "latest"
},
"devDependencies": {

View File

@@ -2815,11 +2815,6 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
copyfiles@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
@@ -3486,14 +3481,13 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -3674,16 +3668,6 @@ eslint@^8.19.0:
strip-ansi "^6.0.1"
text-table "^0.2.0"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
espree@^9.6.0, espree@^9.6.1:
version "9.6.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
@@ -3769,7 +3753,7 @@ express-rate-limit@5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@4.18.2:
express@4.18.2, express@^4.17.1:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@@ -3806,43 +3790,6 @@ express@4.18.2:
utils-merge "1.0.1"
vary "~1.1.2"
express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.11.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
ext@^1.1.2:
version "1.7.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
@@ -4566,9 +4513,9 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"

View File

@@ -8,7 +8,7 @@
"@payloadcms/db-mongodb": "^1.1.0",
"@payloadcms/richtext-slate": "^1.3.1",
"dotenv": "^16.3.1",
"express": "^4.19.2",
"express": "^4.18.2",
"get-tsconfig": "^4.7.0",
"payload": "^2.4.0"
},

View File

@@ -3335,11 +3335,6 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
cosmiconfig@^7.0.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6"
@@ -3933,14 +3928,13 @@ es-module-lexer@^1.2.1:
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz#41ea21b43908fe6a287ffcbe4300f790555331f5"
integrity sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -4003,16 +3997,6 @@ eslint-scope@5.1.1:
esrecurse "^4.3.0"
estraverse "^4.1.1"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
@@ -4113,7 +4097,7 @@ express-rate-limit@5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@4.18.2:
express@4.18.2, express@^4.18.2:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
@@ -4150,43 +4134,6 @@ express@4.18.2:
utils-merge "1.0.1"
vary "~1.1.2"
express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.11.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
ext@^1.1.2:
version "1.7.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
@@ -4354,9 +4301,9 @@ focus-trap@^6.9.2:
tabbable "^5.3.3"
follow-redirects@^1.15.2:
version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
version "1.15.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
for-each@^0.3.3:
version "0.3.3"
@@ -4888,9 +4835,9 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"

View File

@@ -15,7 +15,7 @@
},
"dependencies": {
"dotenv": "^8.2.0",
"express": "^4.19.2",
"express": "^4.17.1",
"payload": "latest"
},
"devDependencies": {

View File

@@ -2058,7 +2058,25 @@ bl@^4.0.3:
inherits "^2.0.4"
readable-stream "^3.4.0"
body-parser@1.20.2, body-parser@^1.20.1:
body-parser@1.20.1:
version "1.20.1"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
dependencies:
bytes "3.1.2"
content-type "~1.0.4"
debug "2.6.9"
depd "2.0.0"
destroy "1.2.0"
http-errors "2.0.0"
iconv-lite "0.4.24"
on-finished "2.4.1"
qs "6.11.0"
raw-body "2.5.1"
type-is "~1.6.18"
unpipe "1.0.0"
body-parser@^1.20.1:
version "1.20.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd"
integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==
@@ -2455,10 +2473,10 @@ cookie-signature@1.0.6:
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
cookie@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
copyfiles@^2.4.1:
version "2.4.1"
@@ -3015,14 +3033,13 @@ es-module-lexer@^1.2.1:
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f"
integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.64"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714"
integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
version "0.10.62"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
es6-symbol "^3.1.3"
esniff "^2.0.1"
next-tick "^1.1.0"
es6-iterator@^2.0.3:
@@ -3080,16 +3097,6 @@ eslint-scope@5.1.1:
esrecurse "^4.3.0"
estraverse "^4.1.1"
esniff@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
dependencies:
d "^1.0.1"
es5-ext "^0.10.62"
event-emitter "^0.3.5"
type "^2.7.2"
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
@@ -3147,17 +3154,17 @@ express-rate-limit@^5.5.1:
resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2"
integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==
express@^4.18.2, express@^4.19.2:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
express@^4.17.1, express@^4.18.2:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.2"
body-parser "1.20.1"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie "0.5.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
@@ -3741,9 +3748,9 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
ip@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105"
integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==
version "2.0.0"
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
ipaddr.js@1.9.1:
version "1.9.1"
@@ -5668,6 +5675,16 @@ range-parser@^1.2.1, range-parser@~1.2.1:
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raw-body@2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
dependencies:
bytes "3.1.2"
http-errors "2.0.0"
iconv-lite "0.4.24"
unpipe "1.0.0"
raw-body@2.5.2:
version "2.5.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"

View File

@@ -15,13 +15,9 @@
"dev:generate-graphql-schema": "ts-node -T ./test/generateGraphQLSchema.ts",
"dev:generate-types": "ts-node -T ./test/generateTypes.ts",
"dev:postgres": "pnpm --filter payload run dev:postgres",
"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",
"fix": "eslint \"packages/**/*.ts\" --fix",
"lint": "eslint \"packages/**/*.ts\"",
"lint-staged": "lint-staged",
"prepare": "husky install",
"pretest": "pnpm build",
"reinstall": "pnpm clean:unix && pnpm install",
"script:list-packages": "tsx ./scripts/list-packages.ts",
@@ -33,10 +29,10 @@
"test:e2e:headed": "cross-env DISABLE_LOGGING=true playwright test --headed",
"test:int:postgres": "cross-env PAYLOAD_DATABASE=postgres DISABLE_LOGGING=true jest --forceExit --detectOpenHandles",
"test:int": "cross-env DISABLE_LOGGING=true jest --forceExit --detectOpenHandles",
"translateNewKeys": "pnpm --filter payload run translateNewKeys"
"translateNewKeys": "pnpm --filter payload run translateNewKeys",
"prepare": "husky install"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.142.0",
"@payloadcms/eslint-config": "workspace:*",
"@playwright/test": "1.40.1",
"@swc/cli": "^0.1.62",
@@ -68,7 +64,7 @@
"copyfiles": "2.4.1",
"cross-env": "7.0.3",
"dotenv": "8.6.0",
"drizzle-orm": "0.29.3",
"drizzle-orm": "0.28.5",
"express": "4.18.2",
"form-data": "3.0.1",
"fs-extra": "10.1.0",
@@ -81,12 +77,12 @@
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"jwt-decode": "3.1.2",
"lexical": "0.13.1",
"lexical": "0.12.5",
"lint-staged": "^14.0.1",
"minimist": "1.2.8",
"mongodb-memory-server": "^9",
"node-fetch": "2.6.12",
"nodemon": "3.0.3",
"nodemon": "3.0.2",
"prettier": "^3.0.3",
"prompts": "2.4.2",
"qs": "6.11.2",
@@ -98,7 +94,7 @@
"slash": "3.0.0",
"slate": "0.91.4",
"tempfile": "^3.0.0",
"ts-node": "10.9.2",
"ts-node": "10.9.1",
"turbo": "^1.11.1",
"typescript": "5.2.2",
"uuid": "^9.0.1"
@@ -108,16 +104,6 @@
"react-i18next": "11.18.6",
"react-router-dom": "5.3.4"
},
"pnpm": {
"overrides": {
"copyfiles": "$copyfiles",
"cross-env": "$cross-env",
"dotenv": "$dotenv",
"drizzle-orm": "$drizzle-orm",
"ts-node": "$ts-node",
"typescript": "$typescript"
}
},
"engines": {
"node": ">=14",
"pnpm": ">=8"

View File

@@ -2,11 +2,7 @@
"name": "@payloadcms/bundler-vite",
"version": "0.1.6",
"description": "The officially supported Vite bundler adapter for Payload",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/bundler-vite"
},
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",
"homepage": "https://payloadcms.com",
"author": {

View File

@@ -2,11 +2,7 @@
"name": "@payloadcms/bundler-webpack",
"version": "1.0.6",
"description": "The officially supported Webpack bundler adapter for Payload",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/bundler-webpack"
},
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",
"homepage": "https://payloadcms.com",
"author": {

View File

@@ -2,15 +2,9 @@
"name": "create-payload-app",
"version": "1.0.0",
"license": "MIT",
"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 build:swc",
"build:swc": "swc ./src -d ./dist --config-file .swcrc",

View File

@@ -1,12 +1,8 @@
{
"name": "@payloadcms/db-mongodb",
"version": "1.4.3",
"version": "1.3.1",
"description": "The officially supported MongoDB database adapter for Payload",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/db-mongodb"
},
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",
"homepage": "https://payloadcms.com",
"author": {

View File

@@ -29,18 +29,15 @@ export const connect: Connect = async function connect(this: MongooseAdapter, pa
urlToConnect = process.env.PAYLOAD_TEST_MONGO_URL
} else {
connectionOptions.dbName = 'payloadmemory'
const { MongoMemoryReplSet } = require('mongodb-memory-server')
const { MongoMemoryServer } = require('mongodb-memory-server')
const getPort = require('get-port')
const port = await getPort()
this.mongoMemoryServer = await MongoMemoryReplSet.create({
this.mongoMemoryServer = await MongoMemoryServer.create({
instance: {
dbName: 'payloadmemory',
port,
},
replSet: {
count: 3,
},
})
urlToConnect = this.mongoMemoryServer.getUri()
@@ -53,7 +50,7 @@ export const connect: Connect = async function connect(this: MongooseAdapter, pa
const client = this.connection.getClient()
if (!client.options.replicaSet) {
if (!client.options.replicaSet || this.transactionOptions === false) {
this.transactionOptions = false
this.beginTransaction = undefined
}

View File

@@ -49,7 +49,6 @@ export const createGlobalVersion: CreateGlobalVersion = async function createGlo
],
},
{ $unset: { latest: 1 } },
options,
)
const result: Document = JSON.parse(JSON.stringify(doc))

View File

@@ -32,7 +32,7 @@ export const createMigration: CreateMigration = async function createMigration({
// Check for predefined migration.
// Either passed in via --file or prefixed with @payloadcms/db-mongodb/
if (file || migrationName?.startsWith('@payloadcms/db-mongodb/')) {
if (file || migrationName.startsWith('@payloadcms/db-mongodb/')) {
if (!file) file = migrationName
const predefinedMigrationName = file.replace('@payloadcms/db-mongodb/', '')
@@ -59,8 +59,8 @@ export const createMigration: CreateMigration = async function createMigration({
const timestamp = `${formattedDate}_${formattedTime}`
const formattedName = migrationName?.replace(/\W/g, '_')
const fileName = migrationName ? `${timestamp}_${formattedName}.ts` : `${timestamp}_migration.ts`
const formattedName = migrationName.replace(/\W/g, '_')
const fileName = `${timestamp}_${formattedName}.ts`
const filePath = `${dir}/${fileName}`
fs.writeFileSync(filePath, migrationFileContent)
payload.logger.info({ msg: `Migration created at ${filePath}` })

View File

@@ -57,7 +57,6 @@ export const createVersion: CreateVersion = async function createVersion(
],
},
{ $unset: { latest: 1 } },
options,
)
const result: Document = JSON.parse(JSON.stringify(doc))

View File

@@ -63,7 +63,6 @@ export const find: Find = async function find(
paginationOptions.useCustomCountFn = () => {
return Promise.resolve(
Model.countDocuments(query, {
...options,
hint: { _id: 1 },
}),
)

View File

@@ -82,7 +82,6 @@ export const findGlobalVersions: FindGlobalVersions = async function findGlobalV
paginationOptions.useCustomCountFn = () => {
return Promise.resolve(
Model.countDocuments(query, {
...options,
hint: { _id: 1 },
}),
)

View File

@@ -63,6 +63,7 @@ export const findVersions: FindVersions = async function findVersions(
lean: true,
leanWithId: true,
limit,
offset: skip || 0,
options,
page,
pagination,
@@ -78,7 +79,6 @@ export const findVersions: FindVersions = async function findVersions(
paginationOptions.useCustomCountFn = () => {
return Promise.resolve(
Model.countDocuments(query, {
...options,
hint: { _id: 1 },
}),
)

View File

@@ -93,13 +93,18 @@ export function mongooseAdapter({
connectOptions,
disableIndexHints = false,
migrationDir: migrationDirArg,
transactionOptions = {},
transactionOptions,
url,
}: Args): MongooseAdapterResult {
function adapter({ payload }: { payload: Payload }) {
const migrationDir = findMigrationDir(migrationDirArg)
let beginTransactionFunction = beginTransaction
mongoose.set('strictQuery', false)
if (transactionOptions === false) {
beginTransactionFunction = () => null
}
return createDatabaseAdapter<MongooseAdapter>({
name: 'mongoose',
@@ -117,7 +122,7 @@ export function mongooseAdapter({
versions: {},
// DatabaseAdapter
beginTransaction: transactionOptions ? beginTransaction : undefined,
beginTransaction: beginTransactionFunction,
commitTransaction,
connect,
create,

View File

@@ -11,30 +11,25 @@ import type { MongooseAdapter } from '.'
/**
* Drop the current database and run all migrate up functions
*/
export async function migrateFresh(
this: MongooseAdapter,
{ forceAcceptWarning = false }: { forceAcceptWarning?: boolean },
): Promise<void> {
export async function migrateFresh(this: MongooseAdapter): Promise<void> {
const { payload } = this
if (!forceAcceptWarning) {
const { confirm: acceptWarning } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message: `WARNING: This will drop your database and run all migrations. Are you sure you want to proceed?`,
const { confirm: acceptWarning } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message: `WARNING: This will drop your database and run all migrations. Are you sure you want to proceed?`,
},
{
onCancel: () => {
process.exit(0)
},
{
onCancel: () => {
process.exit(0)
},
},
)
},
)
if (!acceptWarning) {
process.exit(0)
}
if (!acceptWarning) {
process.exit(0)
}
payload.logger.info({

View File

@@ -14,10 +14,8 @@ import type {
DateField,
EmailField,
Field,
FieldAffectingData,
GroupField,
JSONField,
NonPresentationalField,
NumberField,
PointField,
RadioField,
@@ -25,12 +23,12 @@ import type {
RichTextField,
RowField,
SelectField,
Tab,
TabsField,
TextField,
TextareaField,
UploadField,
} from 'payload/types'
import type { FieldAffectingData, NonPresentationalField, Tab, UnnamedTab } from 'payload/types'
import { Schema } from 'mongoose'
import {
@@ -63,15 +61,7 @@ const formatBaseSchema = (field: FieldAffectingData, buildSchemaOptions: BuildSc
unique: (!disableUnique && field.unique) || false,
}
if (
schema.unique &&
(field.localized ||
draftsEnabled ||
(fieldAffectsData(field) &&
field.type !== 'group' &&
field.type !== 'tab' &&
field.required !== true))
) {
if (schema.unique && (field.localized || draftsEnabled)) {
schema.sparse = true
}
@@ -89,6 +79,7 @@ const localizeSchema = (
) => {
if (fieldIsLocalized(entity) && localization && Array.isArray(localization.locales)) {
return {
localized: true,
type: localization.localeCodes.reduce(
(localeSchema, locale) => ({
...localeSchema,
@@ -98,7 +89,6 @@ const localizeSchema = (
_id: false,
},
),
localized: true,
}
}
return schema
@@ -150,6 +140,7 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
) => {
const baseSchema = {
...formatBaseSchema(field, buildSchemaOptions),
default: undefined,
type: [
buildSchema(config, field.fields, {
allowIDField: true,
@@ -162,7 +153,6 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
},
}),
],
default: undefined,
}
schema.add({
@@ -176,8 +166,8 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
buildSchemaOptions: BuildSchemaOptions,
): void => {
const fieldSchema = {
type: [new Schema({}, { _id: false, discriminatorKey: 'blockType' })],
default: undefined,
type: [new Schema({}, { _id: false, discriminatorKey: 'blockType' })],
}
schema.add({
@@ -197,12 +187,12 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
if (field.localized && config.localization) {
config.localization.localeCodes.forEach((localeCode) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error Possible incorrect typing in mongoose types, this works
// @ts-ignore Possible incorrect typing in mongoose types, this works
schema.path(`${field.name}.${localeCode}`).discriminator(blockItem.slug, blockSchema)
})
} else {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error Possible incorrect typing in mongoose types, this works
// @ts-ignore Possible incorrect typing in mongoose types, this works
schema.path(field.name).discriminator(blockItem.slug, blockSchema)
}
})
@@ -335,14 +325,14 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
buildSchemaOptions: BuildSchemaOptions,
): void => {
const baseSchema: SchemaTypeOptions<unknown> = {
type: {
type: String,
enum: ['Point'],
},
coordinates: {
type: [Number],
default: field.defaultValue || undefined,
required: false,
type: [Number],
},
type: {
enum: ['Point'],
type: String,
},
}
if (buildSchemaOptions.disableUnique && field.unique && field.localized) {
@@ -376,11 +366,11 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
): void => {
const baseSchema = {
...formatBaseSchema(field, buildSchemaOptions),
type: String,
enum: field.options.map((option) => {
if (typeof option === 'object') return option.value
return option
}),
type: String,
}
schema.add({
@@ -398,6 +388,7 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
if (field.localized && config.localization) {
schemaToReturn = {
localized: true,
type: config.localization.localeCodes.reduce((locales, locale) => {
let localeSchema: { [key: string]: any } = {}
@@ -405,57 +396,56 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
localeSchema = {
...formatBaseSchema(field, buildSchemaOptions),
_id: false,
relationTo: { enum: field.relationTo, type: String },
type: Schema.Types.Mixed,
relationTo: { type: String, enum: field.relationTo },
value: {
type: Schema.Types.Mixed,
refPath: `${field.name}.${locale}.relationTo`,
type: Schema.Types.Mixed,
},
}
} else {
localeSchema = {
...formatBaseSchema(field, buildSchemaOptions),
type: Schema.Types.Mixed,
ref: field.relationTo,
type: Schema.Types.Mixed,
}
}
return {
...locales,
[locale]: field.hasMany ? { type: [localeSchema], default: undefined } : localeSchema,
[locale]: field.hasMany ? { default: undefined, type: [localeSchema] } : localeSchema,
}
}, {}),
localized: true,
}
} else if (hasManyRelations) {
schemaToReturn = {
...formatBaseSchema(field, buildSchemaOptions),
_id: false,
relationTo: { enum: field.relationTo, type: String },
type: Schema.Types.Mixed,
relationTo: { type: String, enum: field.relationTo },
value: {
type: Schema.Types.Mixed,
refPath: `${field.name}.relationTo`,
type: Schema.Types.Mixed,
},
}
if (field.hasMany) {
schemaToReturn = {
type: [schemaToReturn],
default: undefined,
type: [schemaToReturn],
}
}
} else {
schemaToReturn = {
...formatBaseSchema(field, buildSchemaOptions),
type: Schema.Types.Mixed,
ref: field.relationTo,
type: Schema.Types.Mixed,
}
if (field.hasMany) {
schemaToReturn = {
type: [schemaToReturn],
default: undefined,
type: [schemaToReturn],
}
}
}
@@ -498,11 +488,11 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
): void => {
const baseSchema = {
...formatBaseSchema(field, buildSchemaOptions),
type: String,
enum: field.options.map((option) => {
if (typeof option === 'object') return option.value
return option
}),
type: String,
}
if (buildSchemaOptions.draftsEnabled || !field.required) {
@@ -586,8 +576,8 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
): void => {
const baseSchema = {
...formatBaseSchema(field, buildSchemaOptions),
type: Schema.Types.Mixed,
ref: field.relationTo,
type: Schema.Types.Mixed,
}
schema.add({

View File

@@ -65,7 +65,8 @@ export const sanitizeQueryValue = ({
if (field.type === 'date' && typeof val === 'string') {
formattedValue = new Date(val)
if (Number.isNaN(Date.parse(formattedValue))) {
return undefined
// ignore invalid query
return { rawQuery: {} }
}
}
@@ -77,7 +78,6 @@ export const sanitizeQueryValue = ({
// Object equality requires the value to be the first key in the object that is being queried.
if (
operator === 'equals' &&
formattedValue &&
typeof formattedValue === 'object' &&
formattedValue.value &&
formattedValue.relationTo
@@ -157,23 +157,6 @@ export const sanitizeQueryValue = ({
if (operator === 'exists') {
formattedValue = formattedValue === 'true' || formattedValue === true
// Clearable fields
if (['relationship', 'select', 'upload'].includes(field.type)) {
if (formattedValue) {
return {
rawQuery: {
$and: [{ [path]: { $exists: true } }, { [path]: { $ne: null } }],
},
}
} else {
return {
rawQuery: {
$or: [{ [path]: { $exists: false } }, { [path]: { $eq: null } }],
},
}
}
}
}
return { operator: formattedOperator, val: formattedValue }

View File

@@ -17,11 +17,7 @@ export const rollbackTransaction: RollbackTransaction = async function rollbackT
}
// the first call for rollback should be aborted and deleted causing any other operations with the same transaction to fail
try {
await this.sessions[id].abortTransaction()
await this.sessions[id].endSession()
} catch (error) {
// ignore the error as it is likely a race condition from multiple errors
}
await this.sessions[id].abortTransaction()
await this.sessions[id].endSession()
delete this.sessions[id]
}

View File

@@ -1,12 +1,8 @@
{
"name": "@payloadcms/db-postgres",
"version": "0.7.1",
"version": "0.3.1",
"description": "The officially supported Postgres database adapter for Payload",
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
"directory": "packages/db-postgres"
},
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",
"homepage": "https://payloadcms.com",
"author": {
@@ -26,8 +22,8 @@
"dependencies": {
"@libsql/client": "^0.3.1",
"console-table-printer": "2.11.2",
"drizzle-kit": "0.20.14-1f2c838",
"drizzle-orm": "0.29.3",
"drizzle-kit": "0.19.13-e99bac1",
"drizzle-orm": "0.28.5",
"pg": "8.11.3",
"prompts": "2.4.2",
"to-snake-case": "1.0.0",

View File

@@ -1,51 +1,13 @@
import type { Payload } from 'payload'
import type { Connect } from 'payload/database'
import { eq, sql } from 'drizzle-orm'
import { drizzle } from 'drizzle-orm/node-postgres'
import { numeric, timestamp, varchar } from 'drizzle-orm/pg-core'
import { numeric, pgTable, timestamp, varchar } from 'drizzle-orm/pg-core'
import { Pool } from 'pg'
import prompts from 'prompts'
import type { PostgresAdapter } from './types'
const connectWithReconnect = async function ({
adapter,
payload,
reconnect = false,
}: {
adapter: PostgresAdapter
payload: Payload
reconnect?: boolean
}) {
let result
if (!reconnect) {
result = await adapter.pool.connect()
} else {
try {
result = await adapter.pool.connect()
} catch (err) {
setTimeout(() => {
payload.logger.info('Reconnecting to postgres')
void connectWithReconnect({ adapter, payload, reconnect: true })
}, 1000)
}
}
if (!result) {
return
}
result.prependListener('error', (err) => {
try {
if (err.code === 'ECONNRESET') {
void connectWithReconnect({ adapter, payload, reconnect: true })
}
} catch (err) {
// swallow error
}
})
}
export const connect: Connect = async function connect(this: PostgresAdapter, payload) {
this.schema = {
...this.tables,
@@ -55,19 +17,13 @@ export const connect: Connect = async function connect(this: PostgresAdapter, pa
try {
this.pool = new Pool(this.poolOptions)
await connectWithReconnect({ adapter: this, payload })
await this.pool.connect()
const logger = this.logger || false
this.drizzle = drizzle(this.pool, { logger, schema: this.schema })
this.drizzle = drizzle(this.pool, { schema: this.schema })
if (process.env.PAYLOAD_DROP_DATABASE === 'true') {
this.payload.logger.info(`---- DROPPING TABLES SCHEMA(${this.schemaName || 'public'}) ----`)
await this.drizzle.execute(
sql.raw(`
drop schema if exists ${this.schemaName || 'public'} cascade;
create schema ${this.schemaName || 'public'};
`),
)
this.payload.logger.info('---- DROPPING TABLES ----')
await this.drizzle.execute(sql`drop schema public cascade;
create schema public;`)
this.payload.logger.info('---- DROPPED TABLES ----')
}
} catch (err) {
@@ -83,7 +39,7 @@ export const connect: Connect = async function connect(this: PostgresAdapter, pa
)
return
const { pushSchema } = require('drizzle-kit/payload')
const { pushSchema } = require('drizzle-kit/utils')
// This will prompt if clarifications are needed for Drizzle to push new schema
const { apply, hasDataLoss, statementsToExecute, warnings } = await pushSchema(
@@ -103,9 +59,9 @@ export const connect: Connect = async function connect(this: PostgresAdapter, pa
const { confirm: acceptWarnings } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message,
type: 'confirm',
},
{
onCancel: () => {
@@ -124,7 +80,7 @@ export const connect: Connect = async function connect(this: PostgresAdapter, pa
await apply()
// Migration table def in order to use query using drizzle
const migrationsSchema = this.pgSchema.table('payload_migrations', {
const migrationsSchema = pgTable('payload_migrations', {
name: varchar('name'),
batch: numeric('batch'),
created_at: timestamp('created_at'),

View File

@@ -1,5 +1,5 @@
/* eslint-disable no-restricted-syntax, no-await-in-loop */
import type { DrizzleSnapshotJSON } from 'drizzle-kit/payload'
import type { DrizzleSnapshotJSON } from 'drizzle-kit/utils'
import type { CreateMigration } from 'payload/database'
import fs from 'fs'
@@ -53,14 +53,14 @@ const getDefaultDrizzleSnapshot = (): DrizzleSnapshotJSON => ({
export const createMigration: CreateMigration = async function createMigration(
this: PostgresAdapter,
{ forceAcceptWarning, migrationName, payload },
{ migrationName, payload },
) {
const dir = payload.db.migrationDir
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir)
}
const { generateDrizzleJson, generateMigration } = require('drizzle-kit/payload')
const { generateDrizzleJson, generateMigration } = require('drizzle-kit/utils')
const [yyymmdd, hhmmss] = new Date().toISOString().split('T')
const formattedDate = yyymmdd.replace(/\D/g, '')
@@ -95,13 +95,13 @@ export const createMigration: CreateMigration = async function createMigration(
const sqlStatementsUp = await generateMigration(drizzleJsonBefore, drizzleJsonAfter)
const sqlStatementsDown = await generateMigration(drizzleJsonAfter, drizzleJsonBefore)
if (!sqlStatementsUp.length && !sqlStatementsDown.length && !forceAcceptWarning) {
if (!sqlStatementsUp.length && !sqlStatementsDown.length) {
const { confirm: shouldCreateBlankMigration } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message: 'No schema changes detected. Would you like to create a blank migration file?',
type: 'confirm',
},
{
onCancel: () => {

View File

@@ -1,68 +1,47 @@
import type { DeleteOne } from 'payload/database'
import type { PayloadRequest } from 'payload/types'
import { eq } from 'drizzle-orm'
import toSnakeCase from 'to-snake-case'
import type { PostgresAdapter } from './types'
import { buildFindManyArgs } from './find/buildFindManyArgs'
import buildQuery from './queries/buildQuery'
import { selectDistinct } from './queries/selectDistinct'
import { transform } from './transform/read'
export const deleteOne: DeleteOne = async function deleteOne(
this: PostgresAdapter,
{ collection: collectionSlug, req = {} as PayloadRequest, where: whereArg },
{ collection, req = {} as PayloadRequest, where: incomingWhere },
) {
const db = this.sessions[req.transactionID]?.db || this.drizzle
const collection = this.payload.collections[collectionSlug].config
const tableName = toSnakeCase(collectionSlug)
let docToDelete: Record<string, unknown>
const collectionConfig = this.payload.collections[collection].config
const tableName = toSnakeCase(collection)
const { joinAliases, joins, selectFields, where } = await buildQuery({
const { where } = await buildQuery({
adapter: this,
fields: collection.fields,
locale: req.locale,
fields: collectionConfig.fields,
tableName,
where: whereArg,
where: incomingWhere,
})
const selectDistinctResult = await selectDistinct({
const findManyArgs = buildFindManyArgs({
adapter: this,
chainedMethods: [{ args: [1], method: 'limit' }],
db,
joinAliases,
joins,
selectFields,
depth: 0,
fields: collectionConfig.fields,
tableName,
where,
})
if (selectDistinctResult?.[0]?.id) {
docToDelete = await db.query[tableName].findFirst({
where: eq(this.tables[tableName].id, selectDistinctResult[0].id),
})
} else {
const findManyArgs = buildFindManyArgs({
adapter: this,
depth: 0,
fields: collection.fields,
tableName,
})
findManyArgs.where = where
findManyArgs.where = where
docToDelete = await db.query[tableName].findFirst(findManyArgs)
}
const docToDelete = await db.query[tableName].findFirst(findManyArgs)
const result = transform({
config: this.payload.config,
data: docToDelete,
fields: collection.fields,
fields: collectionConfig.fields,
})
await db.delete(this.tables[tableName]).where(eq(this.tables[tableName].id, docToDelete.id))
await db.delete(this.tables[tableName]).where(where)
return result
}

View File

@@ -1,5 +1,3 @@
import type { QueryPromise } from 'drizzle-orm'
export type ChainedMethods = {
args: unknown[]
method: string
@@ -10,7 +8,7 @@ export type ChainedMethods = {
* @param methods
* @param query
*/
const chainMethods = <T>({ methods, query }): QueryPromise<T> => {
const chainMethods = ({ methods, query }): Promise<unknown> => {
return methods.reduce((query, { args, method }) => {
return query[method](...args)
}, query)

View File

@@ -7,7 +7,6 @@ import type { PostgresAdapter } from '../types'
import type { ChainedMethods } from './chainMethods'
import buildQuery from '../queries/buildQuery'
import { selectDistinct } from '../queries/selectDistinct'
import { transform } from '../transform/read'
import { buildFindManyArgs } from './buildFindManyArgs'
import { chainMethods } from './chainMethods'
@@ -40,6 +39,7 @@ export const findMany = async function find({
let hasPrevPage: boolean
let hasNextPage: boolean
let pagingCounter: number
let selectDistinctResult
const { joinAliases, joins, orderBy, selectFields, where } = await buildQuery({
adapter,
@@ -69,21 +69,36 @@ export const findMany = async function find({
tableName,
})
selectDistinctMethods.push({ args: [skip || (page - 1) * limit], method: 'offset' })
selectDistinctMethods.push({ args: [limit === 0 ? undefined : limit], method: 'limit' })
// only fetch IDs when a sort or where query is used that needs to be done on join tables, otherwise these can be done directly on the table in findMany
if (Object.keys(joins).length > 0 || joinAliases.length > 0) {
if (where) {
selectDistinctMethods.push({ args: [where], method: 'where' })
}
const selectDistinctResult = await selectDistinct({
adapter,
chainedMethods: selectDistinctMethods,
db,
joinAliases,
joins,
selectFields,
tableName,
where,
})
joinAliases.forEach(({ condition, table }) => {
selectDistinctMethods.push({
args: [table, condition],
method: 'leftJoin',
})
})
Object.entries(joins).forEach(([joinTable, condition]) => {
if (joinTable) {
selectDistinctMethods.push({
args: [adapter.tables[joinTable], condition],
method: 'leftJoin',
})
}
})
selectDistinctMethods.push({ args: [skip || (page - 1) * limit], method: 'offset' })
selectDistinctMethods.push({ args: [limit === 0 ? undefined : limit], method: 'limit' })
selectDistinctResult = await chainMethods({
methods: selectDistinctMethods,
query: db.selectDistinct(selectFields).from(table),
})
if (selectDistinctResult) {
if (selectDistinctResult.length === 0) {
return {
docs: [],
@@ -97,14 +112,13 @@ export const findMany = async function find({
totalDocs: 0,
totalPages: 0,
}
} else {
// set the id in an object for sorting later
selectDistinctResult.forEach(({ id }, i) => {
orderedIDMap[id] = i
})
orderedIDs = Object.keys(orderedIDMap)
findManyArgs.where = inArray(adapter.tables[tableName].id, orderedIDs)
}
// set the id in an object for sorting later
selectDistinctResult.forEach(({ id }, i) => {
orderedIDMap[id as number | string] = i
})
orderedIDs = Object.keys(orderedIDMap)
findManyArgs.where = inArray(adapter.tables[tableName].id, orderedIDs)
} else {
findManyArgs.limit = limitArg === 0 ? undefined : limitArg
@@ -144,7 +158,7 @@ export const findMany = async function find({
query: db
.select({
count: sql<number>`count
(DISTINCT ${adapter.tables[tableName].id})`,
(*)`,
})
.from(table)
.where(where),

View File

@@ -78,7 +78,7 @@ export const traverseFields = ({
with: {},
}
const arrayTableName = `${currentTableName}_${path}${toSnakeCase(field.name)}`
const arrayTableName = `${currentTableName}_${toSnakeCase(field.name)}`
if (adapter.tables[`${arrayTableName}_locales`]) withArray.with._locales = _locales
currentArgs.with[`${path}${field.name}`] = withArray

View File

@@ -42,7 +42,7 @@ export type { MigrateDownArgs, MigrateUpArgs } from './types'
export function postgresAdapter(args: Args): PostgresAdapterResult {
function adapter({ payload }: { payload: Payload }) {
const migrationDir = findMigrationDir(args.migrationDir)
const idType = args.idType || 'serial'
return createDatabaseAdapter<PostgresAdapter>({
name: 'postgres',
@@ -50,15 +50,11 @@ export function postgresAdapter(args: Args): PostgresAdapterResult {
drizzle: undefined,
enums: {},
fieldConstraints: {},
idType,
logger: args.logger,
pgSchema: undefined,
pool: undefined,
poolOptions: args.pool,
push: args.push,
relations: {},
schema: {},
schemaName: args.schemaName,
sessions: {},
tables: {},
@@ -71,10 +67,7 @@ export function postgresAdapter(args: Args): PostgresAdapterResult {
createGlobalVersion,
createMigration,
createVersion,
/**
* This represents how a default ID is treated in Payload as were a field type
*/
defaultIDType: idType === 'serial' ? 'number' : 'text',
defaultIDType: 'number',
deleteMany,
deleteOne,
deleteVersions,

View File

@@ -2,21 +2,16 @@
import type { Init } from 'payload/database'
import type { SanitizedCollectionConfig } from 'payload/types'
import { pgEnum, pgSchema, pgTable } from 'drizzle-orm/pg-core'
import { pgEnum } from 'drizzle-orm/pg-core'
import { buildVersionCollectionFields, buildVersionGlobalFields } from 'payload/versions'
import toSnakeCase from 'to-snake-case'
import type { PostgresAdapter } from './types'
import { buildTable } from './schema/build'
import { getConfigIDType } from './schema/getConfigIDType'
export const init: Init = async function init(this: PostgresAdapter) {
if (this.schemaName) {
this.pgSchema = pgSchema(this.schemaName)
} else {
this.pgSchema = { table: pgTable }
}
if (this.payload.config.localization) {
this.enums.enum__locales = pgEnum(
'_locales',
@@ -29,9 +24,9 @@ export const init: Init = async function init(this: PostgresAdapter) {
buildTable({
adapter: this,
buildTexts: true,
buildNumbers: true,
buildRelationships: true,
buildTexts: true,
disableNotNull: !!collection?.versions?.drafts,
disableUnique: false,
fields: collection.fields,
@@ -43,11 +38,13 @@ export const init: Init = async function init(this: PostgresAdapter) {
const versionsTableName = `_${tableName}_v`
const versionFields = buildVersionCollectionFields(collection)
const versionsParentIDColType = getConfigIDType(collection.fields)
buildTable({
adapter: this,
buildTexts: true,
buildNumbers: true,
buildRelationships: true,
buildTexts: true,
disableNotNull: !!collection.versions?.drafts,
disableUnique: true,
fields: versionFields,
@@ -62,9 +59,9 @@ export const init: Init = async function init(this: PostgresAdapter) {
buildTable({
adapter: this,
buildTexts: true,
buildNumbers: true,
buildRelationships: true,
buildTexts: true,
disableNotNull: !!global?.versions?.drafts,
disableUnique: false,
fields: global.fields,
@@ -78,9 +75,9 @@ export const init: Init = async function init(this: PostgresAdapter) {
buildTable({
adapter: this,
buildTexts: true,
buildNumbers: true,
buildRelationships: true,
buildTexts: true,
disableNotNull: !!global.versions?.drafts,
disableUnique: true,
fields: versionFields,

View File

@@ -39,7 +39,7 @@ export async function migrate(this: PostgresAdapter): Promise<void> {
latestBatch = Number(migrationsInDB[0]?.batch)
}
} else {
await createMigrationTable(this)
await createMigrationTable(this.drizzle)
}
if (migrationsInDB.find((m) => m.batch === -1)) {
@@ -80,7 +80,7 @@ export async function migrate(this: PostgresAdapter): Promise<void> {
}
async function runMigrationFile(payload: Payload, migration: Migration, batch: number) {
const { generateDrizzleJson } = require('drizzle-kit/payload')
const { generateDrizzleJson } = require('drizzle-kit/utils')
const start = Date.now()
const req = { payload } as PayloadRequest

View File

@@ -37,7 +37,7 @@ export async function migrateDown(this: PostgresAdapter): Promise<void> {
}
const start = Date.now()
const req = { payload } as PayloadRequest
const req = {} as PayloadRequest
try {
payload.logger.info({ msg: `Migrating down: ${migrationFile.name}` })

View File

@@ -14,40 +14,33 @@ import { parseError } from './utilities/parseError'
/**
* Drop the current database and run all migrate up functions
*/
export async function migrateFresh(
this: PostgresAdapter,
{ forceAcceptWarning = false },
): Promise<void> {
export async function migrateFresh(this: PostgresAdapter): Promise<void> {
const { payload } = this
if (forceAcceptWarning === false) {
const { confirm: acceptWarning } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message: `WARNING: This will drop your database and run all migrations. Are you sure you want to proceed?`,
const { confirm: acceptWarning } = await prompts(
{
name: 'confirm',
type: 'confirm',
initial: false,
message: `WARNING: This will drop your database and run all migrations. Are you sure you want to proceed?`,
},
{
onCancel: () => {
process.exit(0)
},
{
onCancel: () => {
process.exit(0)
},
},
)
},
)
if (!acceptWarning) {
process.exit(0)
}
if (!acceptWarning) {
process.exit(0)
}
payload.logger.info({
msg: `Dropping database.`,
})
await this.drizzle.execute(
sql.raw(`drop schema ${this.schemaName || 'public'} cascade;
create schema ${this.schemaName || 'public'};`),
)
await this.drizzle.execute(sql`drop schema public cascade;
create schema public;`)
const migrationFiles = await readMigrationFiles({ payload })
payload.logger.debug({

View File

@@ -1,5 +1,4 @@
import type { SQL } from 'drizzle-orm'
import type { PgTableWithColumns } from 'drizzle-orm/pg-core'
import type { Field, Where } from 'payload/types'
import { asc, desc } from 'drizzle-orm'
@@ -13,7 +12,7 @@ export type BuildQueryJoins = Record<string, SQL>
export type BuildQueryJoinAliases = {
condition: SQL
table: GenericTable | PgTableWithColumns<any>
table: GenericTable
}[]
type BuildQueryArgs = {
@@ -76,7 +75,6 @@ const buildQuery = async function buildQuery({
pathSegments: sortPath.replace(/__/g, '.').split('.'),
selectFields,
tableName,
value: sortPath,
})
orderBy.column = sortTable?.[sortTableColumnName]
} catch (err) {

View File

@@ -1,9 +1,8 @@
/* eslint-disable no-param-reassign */
import type { SQL } from 'drizzle-orm'
import type { PgTableWithColumns } from 'drizzle-orm/pg-core'
import type { Field, FieldAffectingData, NumberField, TabAsField, TextField } from 'payload/types'
import type { Field, FieldAffectingData, TabAsField } from 'payload/types'
import { and, eq, like, sql } from 'drizzle-orm'
import { and, eq, sql } from 'drizzle-orm'
import { alias } from 'drizzle-orm/pg-core'
import { APIError } from 'payload/errors'
import { fieldAffectsData, tabHasName } from 'payload/types'
@@ -16,7 +15,7 @@ import type { BuildQueryJoinAliases, BuildQueryJoins } from './buildQuery'
type Constraint = {
columnName: string
table: GenericTable | PgTableWithColumns<any>
table: GenericTable
value: unknown
}
@@ -27,12 +26,12 @@ type TableColumn = {
getNotNullColumnByValue?: (val: unknown) => string
pathSegments?: string[]
rawColumn?: SQL
table: GenericTable | PgTableWithColumns<any>
table: GenericTable
}
type Args = {
adapter: PostgresAdapter
aliasTable?: GenericTable | PgTableWithColumns<any>
aliasTable?: GenericTable
collectionPath: string
columnPrefix?: string
constraintPath?: string
@@ -45,14 +44,6 @@ type Args = {
rootTableName?: string
selectFields: Record<string, GenericColumn>
tableName: string
/**
* If creating a new table name for arrays and blocks, this suffix should be appended to the table name
*/
tableNameSuffix?: string
/**
* The raw value of the query before sanitization
*/
value: unknown
}
/**
* Transforms path to table and column name
@@ -74,8 +65,6 @@ export const getTableColumnFromPath = ({
rootTableName: incomingRootTableName,
selectFields,
tableName,
tableNameSuffix = '',
value,
}: Args): TableColumn => {
const fieldPath = incomingSegments[0]
let locale = incomingLocale
@@ -94,8 +83,8 @@ export const getTableColumnFromPath = ({
constraints,
field: {
name: 'id',
type: adapter.idType === 'uuid' ? 'text' : 'number',
} as TextField | NumberField,
type: 'number',
},
table: adapter.tables[newTableName],
}
}
@@ -136,8 +125,6 @@ export const getTableColumnFromPath = ({
rootTableName,
selectFields,
tableName: newTableName,
tableNameSuffix,
value,
})
}
case 'tab': {
@@ -147,7 +134,7 @@ export const getTableColumnFromPath = ({
aliasTable,
collectionPath,
columnPrefix: `${columnPrefix}${field.name}_`,
constraintPath: `${constraintPath}${field.name}.`,
constraintPath,
constraints,
fields: field.fields,
joinAliases,
@@ -157,8 +144,6 @@ export const getTableColumnFromPath = ({
rootTableName,
selectFields,
tableName: newTableName,
tableNameSuffix: `${tableNameSuffix}${toSnakeCase(field.name)}_`,
value,
})
}
return getTableColumnFromPath({
@@ -176,8 +161,6 @@ export const getTableColumnFromPath = ({
rootTableName,
selectFields,
tableName: newTableName,
tableNameSuffix,
value,
})
}
@@ -202,7 +185,7 @@ export const getTableColumnFromPath = ({
aliasTable,
collectionPath,
columnPrefix: `${columnPrefix}${field.name}_`,
constraintPath: `${constraintPath}${field.name}.`,
constraintPath,
constraints,
fields: field.fields,
joinAliases,
@@ -212,13 +195,11 @@ export const getTableColumnFromPath = ({
rootTableName,
selectFields,
tableName: newTableName,
tableNameSuffix: `${tableNameSuffix}${toSnakeCase(field.name)}_`,
value,
})
}
case 'array': {
newTableName = `${tableName}_${tableNameSuffix}${toSnakeCase(field.name)}`
newTableName = `${tableName}_${toSnakeCase(field.name)}`
constraintPath = `${constraintPath}${field.name}.%.`
if (locale && field.localized && adapter.payload.config.localization) {
joins[newTableName] = and(
@@ -251,39 +232,12 @@ export const getTableColumnFromPath = ({
rootTableName,
selectFields,
tableName: newTableName,
value,
})
}
case 'blocks': {
let blockTableColumn: TableColumn
let newTableName: string
// handle blockType queries
if (pathSegments[1] === 'blockType') {
// find the block config using the value
const blockTypes = Array.isArray(value) ? value : [value]
blockTypes.forEach((blockType) => {
const block = field.blocks.find((block) => block.slug === blockType)
newTableName = `${tableName}_blocks_${toSnakeCase(block.slug)}`
joins[newTableName] = eq(
adapter.tables[tableName].id,
adapter.tables[newTableName]._parentID,
)
constraints.push({
columnName: '_path',
table: adapter.tables[newTableName],
value: pathSegments[0],
})
})
return {
constraints,
field,
getNotNullColumnByValue: () => 'id',
table: adapter.tables[tableName],
}
}
const hasBlockField = field.blocks.some((block) => {
newTableName = `${tableName}_blocks_${toSnakeCase(block.slug)}`
constraintPath = `${constraintPath}${field.name}.%.`
@@ -304,7 +258,6 @@ export const getTableColumnFromPath = ({
rootTableName,
selectFields: blockSelectFields,
tableName: newTableName,
value,
})
} catch (error) {
// this is fine, not every block will have the field
@@ -345,6 +298,9 @@ export const getTableColumnFromPath = ({
table: blockTableColumn.table,
}
}
if (pathSegments[1] === 'blockType') {
throw new APIError('Querying on blockType is not supported')
}
break
}
@@ -361,15 +317,21 @@ export const getTableColumnFromPath = ({
// Join in the relationships table
joinAliases.push({
condition: and(
eq((aliasTable || adapter.tables[rootTableName]).id, aliasRelationshipTable.parent),
like(aliasRelationshipTable.path, `${constraintPath}${field.name}`),
condition: eq(
(aliasTable || adapter.tables[rootTableName]).id,
aliasRelationshipTable.parent,
),
table: aliasRelationshipTable,
})
selectFields[`${relationTableName}.path`] = aliasRelationshipTable.path
constraints.push({
columnName: 'path',
table: aliasRelationshipTable,
value: `${constraintPath}${field.name}`,
})
let newAliasTable
if (typeof field.relationTo === 'string') {
@@ -384,7 +346,7 @@ export const getTableColumnFromPath = ({
table: newAliasTable,
})
if (newCollectionPath === '' || newCollectionPath === 'id') {
if (newCollectionPath === '') {
return {
columnName: `${field.relationTo}ID`,
constraints,
@@ -432,7 +394,6 @@ export const getTableColumnFromPath = ({
rootTableName: newTableName,
selectFields,
tableName: newTableName,
value,
})
}
@@ -467,7 +428,7 @@ export const getTableColumnFromPath = ({
columnName: `${columnPrefix}${field.name}`,
constraints,
field,
pathSegments,
pathSegments: pathSegments,
table: targetTable,
}
}

View File

@@ -63,7 +63,11 @@ export async function parseParams({
where: condition,
})
if (builtConditions.length > 0) {
result = operatorMap[conditionOperator](...builtConditions)
if (result) {
result = operatorMap[conditionOperator](result, ...builtConditions)
} else {
result = operatorMap[conditionOperator](...builtConditions)
}
}
} else {
// It's a path - and there can be multiple comparisons on a single path.
@@ -73,7 +77,6 @@ export async function parseParams({
if (typeof pathOperators === 'object') {
for (const operator of Object.keys(pathOperators)) {
if (validOperators.includes(operator as Operator)) {
const val = where[relationOrPath][operator]
const {
columnName,
constraints: queryConstraints,
@@ -92,9 +95,10 @@ export async function parseParams({
pathSegments: relationOrPath.replace(/__/g, '.').split('.'),
selectFields,
tableName,
value: val,
})
const val = where[relationOrPath][operator]
queryConstraints.forEach(({ columnName: col, table: constraintTable, value }) => {
if (typeof value === 'string' && value.indexOf('%') > -1) {
constraints.push(operatorMap.like(constraintTable[col], value))
@@ -165,7 +169,6 @@ export async function parseParams({
}
const sanitizedQueryValue = sanitizeQueryValue({
adapter,
field,
operator,
relationOrPath,
@@ -204,16 +207,6 @@ export async function parseParams({
break
}
if (operator === 'equals' && queryValue === null) {
constraints.push(isNull(rawColumn || table[columnName]))
break
}
if (operator === 'not_equals' && queryValue === null) {
constraints.push(isNotNull(rawColumn || table[columnName]))
break
}
constraints.push(
operatorMap[queryOperator](rawColumn || table[columnName], queryValue),
)

View File

@@ -2,10 +2,7 @@ import { APIError } from 'payload/errors'
import { type Field, type TabAsField, fieldAffectsData } from 'payload/types'
import { createArrayFromCommaDelineated } from 'payload/utilities'
import type { PostgresAdapter } from '../types'
type SanitizeQueryValueArgs = {
adapter: PostgresAdapter
field: Field | TabAsField
operator: string
relationOrPath: string
@@ -13,7 +10,6 @@ type SanitizeQueryValueArgs = {
}
export const sanitizeQueryValue = ({
adapter,
field,
operator: operatorArg,
relationOrPath,
@@ -31,10 +27,8 @@ export const sanitizeQueryValue = ({
) {
const allPossibleIDTypes: (number | string)[] = []
formattedValue.forEach((val) => {
if (adapter.idType !== 'uuid' && typeof val === 'string') {
if (typeof val === 'string') {
allPossibleIDTypes.push(val, parseInt(val))
} else if (typeof val === 'string') {
allPossibleIDTypes.push(val)
} else {
allPossibleIDTypes.push(val, String(val))
}

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