Compare commits

..

517 Commits

Author SHA1 Message Date
Elliot DeNolf
b9854ed60a chore(release): db-postgres/0.8.4 [skip ci] 2024-05-17 14:36:02 -04:00
Elliot DeNolf
576ee14976 chore(release): payload/2.18.3 [skip ci] 2024-05-17 14:33:14 -04:00
Dan Ribbens
bf77cec7e9 fix(db-postgres): query with like on id columns (#6416)
copy of https://github.com/payloadcms/payload/pull/6414 to main
2024-05-17 14:07:57 -04:00
Patrik
ab8b2f3fb8 fix: nested disableListColumn in rows (#6412)
## Description

Fixes #6407 

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
2024-05-17 14:01:08 -04:00
Patrik
db5f3f3ccd fix(db-postgres): uuid custom db name (#6409)
## Description

Fixes an issue with creating versions when using custom DB names,
`uuid`, and drafts.

v3 PR [here](https://github.com/payloadcms/payload/pull/6408)

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] Existing test suite passes locally with my changes
2024-05-17 13:58:08 -04:00
Francis Turmel
cece39957f chore(i18n): French translation improvements (#6035)
## Description

see #6406 for the changes against `beta`

* The apostrophe character `’` should be used instead of the single
quote `'`
* Gender corrections: "L’adresse e-mail fourni**e**", "Vérification
échoué**e**"
* Lowercase: "Supprimer le **té**léversement"
* Dark and light theme: I think it makes more sense to use "Sombre" and
"Clair" here to identify the theme. Day/Night modes imply a hue/warmth
correction and are different features altogether. Reference:
https://fr.wikipedia.org/wiki/Mode_sombre#Mode_sombre_et_mode_nuit_ou_chaud
* Fix accent: "Mis à jour avec succ**è**s"
* "Bienvenue" I think would be the correct standalone greeting form.
Reference:
https://www.projet-voltaire.fr/question-orthographe/orthographe-bienvenu-bienvenue-chez-moi/
* "Recadrer" is the correct word for "crop". "Récolte" means "crop" in
the sense of "harvest", so this was probably a bad literal Google
Translate that slipped through.
* Correct all "Es-tu sûr ?" to the proper formal "Êtes-vous sûr ?" for
consistency
* Use _article défini_ since we will enumerate the values: "Ce champ
contient **les** sélections invalides suivantes :"
* Space before question marks

---

<!-- Please include a summary of the pull request and any related issues
it fixes. Please also include relevant motivation and context. -->

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

<!-- Please delete options that are not relevant. -->

- [x] Chore (non-breaking change which does not add functionality)
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Change to the
[templates](https://github.com/payloadcms/payload/tree/main/templates)
directory (does not affect core functionality)
- [ ] Change to the
[examples](https://github.com/payloadcms/payload/tree/main/examples)
directory (does not affect core functionality)
- [ ] This change requires a documentation update

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-05-17 13:51:47 -03:00
Elliot DeNolf
157fff0417 chore(release): payload/2.18.2 [skip ci] 2024-05-17 10:09:35 -04:00
Elliot DeNolf
88e113a545 fix: allow focal point when no sizes defined (#6397)
Allow focal points to be saved even when no imageSizes are defined.
Expands upon #6364 .
2024-05-17 09:06:42 -04:00
Elliot DeNolf
d33afe48fe chore(release): payload/2.18.1 [skip ci] 2024-05-16 15:46:23 -04:00
Elliot DeNolf
e76df32f09 fix: add back explicit crop x and y values (#6391)
Cropping x and y values pulling from the UI were unintentionally removed
in #6364
2024-05-16 15:32:36 -04:00
Elliot DeNolf
b068f30f51 chore(release): richtext-lexical/0.11.1 [skip ci] 2024-05-16 14:05:28 -04:00
Elliot DeNolf
82bd5c656f chore(release): db-postgres/0.8.3 [skip ci] 2024-05-16 14:05:16 -04:00
Elliot DeNolf
afe8992ca6 chore(release): payload/2.18.0 [skip ci] 2024-05-16 14:04:05 -04:00
Alessio Gravili
48a410e294 fix(richtext-lexical): upload, relationship and block node insertion fails sometimes (#6390)
Backport of https://github.com/payloadcms/payload/pull/6389
2024-05-16 13:34:43 -04:00
Elliot DeNolf
82b88a315f feat: store focal point on uploads (#6364)
Store focal point data on uploads as `focalX` and `focalY`

Addresses https://github.com/payloadcms/payload/discussions/4082
2024-05-16 11:58:49 -04:00
Patrik
cc94078607 fix: filter with ID not_in AND queries - postgres (#6358)
## Description

Fixes #5151 

`Issue`: With `Postgres`, when filtering by two queries with `AND`, if
the first query involved `ID` and the `not_in` operator, the second
query in the filter would never be evaluated.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
2024-05-15 15:09:53 -04:00
Elliot DeNolf
1c30ad73b6 chore(release): richtext-lexical/0.11.0 [skip ci] 2024-05-15 11:35:05 -04:00
Elliot DeNolf
d9442dcce3 chore(release): payload/2.17.0 [skip ci] 2024-05-15 11:33:53 -04:00
Patrik
de92c50847 fix: safely access cookie header for uploads (#6367)
## Description

Issue with editing and changing the crop or focal point of an image

`Error`:

```
ERROR (payload): FileRetrievalError: There was a problem while uploading the file. Cannot read properties of undefined (reading 'cookie')
    at generateFileData (/node_modules/payload/src/uploads/generateFileData.ts:86:15)
```
(`payload v2.16.1` and `plugin-cloud v3.0.1`)

Fix: add optional chaing to safely access `cookie` header when fetching
image

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## Checklist:

- [x] Existing test suite passes locally with my changes
2024-05-15 10:50:14 -04:00
Jacob Fletcher
b7f5f932f6 fix(examples/live-preview): regenerates yarn lockfiles (#6356) 2024-05-14 15:27:51 -04:00
Jessica Chowdhury
bc9e591e37 chore: removes letter spacing in loading overlay for script languages (#4769) 2024-05-14 16:51:34 +01:00
Jessica Chowdhury
ad38011348 chore: fix api preview indentation (#6152) 2024-05-14 16:09:17 +01:00
Patrik
d02b1fb084 fix: step-nav breadcrumbs ellipsis (#6345) 2024-05-14 11:08:59 -04:00
Jessica Chowdhury
51efe4f39b fix: collection labels with locales not working when creating new doc (#5995) 2024-05-14 10:45:39 -04:00
Jessica Chowdhury
30e535b5b9 feat: adds misc translations to API view and react select (#6138) 2024-05-13 08:52:12 -04:00
Jessica Chowdhury
4bd3bb9400 chore: adds translations for checkbox field in collection view (#6167) 2024-05-13 12:31:36 +01:00
Patrik
69c93d3c62 fix: appends editDepth value to radio & checkbox IDs when inside drawer (#6181) 2024-05-10 11:24:21 -04:00
Elliot DeNolf
78aa957043 fix(plugin-object-ids): add webpack to dev deps 2024-05-10 11:02:29 -04:00
Patrik
cd06c022c0 feat(plugin-relationship-object-ids): adds plugin-relationship-object-ids package (#6044) 2024-05-10 10:39:47 -04:00
Jacob Fletcher
8299e9fc33 docs(examples): adds examples docs (#6312) 2024-05-10 10:22:22 -04:00
Alessio Gravili
9df5ab8a10 feat(richtext-lexical)!: remove LexicalBlock, RichTextFieldRequiredEditor and FieldWithRichTextRequiredEditor types (#6279)
BREAKING:

`LexicalBlock`, `RichTextFieldRequiredEditor` and `FieldWithRichTextRequiredEditor` types have been removed. Instead of `LexicalBlock`, use `Block`. Instead of `RichTextFieldRequiredEditor`, use `RichTextField`. And instead of `FieldWithRichTextRequiredEditor`, use `Field`.
2024-05-09 09:46:03 -04:00
Elliot DeNolf
6979f5a1b1 ci: register release-canary workflow 2024-05-09 09:22:18 -04:00
Elliot DeNolf
723791b94f chore(release): richtext-lexical/0.10.0 [skip ci] 2024-05-07 15:53:11 -04:00
Elliot DeNolf
aa3833ec83 chore(release): payload/2.16.1 [skip ci] 2024-05-07 15:52:06 -04:00
Dan Ribbens
2972af2af1 chore: add index to version status field (#6256) 2024-05-07 15:47:55 -04:00
Alessio Gravili
857b9a4ac3 feat(richtext-lexical): add maxDepth property to various lexical features (#6250)
Backports #6242
2024-05-07 09:39:48 -04:00
Alessio Gravili
f829b084ba fix(richtext-lexical): export missing HorizontalRuleFeature (#6236) 2024-05-06 13:54:49 -04:00
Elliot DeNolf
6ae682698d chore(release): payload/2.16.0 [skip ci] 2024-05-06 12:47:28 -04:00
Francisco Lourenço
622cdb0440 fix: hide drag handles when admin.isSortable: false (#6225)
Co-authored-by: Kendell Joseph <kendelljoseph@gmail.com>
2024-05-06 12:21:35 -04:00
Jarrod Flesch
cac52da638 fix: graphql upload relations returning null (#6233) 2024-05-06 11:58:48 -04:00
DracoBlue
3cb3c1aceb docs(plugin-cloud): Fix link to local-dev.md (#6222) 2024-05-05 22:27:26 -04:00
Patrik
db4aacebb8 feat: adds disableListColumn, disableListFilter to fields admin props (#6188) 2024-05-03 16:49:06 -04:00
Paul
b735d6aa16 fix(plugin-form-builder): hook overrides not working as intended (#6203) 2024-05-03 17:36:03 -03:00
Elliot DeNolf
fbec3a33e0 chore(release): richtext-slate/1.5.2 [skip ci] 2024-05-03 11:23:16 -04:00
Elliot DeNolf
034be89bdb chore(release): richtext-lexical/0.9.3 [skip ci] 2024-05-03 11:23:00 -04:00
Elliot DeNolf
1f2af0963b chore(release): plugin-cloud/3.0.1 [skip ci] 2024-05-03 11:22:42 -04:00
Elliot DeNolf
20f1ece2d7 chore(release): payload/2.15.0 [skip ci] 2024-05-03 11:21:26 -04:00
Jessica Chowdhury
2be5ad0eba fix: hide unusable fields from collection filter select (#6135) 2024-05-03 11:01:47 -04:00
Kendell Joseph
5c58bd322d feat: add isSortable to arrays and blocks (#5962) 2024-05-03 10:38:02 -04:00
Dan Ribbens
23f3eb1cf0 feat: use filterOptions in list relationship filter (#6156) 2024-05-03 10:26:49 -04:00
Patrik
af67749e49 fix: incorrect localesNotSaved translation (#5996) 2024-05-03 10:22:06 -04:00
Patrik
43dab5c705 fix: sanitizes fields in default edit view for drawer content (#6175) 2024-05-03 10:16:24 -04:00
Patrik
9b7e62dc20 fix: properly adds readonly styles to disabled radio fields (#6176) 2024-05-03 10:07:52 -04:00
Patrik
6e38cc2bcf fix: resets filter state when param state change within route (#6169) 2024-05-02 13:21:51 -04:00
Tylan Davis
83551bfcaa docs: adjust line breaks in code blocks - v2 (#6002) 2024-05-01 15:58:15 -04:00
Francisco Lourenço
7b44d9d28a docs: fix outdated #aliasing-server-only-modules urls (#5014) 2024-05-01 15:52:18 -04:00
ovalice
182d5db6de docs: Fix RowLabel code snippet that causes compilation error (#4947)
Co-authored-by: smarten <user@example.com>
2024-05-01 15:42:43 -04:00
Mina Sameh
93109ec84a docs: edit code of generate email subject in verify auth section (#4607) 2024-05-01 15:31:24 -04:00
Take Weiland
4d9e0f35f0 docs: clarify docs around direction transaction access (#3648) 2024-05-01 15:22:48 -04:00
Carlo Taleon
19327c8d6d docs: slate linebreak serialization in 'Generating HTML' example (#3804) 2024-05-01 15:21:03 -04:00
Elliot DeNolf
831f1ff5be fix(plugin-cloud): purge cache for all sizes (#5301) 2024-05-01 15:15:16 -04:00
Jarrod Flesch
a8ac8b4633 fix: cascade draft arg in nested GraphQL relationship queries (#6141) 2024-04-30 14:19:20 -04:00
Alessio Gravili
36b1f5a763 fix(richtext-lexical): floating toolbar caret positioned incorrectly for some line heights (#6151) 2024-04-30 12:06:02 -04:00
Alessio Gravili
24f697219b fix(richtext-lexical): drag and add block handles disappear too quickly for smaller screen sizes. (#6145) 2024-04-30 10:52:37 -04:00
Jarrod Flesch
3fccd34abe fix: GraphQL nested relationships not respecting req locale (#6117) 2024-04-29 16:32:33 -04:00
Friggo
a38f8e93a6 chore: Czech translation improvement (#6079) 2024-04-28 07:57:47 -04:00
Dan Ribbens
84570e6e3b fix: bulk publish from collection list (#6063) 2024-04-28 07:30:37 -04:00
Friggo
5ad8e0edcb chore: Czech translation improvements (#6077) 2024-04-28 07:27:26 -04:00
Jarrod Flesch
91bac9c0aa fix: version restoration (#6039) 2024-04-26 16:15:14 -04:00
Elliot DeNolf
33f6edc9d5 chore(release): richtext-slate/1.5.1 [skip ci] 2024-04-26 16:05:01 -04:00
Elliot DeNolf
e1f91f5170 chore(release): richtext-lexical/0.9.2 [skip ci] 2024-04-26 16:04:37 -04:00
Elliot DeNolf
0e75dfb5c1 chore(release): plugin-stripe/0.0.17 [skip ci] 2024-04-26 16:04:29 -04:00
Elliot DeNolf
1300e264be chore(release): plugin-seo/2.3.2 [skip ci] 2024-04-26 16:04:21 -04:00
Elliot DeNolf
5600125de7 chore(release): plugin-search/1.1.1 [skip ci] 2024-04-26 16:04:14 -04:00
Elliot DeNolf
22e270f89c chore(release): plugin-redirects/1.0.2 [skip ci] 2024-04-26 16:04:06 -04:00
Elliot DeNolf
593f82bcba chore(release): plugin-form-builder/1.2.2 [skip ci] 2024-04-26 16:03:58 -04:00
Elliot DeNolf
cbf3da1144 chore(release): bundler-vite/0.1.7 [skip ci] 2024-04-26 16:03:49 -04:00
Elliot DeNolf
1a2aab4126 chore(release): payload/2.14.2 [skip ci] 2024-04-26 16:01:09 -04:00
Jacob Fletcher
d0ba694c80 fix(deps): dedupes react (#6058) 2024-04-26 11:43:14 -04:00
Elliot DeNolf
d78df36d9b ci(scripts): safer package details retrieval 2024-04-25 14:50:01 -04:00
Elliot DeNolf
02572d945a chore(release): db-postgres/0.8.2 [skip ci] 2024-04-25 14:39:37 -04:00
Elliot DeNolf
f05a433320 chore(release): richtext-lexical/0.9.1 [skip ci] 2024-04-25 14:38:56 -04:00
Elliot DeNolf
9ce3b3ab29 chore(release): db-mongodb/1.5.1 [skip ci] 2024-04-25 14:38:44 -04:00
Elliot DeNolf
ade637befb chore(release): payload/2.14.1 [skip ci] 2024-04-25 14:37:27 -04:00
Dan Ribbens
c31b8dcaa0 fix(db-postgres): cummulative updates (#6033) 2024-04-25 13:05:49 -04:00
Dan Ribbens
0ffdcc685f fix: disable api key checkbox does not remove api key (#6017) 2024-04-25 09:39:09 -04:00
James Mikrut
881119ba3a Update README.md (#6028) 2024-04-25 09:35:41 -04:00
Alessio Gravili
60372faf36 fix(richtext-lexical): minimize the amount of times sanitizeFields is called (#6018) 2024-04-24 17:51:14 -04:00
Elliot DeNolf
8bca0b0b86 chore(release): db-postgres/0.8.1 [skip ci] 2024-04-24 15:41:48 -04:00
Elliot DeNolf
87a1d698b2 chore(release): payload/2.14.0 [skip ci] 2024-04-24 15:40:04 -04:00
Dan Ribbens
c11600aac3 fix: bulk publish (#6006) 2024-04-24 15:04:50 -04:00
Elliot DeNolf
ad01c6784d fix: header filters (#5997) 2024-04-24 11:01:24 -04:00
Elliot DeNolf
62601c54a7 chore: update .vscode/settings.json 2024-04-24 08:59:45 -04:00
Elliot DeNolf
4a144ddc44 ci: register pr-title workflow 2024-04-23 23:31:13 -04:00
Patrik
9152a238d2 fix(db-postgres): row table names were not being built properly - v2 (#5961) 2024-04-22 16:56:03 -04:00
Mike Keefe
fc8b835264 docs: fix typo in admin custom components docs (#5944) 2024-04-21 20:39:32 -04:00
Elliot DeNolf
28ee5e34c3 chore(readme): add 3.0 beta announcement [skip ci] 2024-04-21 16:54:26 -04:00
Ricardo Domingues
e25886649f fix(db-postgres): Fixes nested groups inside nested blocks (#5882)
Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
2024-04-21 00:18:25 -04:00
Rafał Nawojczyk
985796be54 fix: min/max attributes missing from number input (#5779) 2024-04-20 23:36:32 -04:00
Dan Ribbens
bd8b5123b0 fix(db-postgres): extra version suffix added to table names (#5939) 2024-04-20 23:23:31 -04:00
Ritsu
c380deee4a feat: add count operation to collections (#5936) 2024-04-20 23:05:37 -04:00
Elliot DeNolf
0b12aac895 ci: bump actions node version (#5103) 2024-04-20 08:54:12 -04:00
Christian Gil
90d3f178ab feat(live-preview-vue): Vue Hook for Live Preview (#5925) 2024-04-20 06:45:18 -04:00
Patrik
a8c9625cde fix: removes equals & not_equals operators from fields with hasMany (#5885) 2024-04-19 11:41:39 -04:00
Elliot DeNolf
938d069523 chore(release): plugin-seo/2.3.1 [skip ci] 2024-04-19 11:38:41 -04:00
Elliot DeNolf
1a337ec223 chore(release): richtext-lexical/0.9.0 [skip ci] 2024-04-19 11:38:09 -04:00
Elliot DeNolf
08f372e6c2 chore(release): db-postgres/0.8.0 [skip ci] 2024-04-19 11:37:56 -04:00
Elliot DeNolf
2994269f22 chore(release): db-mongodb/1.5.0 [skip ci] 2024-04-19 11:37:43 -04:00
Elliot DeNolf
8d1a706928 chore(release): payload/2.13.0 [skip ci] 2024-04-19 11:36:17 -04:00
Pan
fcb29bb1c6 feat(plugin-seo): add Chinese translation (#5429) 2024-04-19 11:13:26 -04:00
Kendell Joseph
2c402cc65c feat: json field schemas (#5726) 2024-04-19 10:45:40 -04:00
Elliot DeNolf
ad38f76011 fix: properly handle drafts in bulk update (#5872)
Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
2024-04-19 10:08:26 -04:00
Jessica Chowdhury
b974a2c042 chore(i18n): adds document translation key (#5889) 2024-04-18 10:17:35 +01:00
Dan Ribbens
cb8d562132 fix(db-mongodb): ignore end session errors (#5904) 2024-04-17 16:44:15 -04:00
Patrik
1f0036054a fix: adds type error validations for email and password in login operation (#4852) 2024-04-17 16:31:35 -04:00
Elliot DeNolf
aaa4397351 ci: cut down on codeowners noise [skip ci] 2024-04-16 22:10:44 -04:00
Dan Ribbens
6185f8a5d8 fix(db-postgres): query hasMany fields with in (#5881) 2024-04-16 17:09:53 -04:00
Jacob Fletcher
e47e544364 fix(plugin-seo): uses correct key for ukrainian translation (#5873) 2024-04-16 11:16:33 -04:00
Bohdan Kucheriavyi
2e80350a5a chore(plugin-seo): adds Ukrainian translations (#5843)
Signed-off-by: Bohdan Kucheriavyi <bohdan.kucheriavyi@zapal.tech>
2024-04-16 09:31:18 -04:00
Ritsu
4c4f924e90 fix(db-postgres): validateExistingBlockIsIdentical localized (#5839) 2024-04-15 16:49:43 -04:00
Elliot DeNolf
170957c380 feat: allow configuration for setting headers on external file fetch (#5865) 2024-04-15 15:09:00 -04:00
Elliot DeNolf
9061ae05e7 docs: add externalFileHeaderFilter 2024-04-15 15:08:03 -04:00
Dan Ribbens
fe0028c899 fix(db-mongodb): version fields indexSortableFields (#5863) 2024-04-15 14:46:06 -04:00
Elliot DeNolf
ec1ad0b662 feat: allow configuration for setting headers on external file fetch 2024-04-15 14:40:55 -04:00
Tylan Davis
e5f32562a3 docs: adds missing tick marks (#5858) 2024-04-15 13:06:17 -04:00
Tylan Davis
ba6100cbe8 docs: adds missing tick marks 2024-04-15 13:03:44 -04:00
Alessio Gravili
c08c8b5628 ci: add weird tune linux network step which seems to reduce flakes (#5857) 2024-04-15 12:38:38 -04:00
James Mikrut
9e918831d1 fix: number ids were not sanitized to number in rest api (#5794) 2024-04-15 11:02:36 -04:00
Patrik
25c9a145be fix: passes parent id instead of incoming id to saveVersion (#5831) 2024-04-15 10:42:36 -04:00
Alessio Gravili
3b1d331316 fix(richtext-lexical): use correct nodeType on HorizontalRule feature HTML converter (#5805) 2024-04-11 16:10:55 -04:00
Alessio Gravili
5aa68b5e5d feat(richtext-lexical): add HorizontalRuleFeature, improve block handle positioning (#5804) 2024-04-11 15:54:56 -04:00
Alessio Gravili
d8e9084db2 feat(richtext-lexical): add HorizontalRuleFeature 2024-04-11 15:37:45 -04:00
Dan Ribbens
65690a675c fix(db-postgres): relationship query pagination (#5802) 2024-04-11 15:37:19 -04:00
PatrikKozak
9530d28a67 fix: updates var 2024-04-11 15:08:24 -04:00
PatrikKozak
509ec677c4 fix: uses find instead of fieldIndex for custom ID check 2024-04-11 14:19:45 -04:00
Alessio Gravili
a00439ea89 fix(richtext-lexical): limit unnecessary floating handle positioning updates 2024-04-11 14:12:59 -04:00
Alessio Gravili
0055a8eb36 feat(richtext-lexical): improve floating handle y-positioning by positioning it in the center for smaller elements. 2024-04-11 13:50:24 -04:00
Alessio Gravili
de5d6cc4bd fix(richtext-lexical): incorrect floating handle y-position calculation next to certain kinds of HTML elements like HR 2024-04-11 12:29:49 -04:00
PatrikKozak
51f84a4fcf fix: number ids were not sanitized to number in rest api 2024-04-11 12:23:57 -04:00
Paul
c0ba6cc19a fix: use isolateObjectProperty function in createLocalReq (#5748) 2024-04-11 09:27:42 -04:00
Patrik
5fa99fb060 fix(db-mongodb): failing contains query with special chars (#5774) 2024-04-11 09:23:05 -04:00
Patrik
e3c3ddac34 fix: avoids getting and setting doc preferences when creating new (#5757) 2024-04-10 11:20:02 -04:00
Alessio Gravili
6186493246 fix(richtext-lexical)!: do not allow omitting editor prop for sub-richtext fields within lexical defined in the payload config (#5766)
**BREAKING:** Modifies fields types which are allowed to be passed in to upload, link, and blocks lexical features. Can break your types even if no sub-richText editor is passed in
2024-04-10 11:14:32 -04:00
Alessio Gravili
9b44296092 fix(richtext-lexical): catch errors that may occur during HTML generation (#5754) 2024-04-09 15:58:34 -04:00
Paul
cbd03ed2f8 fix: req.collection being lost when querying a global inside a collection (#5727) 2024-04-08 15:16:37 -03:00
Alessio Gravili
cf135fd1e4 fix(richtext-lexical): pass through config for schema generation. Makes it more robust (#5700) 2024-04-05 15:55:51 -04:00
Dan Ribbens
e7608f5507 fix: block field type missing dbName (#5695) 2024-04-05 15:52:06 -04:00
Alessio Gravili
608d6d0a87 fix(db-postgres): hasMany relationship query contains operator (#4212)
Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
2024-04-05 13:59:00 -04:00
Dan Ribbens
9bbacc4fb1 feat: custom db table and enum names (#5045)
Co-authored-by: Ritsu <enjoythepain1337@gmail.com>
2024-04-05 11:22:46 -04:00
Patrik
7df7bf448b fix: updates type name of CustomPublishButtonProps to CustomPublishButtonType (#5644)
* fix: updates type name from CustomPublishButtonProps to CustomPublishButtonType

* fix: maps old name to new name
2024-04-04 16:55:18 -04:00
Paul
44599cbc7b fix(db-postgres): issue querying by localised relationship not respecting locale as constraint (#5666)
* fix: add table join for querying on a localised field in relationship fields

* chore: add int tests in relationships
2024-04-04 16:07:11 -03:00
Patrik
373787de31 fix: duplicate document multiple times in quick succession (#5642) 2024-04-04 14:06:29 -04:00
Patrik
c1c86009a5 fix: missing date locales (#5656) 2024-04-04 13:55:07 -04:00
Paul
6cf6ca3ea8 fix(website template): archiveBlock being populated with draft items by default, causing an error for graphql in the frontend (#5643)
* fix(website template): archiveBlock being populated with draft items by default, causing an error for graphql in the frontend
2024-04-03 19:34:36 -03:00
Elliot DeNolf
6706bdb140 chore(release): db-mongodb/1.4.4 [skip ci] 2024-04-03 14:54:53 -04:00
Elliot DeNolf
5caaa032bb chore(release): payload/2.12.1 [skip ci] 2024-04-03 14:37:42 -04:00
Elliot DeNolf
4cf8c5bd78 Merge pull request #5637 from payloadcms/chore/release-2.12.0
chore(release): 2.12.0
2024-04-03 14:34:55 -04:00
Elliot DeNolf
d6afee662b chore(release): db-postgres/0.7.1 [skip ci] 2024-04-03 14:27:20 -04:00
Elliot DeNolf
0fc62446b8 chore(release): richtext-slate/1.5.0 [skip ci] 2024-04-03 14:26:11 -04:00
Elliot DeNolf
823fde07c3 chore(release): richtext-lexical/0.8.0 [skip ci] 2024-04-03 14:25:56 -04:00
Elliot DeNolf
fe35b7d32c chore(release): plugin-seo/2.3.0 [skip ci] 2024-04-03 14:25:47 -04:00
Elliot DeNolf
3b45b0d085 chore(release): payload/2.12.0 [skip ci] 2024-04-03 14:24:24 -04:00
Yunsup Sim
742a7af93d fix: Skip parsing if operator is 'exist' (#5404) 2024-04-03 13:50:28 -04:00
Patrik
a7e7c92768 fix: updates colors of tooltip in light mode (#5632) 2024-04-03 13:47:08 -04:00
Patrik
e10d5df0b2 fix: sets beforeValidateHook req type to required (#5608) 2024-04-03 13:42:05 -04:00
Patrik
3023118b71 chore: updates comment in globals afterchange hook example (#5606) 2024-04-03 13:36:17 -04:00
Patrik
80375d1798 docs: updates incorrect rate limit from 90000 to 900000 (#5630) 2024-04-03 13:36:01 -04:00
Jørgen Kalsnes Hagen
589b492b2e feat(plugin-seo): adds Norwegian translation (#5621) 2024-04-03 13:27:17 -04:00
Elliot DeNolf
bdeef377ea ci: docker compose v2, v1 no longer supported on gh runner (#5623) 2024-04-03 11:28:47 -04:00
Elliot DeNolf
b76c5c8c11 chore: update all package.json repository urls 2024-04-03 11:06:42 -04:00
dependabot[bot]
58c9fecbae chore(deps): bump es5-ext in /examples/whitelabel (#5185)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 10:01:57 -04:00
dependabot[bot]
e88de5db60 chore(deps): bump express from 4.18.2 to 4.19.2 in /templates/ecommerce (#5533)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 10:01:09 -04:00
dependabot[bot]
ce75fab4fc chore(deps): bump express from 4.18.2 to 4.19.2 in /examples/testing (#5541)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 10:00:26 -04:00
dependabot[bot]
5b57f1411a chore(deps): bump express from 4.18.2 to 4.19.2 in /examples/email (#5535)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 10:00:20 -04:00
dependabot[bot]
11ff2042f3 chore(deps): bump express from 4.18.2 to 4.19.2 in /templates/website (#5537)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 10:00:14 -04:00
dependabot[bot]
8f9481f8a7 chore(deps): bump express in /examples/redirects/payload (#5544)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 10:00:05 -04:00
dependabot[bot]
5de32b2534 chore(deps): bump es5-ext from 0.10.62 to 0.10.64 in /examples/hierarchy (#5198)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:59:37 -04:00
dependabot[bot]
dbcffc688f chore(deps): bump es5-ext in /examples/draft-preview/payload (#5192)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:59:31 -04:00
dependabot[bot]
17cf179d16 chore(deps): bump es5-ext in /examples/auth/payload (#5191)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:59:26 -04:00
dependabot[bot]
1dc86aa6e6 chore(deps): bump es5-ext from 0.10.62 to 0.10.64 in /templates/website (#5190)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:59:19 -04:00
dependabot[bot]
d8e0824547 chore(deps): bump es5-ext in /examples/multi-tenant (#5189)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:59:09 -04:00
dependabot[bot]
1453547e35 chore(deps): bump es5-ext from 0.10.62 to 0.10.64 in /templates/blank (#5188)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:59:01 -04:00
dependabot[bot]
4c6874449a chore(deps): bump es5-ext in /examples/custom-server (#5187)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:58:50 -04:00
dependabot[bot]
332c9b3a98 chore(deps): bump es5-ext in /templates/ecommerce (#5186)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:58:36 -04:00
dependabot[bot]
73544b5b5e chore(deps): bump es5-ext from 0.10.62 to 0.10.64 in /examples/email (#5184)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:58:28 -04:00
dependabot[bot]
e03302160a chore(deps): bump es5-ext from 0.10.62 to 0.10.64 in /examples/testing (#5193)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:57:09 -04:00
dependabot[bot]
edb530fc64 chore(deps): bump es5-ext in /examples/live-preview/payload (#5194)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:57:04 -04:00
dependabot[bot]
064b4baed8 chore(deps): bump es5-ext in /examples/form-builder/payload (#5195)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:56:59 -04:00
dependabot[bot]
4cb8259b8b chore(deps): bump es5-ext in /examples/redirects/payload (#5196)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:56:53 -04:00
dependabot[bot]
34b2451b3b chore(deps): bump es5-ext in /examples/nested-docs/payload (#5197)
Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64.
- [Release notes](https://github.com/medikoo/es5-ext/releases)
- [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md)
- [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64)

---
updated-dependencies:
- dependency-name: es5-ext
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:56:48 -04:00
dependabot[bot]
29ccd06553 chore(deps): bump follow-redirects in /examples/testing (#5349)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:56:37 -04:00
dependabot[bot]
a5971c12b3 chore(deps): bump express from 4.18.2 to 4.19.2 in /examples/whitelabel (#5531)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:56:15 -04:00
dependabot[bot]
0900baf8f9 chore(deps): bump express from 4.18.2 to 4.19.2 in /templates/blank (#5532)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:56:07 -04:00
dependabot[bot]
d1a9a3e4d5 chore(deps): bump express in /examples/multi-tenant (#5534)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:55:59 -04:00
dependabot[bot]
d27a33dc1d chore(deps): bump express in /examples/custom-server (#5536)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:55:52 -04:00
dependabot[bot]
d01c586a90 chore(deps): bump express in /examples/draft-preview/payload (#5538)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:55:42 -04:00
dependabot[bot]
caa0d7cf0d chore(deps): bump express in /examples/auth/payload (#5539)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:55:36 -04:00
dependabot[bot]
c40b5a1784 chore(deps): bump express in /examples/live-preview/payload (#5542)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:55:29 -04:00
dependabot[bot]
b0869ea0ed chore(deps): bump express in /examples/form-builder/payload (#5543)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:55:22 -04:00
dependabot[bot]
00faebed4b chore(deps): bump express in /examples/nested-docs/payload (#5547)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:55:07 -04:00
dependabot[bot]
638a35a2e7 chore(deps): bump express from 4.18.2 to 4.19.2 in /examples/hierarchy (#5552)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-03 09:54:58 -04:00
Alessio Gravili
44bca2ed36 Merge pull request #5622 from payloadcms/fix/lexical-html-conversion 2024-04-03 09:53:30 -04:00
Alessio Gravili
fa90cec758 docs(richtext-lexical): clarify that HTML generation has to happen on the server 2024-04-03 09:52:31 -04:00
Alessio Gravili
2164dcc594 fix(richtext-lexical): disable instanceof HTMLImageElement check as it causes issues when used on the server 2024-04-03 09:50:46 -04:00
Jessica Chowdhury
a3ae416085 fix: number field with hasMany accept defaultValue array (#5618) 2024-04-03 08:05:17 -04:00
Alessio Gravili
02d2c51717 feat(richtext-*): add ability to provide custom Field and Error components (#5574) 2024-03-31 20:57:30 -04:00
Alessio Gravili
b3503e3dce docs(richtext-slate): update outdated code example (#5572) 2024-03-31 17:49:17 -04:00
Alessio Gravili
2e5400fa7a fix(richtext-lexical): checklist html converter incorrectly outputting children (#5570) 2024-03-31 16:23:40 -04:00
Alessio Gravili
48dc116f57 fix(richtext-lexical): properly center add- and drag-block handles (#5568) 2024-03-31 16:03:51 -04:00
Dan Ribbens
9b2ba7cc0e chore: fix test config defaultValue typo (#5562) 2024-03-29 17:56:21 -04:00
Dan Ribbens
916923071a fix(db-postgres): error on delete having joins (#5459)
* chore(db-postgres): reduce duplicate lines of code

* chore(db-postgres): fix deleteOne regression

* chore(db-postgres): missing await
2024-03-26 14:00:46 -04:00
Dan Ribbens
3ceb6efd32 fix: regression of filterOptions using different transaction (#5169) 2024-03-25 11:13:49 -04:00
Dan Ribbens
8184e0005a fix: image resize tiff files (#5415) 2024-03-25 10:50:02 -04:00
Tylan Davis
1c0d43c61a fix(docs): broken links (#5340)
* fix: broken links

* fix: another broken link
2024-03-15 10:35:25 -04:00
Alessio Gravili
0eb7b44735 chore(eslint-config-payload): improve @typescript-eslint/no-unused-vars rule (#4793) 2024-03-12 12:44:36 -04:00
geisterfurz007
c038acb3a4 chore: fix typescript hallucinations (#4559)
* chore: fix typescript halluzinations

* chore: remove another unused ts-expect-error directive
2024-03-10 01:30:01 -05:00
Jarrod Flesch
f8c2ccf6b1 chore(examples/multi-tenant): updates readme, fixes payload.init 2024-03-10 00:38:51 -05:00
Akhil Naidu
e6092fd36c docs: improve naming for afterForgotPassword hook example code (#5062) 2024-03-10 00:22:58 -05:00
Max Morozov
e0eae77758 docs: fix typo (#5052) 2024-03-10 00:12:29 -05:00
mhjmaas
0780ff22bb chore(translations): NL mistranslation of crop from "gewas" to "bijsnijden" 2024-03-07 22:58:08 -05:00
Alessio Gravili
e7f6bfbe9d fix(richtext-lexical): Blocks: generated output schema is not fully correct (#5259) 2024-03-07 13:27:27 -05:00
Fabian Aggeler
23df60dba5 fix(richtext-lexical): Link: add open-in-new-tab to html converter 2024-03-07 13:22:02 -05:00
Dan Ribbens
8919b86571 chore(ecommerce-template): fix duplicate cart update calls (#5228) 2024-03-05 10:51:50 -05:00
dependabot[bot]
8104fac5ed chore(deps): bump ip from 2.0.0 to 2.0.1 in /examples/whitelabel (#5128)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:25:00 -05:00
dependabot[bot]
59ef1263a5 chore(deps): bump ip from 2.0.0 to 2.0.1 in /examples/auth/payload (#5134)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:24:53 -05:00
dependabot[bot]
813e3dbc98 chore(deps): bump ip from 2.0.0 to 2.0.1 in /examples/redirects/payload (#5138)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:24:45 -05:00
dependabot[bot]
12a23092e1 chore(deps): bump ip from 1.1.8 to 1.1.9 in /examples/email (#5127)
Bumps [ip](https://github.com/indutny/node-ip) from 1.1.8 to 1.1.9.
- [Commits](https://github.com/indutny/node-ip/compare/v1.1.8...v1.1.9)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:24:23 -05:00
dependabot[bot]
4a49beb552 chore(deps): bump ip from 2.0.0 to 2.0.1 in /templates/blank (#5129)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:24:14 -05:00
dependabot[bot]
80530c666e chore(deps): bump ip from 2.0.0 to 2.0.1 in /examples/multi-tenant (#5130)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:24:09 -05:00
dependabot[bot]
f53e2df951 chore(deps): bump ip from 2.0.0 to 2.0.1 in /templates/website (#5131)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:24:01 -05:00
dependabot[bot]
db58e2bab2 chore(deps): bump ip from 2.0.0 to 2.0.1 in /examples/custom-server (#5132)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:23:56 -05:00
dependabot[bot]
d88e97e123 chore(deps): bump ip in /examples/draft-preview/payload (#5133)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:23:48 -05:00
dependabot[bot]
bb72e506e6 chore(deps): bump ip from 2.0.0 to 2.0.1 in /examples/testing (#5135)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:23:40 -05:00
dependabot[bot]
b1f727fd6a chore(deps): bump ip in /examples/live-preview/payload (#5136)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:23:33 -05:00
dependabot[bot]
72af18229b chore(deps): bump ip in /examples/form-builder/payload (#5137)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:23:27 -05:00
dependabot[bot]
af52b526c8 chore(deps): bump ip in /examples/nested-docs/payload (#5139)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:23:17 -05:00
dependabot[bot]
60525623bf chore(deps): bump ip from 2.0.0 to 2.0.1 in /examples/hierarchy (#5140)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:23:11 -05:00
dependabot[bot]
0fba582926 chore(deps): bump ip from 2.0.0 to 2.0.1 in /templates/ecommerce (#5126)
Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1.
- [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-26 11:22:49 -05:00
Elliot DeNolf
5d1cad3adb chore(release): db-postgres/0.7.0 [skip ci] 2024-02-23 14:31:55 -05:00
Elliot DeNolf
e31f72da8e chore(release): plugin-nested-docs/1.0.12 [skip ci] 2024-02-23 14:31:26 -05:00
Elliot DeNolf
7aa058d604 chore(release): db-mongodb/1.4.3 [skip ci] 2024-02-23 14:31:11 -05:00
Elliot DeNolf
64e80d242e chore(release): payload/2.11.2 [skip ci] 2024-02-23 14:29:37 -05:00
Dan Ribbens
e8f2ca484e feat(db-postgres): configurable custom schema to use (#5047)
* feat(db-postgres): configurable custom schema to use

* test(db-postgres): use public schema

* chore(db-postgres): simplify drop schema

* chore: add postgres-custom-schema test to ci

* chore: add custom schema to postgres ci

* chore(db-postgres): custom schema in migrate

* chore: ci postgres wait condition
2024-02-23 12:48:06 -05:00
Dan Ribbens
ceca5c4e97 fix(db-postgres): set _parentID for array nested localized fields (#5117)
* fix(db-postgres): find missing path for nested arrays

* fix(db-postgres): set _parentID for array nested localized fields

* fix: afterRead fallbackLocale causing locale data loss

* chore(richtext-lexical): updated args to match payload type change

* test: simplify localization e2e duplicate
2024-02-23 12:44:30 -05:00
Dan Ribbens
ee13736288 chore(plugin-nested-docs): payload added to peerDependencies (#5143) 2024-02-23 12:37:42 -05:00
Dan Ribbens
815bdfac0b fix(db-mongodb): unique sparse for not required fields (#5114)
* fix(db-mongodb): unique sparse for not required fields

* chore(db-mongodb): cleanup sparse index condition

* test: indexed field fix
2024-02-23 12:36:34 -05:00
Dan Ribbens
7a7f0ed7e8 fix: disabling API Key does not remove the key (#5145)
* fix: disabling API Key does not remove the key

* chore: encryptKey hook return null

* chore: fix auth e2e test setup
2024-02-23 12:31:14 -05:00
Dan Ribbens
ad42d541b3 fix: transaction error from access endpoint (#5156)
* fix: transaction error from access endpoint

* chore: fix async race condition in getEntityPolicies
2024-02-23 12:28:43 -05:00
Elliot DeNolf
32ed95e1ee fix: handle thrown errors in config-level afterError hook (#5147) 2024-02-21 16:44:16 -05:00
Yunsup Sim
70e57fef18 fix: Add Context Provider in EditMany Component (#5005)
* fix: Add  Context Provider in EditMany Component

* test: Fix e2e test error
2024-02-21 16:39:34 -05:00
Jarrod Flesch
0a07f607b9 fix: only replace the drawer content with full edit component if it exists (#5144) 2024-02-21 15:44:09 -05:00
Piotr Rogowski
3918fc7c21 chore(plugin-seo): add pl translations (#5021) 2024-02-21 15:01:38 -05:00
Martin Chełminiak
13f71ac475 chore: console error for missing script when running npm run payload (#5078) 2024-02-19 10:13:50 -05:00
Ben Regenspan
07720e777a docs: Reword Hooks Overview re: server-only execution (#5070) 2024-02-19 09:56:55 -05:00
Sondre Ørland
efff47e400 chore: translation for image cropping in norwegian bokmål (#5113) 2024-02-19 09:47:32 -05:00
Elliot DeNolf
453ac218ea chore: reorder changelog 2024-02-17 01:38:13 -05:00
Elliot DeNolf
d4b09bd9cd chore(release): richtext-lexical/0.7.0 [skip ci] 2024-02-16 15:00:13 -05:00
Elliot DeNolf
dd67e03fc1 chore(release): plugin-search/1.1.0 [skip ci] 2024-02-16 15:00:03 -05:00
Elliot DeNolf
548de80bee chore(release): db-postgres/0.6.0 [skip ci] 2024-02-16 14:59:51 -05:00
Elliot DeNolf
2c05fbbb5e chore(release): plugin-form-builder/1.2.1 [skip ci] 2024-02-16 14:59:15 -05:00
Elliot DeNolf
9b54659818 chore(release): db-mongodb/1.4.2 [skip ci] 2024-02-16 14:58:57 -05:00
Elliot DeNolf
e9f550406e chore(release): payload/2.11.1 [skip ci] 2024-02-16 14:57:28 -05:00
Dan Ribbens
98b87e2278 feat(plugin-search): add req to beforeSync args for transactions (#5068)
* feat(plugin-search): pass `req` to beforeSync to support using transactions

* fix(plugin-search): hooks do not respect transactions

* chore(plugin-search): await hooks

* chore: remove eslint disable comments
2024-02-16 14:20:40 -05:00
Dan Ribbens
5f3d0169be fix: filterOptions errors cause transaction to abort (#5079)
* fix: filterOptions errors cause transaction to abort

* fix(db-mongodb): uncaught abortTransaction race condition

* chore: remove test that is not adding value

* chore: limit options on errors in filterOptions

* chore: limit options when an error occurs in filterOptions
2024-02-16 13:33:40 -05:00
Dan Ribbens
35c2a085ef fix(db-postgres): query using blockType (#5044)
* fix(db-postgres): query using blockType

* chore: cleanup commented lines
2024-02-16 13:30:26 -05:00
Dan Ribbens
1ac943ed5e fix: remove collection findByID caching (#5034) 2024-02-16 13:23:57 -05:00
Elliot DeNolf
25cee8bb10 fix(uploads): account for serverURL when retrieving external file (#5102) 2024-02-16 13:11:18 -05:00
Elliot DeNolf
419aef452d chore: add .localstack to gitignore 2024-02-16 12:53:28 -05:00
Elliot DeNolf
ea52489126 Merge pull request #4295 from payloadcms/test/plugin-cloud-storage-emulators
test(plugin-cloud-storage): use localstack for tests
2024-02-16 12:47:13 -05:00
Elliot DeNolf
e80c70acae test: cleanup 2024-02-16 12:33:07 -05:00
Elliot DeNolf
70b0064d0b test: adjust adapter log message 2024-02-16 11:32:00 -05:00
Elliot DeNolf
9636bf6efd test: rename .env -> .env.emulated, safely assert bucket contents 2024-02-16 11:31:14 -05:00
Elliot DeNolf
8f4d0da4e0 test: conditionally run plugin-cloud-storage 2024-02-16 11:31:14 -05:00
Elliot DeNolf
f0f1dbdcb0 ci: pnpm docker:start 2024-02-16 11:31:14 -05:00
Elliot DeNolf
a895aee8b1 ci: add localstack aws envs 2024-02-16 11:31:14 -05:00
Elliot DeNolf
aa1dac08c1 ci: add localstack setup 2024-02-16 11:31:14 -05:00
Elliot DeNolf
b8cd1c6ba4 test(plugin-cloud-storage): add test against localstack 2024-02-16 11:31:12 -05:00
Elliot DeNolf
6344464bc6 test(plugin-cloud-storage): add single docker compose for all emulators 2024-02-16 11:30:55 -05:00
Dan Ribbens
5d4022f144 fix(db-mongodb): find versions pagination (#5091) 2024-02-15 16:14:01 -05:00
Dan Ribbens
bf942fdfa6 feat(db-postgres): reconnect after disconnection from database (#5086) 2024-02-15 16:09:17 -05:00
Dan Ribbens
d6c25783cf feat(db-postgres): adds idType to use uuid or serial id columns (#3864)
* feat(db-postgres): WIP adds idType to use uuid or serial id columns

* chore: add postgres-uuid test ci

* chore: add postgres-uuid env vars

* chore: sanitizeQueryValue prevent invalid types

* fix(db-postgres): invalid parentID of nested arrays
2024-02-15 16:06:37 -05:00
Dan Ribbens
82e9d31127 fix(plugin-form-builder): hooks do not respect transactions (#5069)
* fix(plugin-form-builder): hooks do not respect transactions

* chore(plugin-form-builder): linting and cleanup
2024-02-15 15:55:42 -05:00
Elliot DeNolf
399e606b34 chore: use ref for pnpm overrides (#5081) 2024-02-13 12:37:43 -05:00
Alessio Gravili
0d18822062 feat(richtext-lexical)!: Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground (#5066)
* feat(richtext-lexical): Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground

* chore: upgrade lexical version used in monorepo
2024-02-12 17:54:50 +01:00
Alessio Gravili
00fc0343da feat(richtext-lexical): AddBlock handle for all nodes, even if they aren't empty paragraphs (#5063) 2024-02-12 16:11:41 +01:00
Alessio Gravili
6323965c65 fix(richtext-lexical): do not remove adjacent paragraph node when inserting certain nodes in empty editor (#5061) 2024-02-12 14:27:58 +01:00
Máté Tallósi
6d6823c3e5 feat(richtext-lexical): add justify aligment to AlignFeature (#4035) (#4868) 2024-02-12 14:27:12 +01:00
Alessio Gravili
ca70298436 chore: upgrade nodemon versions (#5059) 2024-02-12 14:11:57 +01:00
Elliot DeNolf
4f565759f6 chore(release): payload/2.11.0 [skip ci] 2024-02-09 16:12:03 -05:00
Jarrod Flesch
df39602758 feat: exposes collapsible provider with more functionality (#5043) 2024-02-09 10:38:30 -05:00
Elliot DeNolf
6ea6172afa chore(release): db-postgres/0.5.2 [skip ci] 2024-02-09 09:06:15 -05:00
Elliot DeNolf
486774796d chore(release): db-mongodb/1.4.1 [skip ci] 2024-02-09 09:06:06 -05:00
Elliot DeNolf
1cd1c38764 chore(release): payload/2.10.1 [skip ci] 2024-02-09 09:04:42 -05:00
Elliot DeNolf
f6d7da7510 fix: clearable cells handle null values (#5038) 2024-02-09 08:59:38 -05:00
Elliot DeNolf
cdc4cb971b fix(db-mongodb): handle null values with exists (#5037) 2024-02-09 08:58:10 -05:00
Elliot DeNolf
e0191b54e1 chore(release): richtext-lexical/0.6.1 [skip ci] 2024-02-08 11:49:02 -05:00
Alessio Gravili
2315781f18 fix(richtext-lexical): make editor reactive to initialValue changes (#5010) 2024-02-08 15:30:21 +01:00
Elliot DeNolf
a0a58e7fd2 fix: query relationships by explicit id field (#5022) 2024-02-07 14:18:13 -05:00
Jessica Chowdhury
e1813fb884 fix: ensures docs with the same id are shown in relationship field select (#4859) 2024-02-07 14:04:03 -05:00
Elliot DeNolf
da184d40ec fix(db-postgres): handle nested docs with drafts (#5012) 2024-02-06 21:27:33 -05:00
Elliot DeNolf
ca8675f89d chore(release): plugin-seo/2.2.1 [skip ci] 2024-02-06 15:41:58 -05:00
Elliot DeNolf
e8c6c9338d chore(release): db-postgres/0.5.1 [skip ci] 2024-02-06 15:41:35 -05:00
Elliot DeNolf
558534aff8 chore(release): richtext-lexical/0.6.0 [skip ci] 2024-02-06 15:41:04 -05:00
Elliot DeNolf
29c901ba9b chore(release): payload/2.10.0 [skip ci] 2024-02-06 15:38:33 -05:00
Elliot DeNolf
f3876c2a39 fix(db-postgres): localized field sort count (#4997)
* fix(db-postgres): localized field sort count

* test: localized sort doc count
2024-02-06 11:44:54 -05:00
Elliot DeNolf
c3a3942969 fix(db-postgres): filtering relationships with drafts enabled (#4998)
* fix(db-postgres): filtering relationships with drafts enabled

* test: draft relationship filtering
2024-02-06 11:16:27 -05:00
Paul
23b135b963 fix(templates): fix conflicting routes with Nextjs (#4725)
* Updated templates and readme to note conflicting routes

* Move information in readmes to blockquotes and move next-api to just next

* Remove unnecessary notes
2024-02-06 10:56:20 -05:00
Daniel Kirchhof
e3c8105cc2 feat: use deletion success message from server if provided (#4966) 2024-02-06 10:17:53 -05:00
Jarrod Flesch
2c71aaef75 chore: standardize req passed through the local API (#4994) 2024-02-05 15:43:59 -05:00
brachypelma
922fb9b7fa docs: added link to JSON field type (#4989) 2024-02-05 13:13:28 -05:00
Elliot DeNolf
0740d5095e fix(migrations): safely create migration file when no name passed (#4995) 2024-02-05 10:43:19 -05:00
Jacob Fletcher
b392d656fe chore(examples/multi-tentant): resets lastLoggedInTenant when none found (#4984) 2024-02-02 15:50:12 -05:00
Elliot DeNolf
c0eef90cdc ci: supabase (#4983)
* ci: supabase

* test: add supabase to adapter record

* test: adjust index tests conditional
2024-02-02 15:26:18 -05:00
Dan Ribbens
db22cbdf21 fix(plugin-seo): tabbedUI with email field causes duplicate field (#4944)
* fix(plugin-seo): tabbedUI with email field causes duplicate field

* chore(plugin-seo): code comment
2024-02-02 14:53:51 -05:00
Dan Ribbens
1e8a6b7899 feat: extend transactions to cover after and beforeOperation hooks (#4960)
* feat: extend transactions to cover after and beforeOperation hooks

* feat: use transactions in refresh operation

* docs: add req to beforeOperation and afterOperation args
2024-02-02 14:53:14 -05:00
Dan Ribbens
5d934ba02d feat: previousValue and previousSiblingDoc args added to beforeChange field hooks (#4958)
* feat: previousValue and previousSiblingDoc args added to beforeChange field hooks

* chore: fieldHook type docs
2024-02-02 13:59:11 -05:00
Elliot DeNolf
f651665f2f chore(deps): add pnpm overrides for common packages (#4980)
* chore(deps): add pnpm overrides for common packages

* chore(deps): bump @swc/core for compat w/ latest typescript
2024-02-02 13:21:57 -05:00
Elliot DeNolf
5d3659d48a fix(db-postgres): handle schema changes with supabase (#4968)
* fix(db-postgres): handle schema changes with supabase

* chore(deps): bump drizzle-orm for test suite
2024-02-02 11:29:32 -05:00
Dan Ribbens
47106d5a1a fix(db-postgres): indexes not creating for relationships, arrays, hasmany and blocks (#4976) 2024-02-02 11:16:21 -05:00
Jarrod Flesch
afa2b942e0 fix: ensures docPermissions fallback to collection permissions on create (#4969) 2024-02-01 16:54:52 -05:00
Dan Ribbens
20ddd0de5b chore: add indexes to preferences for performance (#4965) 2024-02-01 15:31:31 -05:00
Dan Ribbens
64f705c3c9 fix(db-postgres): indexes not created for non unique field names (#4967) 2024-02-01 15:21:15 -05:00
Daniel Shamburger
b30ea8aa6b docs: typo (#4948) 2024-01-31 15:40:55 -05:00
Mark Paolo Libunao
471d2113a7 feat: re-use existing logger instance passed to payload.init (#3124) 2024-01-31 15:40:14 -05:00
Alessio Gravili
8725d41164 feat: add more options to addFieldStatePromise so that it can be used for field flattening (#4799) 2024-01-30 23:02:58 +01:00
Dan Ribbens
0bd81aa25a fix(templates-ecommerce): hook errors for non-string ids (#4946) 2024-01-30 13:28:14 -05:00
Dan Ribbens
8c09ca9be5 examples: fix multi-tenant hooks to use transactions (#4955) 2024-01-30 13:26:13 -05:00
Alessio Gravili
90d7ee3e65 feat(richtext-lexical): Blocks: generate type definitions for blocks fields (#4529) 2024-01-30 16:51:18 +01:00
Kendell Joseph
58bbd8c00f chore(examples/hierarchy): adds hierarchy example (#4923) 2024-01-26 16:17:11 -05:00
Elliot DeNolf
003ad065c3 chore(release): plugin-cloud-storage/1.1.2 [skip ci] 2024-01-26 13:58:13 -05:00
Elliot DeNolf
70715926a8 chore(release): richtext-slate/1.4.0 [skip ci] 2024-01-26 13:57:45 -05:00
Elliot DeNolf
b3a6bfacf2 chore(release): db-postgres/0.5.0 [skip ci] 2024-01-26 13:57:34 -05:00
Elliot DeNolf
e1d9accb27 chore(release): db-mongodb/1.4.0 [skip ci] 2024-01-26 13:57:23 -05:00
Elliot DeNolf
f2f55a84cc chore(release): payload/2.9.0 [skip ci] 2024-01-26 13:55:20 -05:00
Dan Ribbens
eba53ba60a feat: forceAcceptWarning migration arg added to accept prompts (#4874)
* chore: gitignore test migrations

* feat: `forceAcceptWarning` migration args added to accept prompts

* chore: migrationDir env variable fallback

* chore: migrationDir testSuiteDir fallback

* chore: migrationDir testSuiteDir fallback fix

* chore: skip migrate down test
2024-01-26 13:48:53 -05:00
Dan Ribbens
f73d503fec fix(plugin-cloud-storage): slow get file performance large collections (#4927) 2024-01-26 13:43:55 -05:00
Dan Ribbens
6930c4e9f2 fix: upload input drawer does not show draft versions (#4903)
* chore: add field classname to upload field

* fix: upload input drawer does not show draft versions
2024-01-26 13:42:32 -05:00
Dan Ribbens
3eb681e847 fix: afterLogin hook write conflicts (#4904)
* fix: afterLogin hook conflict

* test: afterLogin hook returns for assertion

* chore: commit increment login attempt
2024-01-26 13:39:45 -05:00
Jarrod Flesch
cb4638cfa1 chore: make default views callable (#4928) 2024-01-26 13:38:36 -05:00
Dan Ribbens
b40e9f85a2 chore: use transactions in tests running mongoDB memory server (#4750)
* chore: use transactions in tests running mongoDB memory server

* chore: relationship test async setup changes

* chore: async test fix

* chore: flaky e2e localization test
2024-01-23 19:18:55 -05:00
Dan Ribbens
e5a7907a72 fix: remove No Options dropdown from hasMany fields (#4899) 2024-01-23 10:00:16 -05:00
Jarrod Flesch
3f25d1ca84 chore: re-orders request language detection (#4890) 2024-01-22 11:53:01 -05:00
Timothy Choi
d5720bea7b chore: add fieldIsGroupType type guard helper (#4872) 2024-01-19 14:19:35 -05:00
Jesse Sivonen
8ce15c8b07 fix(db-postgres): query unset relation (#4862) 2024-01-19 13:35:58 -05:00
Timothy Choi
9f5efef78f chore: lint #4766 (#4801)
* fix: import location for config test

* fix: linting fix
2024-01-18 09:25:52 -05:00
Dan Ribbens
dfba5222f3 fix(db-postgres): migrate down error (#4861) 2024-01-17 13:55:57 -05:00
Dan Ribbens
b99d24fcfa fix: migrate down missing filter for latest batch (#4860) 2024-01-17 13:54:30 -05:00
Elliot DeNolf
836ed77568 chore: update changelog [skip ci] 2024-01-16 16:39:42 -05:00
Elliot DeNolf
1c5d5b07c8 chore(release): plugin-seo/2.2.0 [skip ci] 2024-01-16 16:33:53 -05:00
Elliot DeNolf
da5f1f2240 chore(release): plugin-form-builder/1.2.0 [skip ci] 2024-01-16 16:33:44 -05:00
Elliot DeNolf
c84c58c7b4 chore(release): db-postgres/0.4.0 [skip ci] 2024-01-16 16:33:21 -05:00
Elliot DeNolf
1c1b8f3cec chore(release): db-mongodb/1.3.2 [skip ci] 2024-01-16 16:32:52 -05:00
Elliot DeNolf
3f69f83180 chore(release): payload/2.8.2 [skip ci] 2024-01-16 16:31:39 -05:00
beezee
371353f153 feat(db-postgres): support drizzle logging config (#4809) 2024-01-16 15:45:17 -05:00
Dan Ribbens
a92c6334b6 chore(db-postgres): update drizzle-kit to 0.20.5-608ae62 and drizzle-orm to latest (#4772) 2024-01-16 13:35:07 -05:00
Paul
eb9e771a9c fix(db-postgres): Remove duplicate keys from response (#4747)
* Remove duplicate keys from response

* Update to delete duplicates at a higher level and remove '_order' from array rows too
2024-01-16 13:22:08 -05:00
Patrik
ee5390aaca fix: removes max-width from field-types class & correctly sets it on uploads (#4829) 2024-01-16 13:12:58 -05:00
Paul
a861311c5a fix(db-mongodb): mongodb versions creating duplicates (#4825)
* Fixes the issue with mongodb versions

* Update other methods to use options too
2024-01-16 12:20:45 -05:00
James Mikrut
74c3fe1bb2 Merge pull request #4806 from payloadcms/fix/#4775-postgres-block-validation-arrays
fix(db-postgres): validateExistingBlockIsIdentical with arrays
2024-01-15 15:04:47 -05:00
James Mikrut
a2be50279e Merge pull request #4804 from payloadcms/fix/#4802-transaction-options-false
fix(db-mongodb): transactionOptions=false typeErrors
2024-01-15 15:04:01 -05:00
James Mikrut
403eb06acf Merge pull request #4723 from payloadcms/fix/4548-fix-missing-spread
fix(plugin-seo):Fix missing spread operator in URL generator function
2024-01-15 15:02:45 -05:00
James Mikrut
f5c2cd74cc Merge pull request #4695 from payloadcms/feat/4539-seo-plugin-allow-field-and-interface-overrides
feat(plugin-seo): Add support for interfaceName and fieldOverrides
2024-01-15 15:02:14 -05:00
Paul Popus
a6a1963ec6 Merge branch 'main' into feat/4539-seo-plugin-allow-field-and-interface-overrides 2024-01-15 16:29:49 -03:00
Dan Ribbens
0647c870f1 fix(db-postgres): validateExistingBlockIsIdentical with other tables 2024-01-13 22:46:05 -05:00
Dan Ribbens
3b88adc7d0 fix(db-postgres): validateExistingBlockIsIdentical with arrays 2024-01-13 22:40:30 -05:00
Dan Ribbens
82383a5b5f fix(db-mongodb): transactionOptions=false typeErrors 2024-01-13 14:59:16 -05:00
James Mikrut
f9dda628b2 Merge pull request #4730 from payloadcms/feat/4471-add-validation-for-form-submission
feat(plugin-form-builder):Add validation for form ID when creating a form submissions
2024-01-12 15:39:35 -05:00
Elliot DeNolf
93eb0e4a31 chore: update bug report template to renamed possible-bug label 2024-01-12 14:19:43 -05:00
Elliot DeNolf
2e362f44f4 chore(release): payload/2.8.1 [skip ci] 2024-01-12 12:44:15 -05:00
Jarrod Flesch
775502b161 fix: corrects config usage in build bin script (#4796) 2024-01-12 12:40:08 -05:00
Elliot DeNolf
84d75ce6ca chore(release): plugin-form-builder/1.1.2 [skip ci] 2024-01-12 10:47:08 -05:00
Elliot DeNolf
175cf229c0 chore(release): richtext-lexical/0.5.2 [skip ci] 2024-01-12 10:41:55 -05:00
Elliot DeNolf
bb40bd3efb chore(release): db-postgres/0.3.1 [skip ci] 2024-01-12 10:41:46 -05:00
Elliot DeNolf
3d74c133aa chore(release): db-mongodb/1.3.1 [skip ci] 2024-01-12 10:41:37 -05:00
Elliot DeNolf
0f6b6ca970 chore(release): bundler-webpack/1.0.6 [skip ci] 2024-01-12 10:41:29 -05:00
Elliot DeNolf
8e1692ef10 chore(release): bundler-vite/0.1.6 [skip ci] 2024-01-12 10:41:21 -05:00
Elliot DeNolf
1d1ee913fc chore(release): plugin-seo/2.1.0 [skip ci] 2024-01-12 10:40:45 -05:00
Elliot DeNolf
beca43341f chore(release): payload/2.8.0 [skip ci] 2024-01-12 10:39:41 -05:00
Patrik
84818469ea fix(plugin-form-builder): replaces curly brackets with lexical editor (#4753)
* chore: scaffolds fix for replacing curly brackets in email with lexical editor

* fix: submissionData not passed to nested fields

* chore: adds int test for lexical serializer

---------

Co-authored-by: Alessio Gravili <alessio@bonfireleads.com>
2024-01-12 10:37:01 -05:00
Patrik
0a259d27b5 fix: passes draft=true in fetch for relationships (#4784)
* fix: passes draft=true to fetch for relationships

* chore: removes unnecessary delay on field click in e2e test
2024-01-12 10:36:45 -05:00
Nico Bohne
e2e56a4d58 fix: text hasMany validation (#4789) 2024-01-11 23:16:52 -05:00
Patrik
d0f7677d5f fix: prioritizes value key when filtering / querying for relationships (#4727)
* fix: object equality query by prioritizing value key in relationship queries

* chore: adds e2e & int test

* chore: updates test for REST querying on poly relationships
2024-01-11 15:56:07 -05:00
Yuri Koshiishi
35956eb837 chore: use consistent param name in useField's setValue (#4710) 2024-01-11 14:25:48 -05:00
Timothy Choi
d92af295eb feat: allow custom config properties in blocks (#4766) 2024-01-11 13:57:32 -05:00
Marvin
493fde5ccc feat(logger): show local time (#4663) 2024-01-11 11:51:11 -05:00
David Oliver
c6bd20ef33 docs: improve email docs SMTP info (#4698) 2024-01-11 11:45:25 -05:00
Paul
6d5ac1de1e fix: allow a custom ID field to be nested inside unnamed tabs and rows (#4701)
* Adds a check for the first tab and e2e test for custom ID

* Add support for ids in any order inside an unnamed tab

* Update tests for rows

* Minor fixes and remove dead commented code
2024-01-11 10:17:24 -05:00
Dan Ribbens
fa3b3dd62d fix: migration regression (#4777) 2024-01-10 22:40:00 -05:00
Jarrod Flesch
1115387744 fix: build payload without initializing (#4028) 2024-01-10 20:40:46 -05:00
Elliot DeNolf
53e8690feb Merge pull request #4773 from payloadcms/fix/limit-zero
fix: limit=0 returns all docs
2024-01-10 17:00:07 -05:00
Maxime Marty-Dessus
4319fe1c6e feat(plugin-seo): add fr translations (#4774) 2024-01-10 16:48:07 -05:00
Elliot DeNolf
2fee0c0d44 docs: update pagination 2024-01-10 16:45:42 -05:00
Elliot DeNolf
7923edd7bc test: fix limit=0 test 2024-01-10 16:45:34 -05:00
Elliot DeNolf
5702b83e82 fix(db-postgres): totalPages value when limit=0 2024-01-10 16:45:07 -05:00
Elliot DeNolf
63e5c43fe6 fix(db-mongodb): limit=0 returns unpaginated 2024-01-10 16:44:57 -05:00
kiwagu
04f2888135 chore(examples/form-builder): removes legacyBehavior flags from next/link (#4764) 2024-01-10 16:26:50 -05:00
Elliot DeNolf
0f69b9c2f8 chore(templates): remove jackspeak resolutions 2024-01-10 13:06:50 -05:00
Elliot DeNolf
f1bb2f8151 feat(templates): bump plugin-cloud (#4770) 2024-01-10 13:03:50 -05:00
Elliot DeNolf
ea528b8c10 chore(release): eslint-config-payload/1.1.1 [skip ci] 2024-01-10 12:49:11 -05:00
Elliot DeNolf
0053e40404 chore(eslint): object-shorthand warn 2024-01-10 12:45:51 -05:00
Elliot DeNolf
605c0be43c chore(release): plugin-seo/2.0.0 [skip ci] 2024-01-10 12:41:02 -05:00
Elliot DeNolf
3152b4c4c5 chore: revert plugin-seo version bump 2024-01-10 12:40:37 -05:00
Elliot DeNolf
a64b80babc chore(release): plugin-cloud/3.0.0 [skip ci] 2024-01-10 12:34:02 -05:00
Elliot DeNolf
5cfde542b1 feat(plugin-cloud): use resend smtp instead of custom transport (#4746) 2024-01-10 12:22:02 -05:00
Patrik
772020963e fix(examples): bumps next to v13.5.1 (#4763) 2024-01-10 12:17:51 -05:00
Alessio Gravili
5e083689d0 feat(plugin-seo)!: remove support for payload <2.7.0 (#4765) 2024-01-10 17:29:29 +01:00
Taís Massaro
911764a490 chore: export useTheme and add documentation (#4718)
* chore(react-hooks): export useTheme hook

* docs(react-hooks): add useTheme documentation
2024-01-10 10:39:00 -05:00
Alessio Gravili
e3b81d913d chore(plugin-seo): remove test script from package.json (#4762) 2024-01-10 14:38:13 +01:00
Alessio Gravili
41b3b17911 chore(plugin-seo): add to CI, minor package.json improvements (#4761)
* chore: add plugin-seo to CI

* chore(plugin-seo): minor package.json improvements
2024-01-10 14:27:30 +01:00
Yunsup Sim
e9860b36f3 chore(plugin-seo): build command fix (#4756)
* chore(plugin-seo): build command fix

* chore: fix build script

---------

Co-authored-by: Alessio Gravili <alessio@bonfireleads.com>
2024-01-10 14:20:50 +01:00
Alessio Gravili
14b39fbc85 chore: eslint improvements (#4739)
* chore: add @typescript-eslint/prefer-ts-expect-error rule

* chore: fix @typescript-eslint/prefer-ts-expect-error rule

* chore: disable useless class-methods-use-this eslint rule

* chore: only warn for no-unused-vars rule

* remove unused ts-expect-error

* undo admin changes
2024-01-10 11:31:00 +01:00
Elliot DeNolf
d08e85d08c chore(release): plugin-nested-docs/1.0.11 [skip ci] 2024-01-09 16:32:02 -05:00
Elliot DeNolf
abcbf9974d chore(release): plugin-form-builder/1.1.1 [skip ci] 2024-01-09 16:31:52 -05:00
Elliot DeNolf
d01437d212 chore(release): plugin-seo/1.1.0 [skip ci] 2024-01-09 16:31:01 -05:00
Elliot DeNolf
06729a0a73 chore(release): db-postgres/0.3.0 [skip ci] 2024-01-09 16:30:49 -05:00
Elliot DeNolf
2bd7822a16 chore(release): db-mongodb/1.3.0 [skip ci] 2024-01-09 16:30:37 -05:00
Elliot DeNolf
bc7daf6b49 chore(release): payload/2.7.0 [skip ci] 2024-01-09 16:28:34 -05:00
James Mikrut
feab679ef7 Merge pull request #4615 from payloadcms/fix/relationship-field-number-ids-untitled
fix: relations with number based ids (postgres) show untitled ID: x
2024-01-09 15:30:41 -05:00
James Mikrut
be39ed4317 Merge pull request #4633 from payloadcms/fix/#3839-postgres-exist-json
fix(db-postgres): incorrect results querying json field using exists
2024-01-09 15:27:22 -05:00
James Mikrut
570e192eb4 Merge pull request #4741 from payloadcms/fix/#4591-migrate-down-batches
fix(db-postgres): migrate down not limited to latest batch
2024-01-09 13:50:45 -05:00
James Mikrut
22f4967dd4 Merge pull request #4726 from payloadcms/feat/migration-transactions
feat: improve transaction support by passing req to migrations
2024-01-09 13:50:00 -05:00
James Mikrut
4873c36129 Merge pull request #4722 from payloadcms/fix/#4719-migration-transaction-options
fix(db-mongodb): migration errors with transactionOptions false
2024-01-09 13:46:06 -05:00
James Mikrut
f0ec21cdda Merge pull request #4624 from payloadcms/fix/#3692-plugin-nested-docs-overrides
fix(plugin-nested-docs): custom overrides of breadcrumb and parent fields
2024-01-09 13:45:46 -05:00
dependabot[bot]
da737bdf8e chore(deps): bump follow-redirects in /examples/testing (#4735)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-09 13:18:29 -05:00
dependabot[bot]
40508880c1 chore(deps): bump follow-redirects in /templates/blank (#4736)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-09 13:18:18 -05:00
dependabot[bot]
8f420d841a chore(deps): bump follow-redirects in /templates/website (#4737)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-09 13:18:08 -05:00
dependabot[bot]
9022e27308 chore(deps): bump follow-redirects in /templates/ecommerce (#4734)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-09 13:17:59 -05:00
Patrik
acf2e41312 docs: updates verify to verifyEmail in local api (#4728) 2024-01-09 13:15:31 -05:00
Dan Ribbens
6acfae8ee7 fix(db-postgres): migrate down only runs latest batch size 2024-01-09 10:21:45 -05:00
Alessio Gravili
20bdd91da4 chore: upgrade @types/nodemailer from v6.4.8 to v6.4.14 (#4733) 2024-01-09 14:19:45 +01:00
Alessio Gravili
50502834c9 chore(richtext-lexical): upgrade lexical from v0.12.5 to v0.12.6 (#4732)
* chore(richtext-lexical): upgrade all lexical packages from 0.12.5 to 0.12.6

* fix(richtext-lexical): fix TypeScript errors

* fix indenting
2024-01-09 09:35:18 +01:00
Paul Popus
2b731c1088 feat(plugin-form-builder):Add validation for form ID when creating a submission 2024-01-08 20:35:52 -03:00
Dan Ribbens
983733ad74 merge main 2024-01-08 17:12:02 -05:00
Dan Ribbens
555d02769a feat(db-postgres): improve transaction support by passing req to migrations 2024-01-08 15:50:22 -05:00
Dan Ribbens
682eca2186 feat(db-mongodb): improve transaction support by passing req to migrations 2024-01-08 15:50:09 -05:00
Paul Popus
6affa1c304 Removed fallback for interfaceName 2024-01-08 15:27:17 -03:00
Dan Ribbens
1d14d9f8b8 feat: improve transaction support by passing req to migrations 2024-01-08 12:34:55 -05:00
Dan Ribbens
0abaddc2ef chore: remove payload migration endpoints 2024-01-08 12:24:53 -05:00
Paul Popus
57dc93da5d Fix missing spread operator in generator function 2024-01-08 14:07:35 -03:00
Dan Ribbens
21b9453cf4 fix(db-mongodb): migration error calling beginTransaction with transactionOptions false 2024-01-08 12:03:45 -05:00
Alessio Gravili
136993ec2b chore: undo adding DocumentInfo state to ActionsProvider (#4707) 2024-01-05 22:58:16 +01:00
Dan Ribbens
63bc4cabe1 fix(db-mongodb): querying plan for collections ignoring indexes (#4655)
* fix(db-mongodb): querying plan for collections ignoring indexes

* chore(db-mongodb): improve index hint comment
2024-01-05 16:21:19 -05:00
Alessio Gravili
6a8a6e4ef4 feat: provide document info to ActionsProvider (#4696) 2024-01-05 21:12:21 +01:00
Jessica Chowdhury
9828772890 fix: prevents row overflow (#4704) 2024-01-05 15:04:30 -05:00
Jessica Chowdhury
6116573164 docs: corrects type in useField example (#4705) 2024-01-05 15:03:38 -05:00
Dan Ribbens
cab6babd60 fix(db-postgres): validation prevents group fields in blocks (#4699)
* fix(db-postgres): validation prevents using group fields within blocks

* fix(db-postgres): validation of non-matching blocks in reverse order
2024-01-05 15:03:08 -05:00
Paul
55399424a1 fix(plugin-nested-docs): children wrongly publishing draft data (#4692)
* fix(plugin-nested-docs): handles child parent doc publishing

* Add tests

* Fix error failing on save hook

---------

Co-authored-by: Jessica Chowdhury <jessica@trbl.design>
2024-01-05 15:02:15 -05:00
Paul Popus
28d3f73c2a Fix integration test 2024-01-05 15:23:57 -03:00
Jessica Chowdhury
28a30120dd fix(plugin-form-builder): slate serializer should replace curly braces in links (#4703) 2024-01-05 13:01:03 -05:00
Elliot DeNolf
40a0921597 docs: update 'accessing files outside of payload cloud' 2024-01-05 11:53:51 -05:00
Paul Popus
7eae86bcb3 Add changes from previous branch and update docs 2024-01-05 12:45:03 -03:00
Paul
0b80e4a403 chore: bump the mongodb-memory-server dependency to 9.x (#4693) 2024-01-05 09:35:35 -05:00
Seied Ali Mirkarimi
b378532ddf chore: rtl locale selector and sidebar button (#4684)
* chore: rtl locale popup selector and sidebar button

* chore(plugin-seo): add persian translation
2024-01-04 21:45:39 -05:00
Patrik
d419275fb5 fix: adds objectID validation to isValidID if of type text (#4689)
* fix: adds updated object-id validation to isValidID

* chore: adds check to see if value is of type string or object

* chore: needs to return false if value not of type object or string
2024-01-04 15:08:55 -05:00
Jessica Chowdhury
0fb3a9ca89 fix: allow json field to be saved empty and reflect value changes (#4687)
* fix: allow json field to be saved empty and reflect value changes

* fix: reverts change to json field validation

* chore: wraps more JSON field logic with a try/catch
2024-01-04 14:47:10 -05:00
Gokulsck
f43cf185d4 feat: hasMany property for text fields (#4605)
* fix for supporting hasMany property in text field

* Updated docs

* handle text case types for schema and graphql schema

* fix unit test for required failing

* add unit test for has many text field

* add end to end test for has many on text field creation

* support has many feature for text field on postgres

---------

Co-authored-by: Chris Heinz <chrisi.heinz@web.de>
2024-01-04 14:45:00 -05:00
Dan Ribbens
5d15955f83 fix: custom ids in versions (#4680)
* chore: scaffolds out fix for postgres issues with custom ids in versions

* fix(db-postgres): queryDrafts returns undefined doc.id

* chore(db-postgres): fix build

* fix: removes extra custom id field from  versions buildCollectionFields

* chore: comments test/versions seeding back in

* fix buildCollectionFields version group fields

* fix: id field can be edited after saving a document with custom ids

* chore: updates versions custom ID test

---------

Co-authored-by: PatrikKozak <patrik@payloadcms.com>
2024-01-04 13:05:10 -05:00
Elliot DeNolf
2d35e06667 ci(templates): generate types in ci (#4685) 2024-01-04 10:04:44 -05:00
Elliot DeNolf
d2de6db449 chore(release): eslint-config-payload/1.1.0 2024-01-04 09:56:42 -05:00
Alessio Gravili
a3e78161b5 fix: non-boolean condition result causes infinite looping (#4579) 2024-01-04 09:51:08 -05:00
Hulpoi George-Valentin
d543665995 fix: unlock user condition always passes due to seconds conversion (#4610)
* fix: unlock condition is always true

* test: extra call for locking user, therefor won't be a condition issue
2024-01-04 09:43:10 -05:00
Alessio Gravili
db7dddf1c5 chore: commit intellij run configurations (#4653)
* chore: update .gitignore

* chore: update .gitignore

* chore: commit IntelliJ run configurations
2024-01-04 09:35:01 -05:00
Paul
3027a03ad1 feat(plugin-seo): add i18n (#4665)
* Add i18n to plugin SEO

* Add new translations and e2e tests for the SEO plugin

* Update e2e tests to utilise a shared page ID from a create function
2024-01-04 09:18:09 -05:00
Paul
85e38b7cfd fix: sidebar fields not disabled by access permissions (#4682)
* Pass operation to sidebar fields too

* Add a test for sidebar field update permission
2024-01-03 20:04:40 -05:00
Elliot DeNolf
9090540ece chore(release): richtext-lexical/0.5.1 [skip ci] 2024-01-03 15:58:05 -05:00
Elliot DeNolf
46ef284f6b chore(release): db-postgres/0.2.3 [skip ci] 2024-01-03 15:57:54 -05:00
Elliot DeNolf
0727dcd963 chore(release): db-mongodb/1.2.0 [skip ci] 2024-01-03 15:57:22 -05:00
Elliot DeNolf
52f8d4f9f0 chore(release): payload/2.6.0 [skip ci] 2024-01-03 15:55:34 -05:00
Jessica Chowdhury
f1fa374ed1 fix: tab field error when using the same interface name (#4657)
* fix: tab field error when using the same interface name

* fix: removes unused tab types
2024-01-03 15:50:07 -05:00
Alessio Gravili
6b691eee43 chore(eslint-config-payload): improve perfectionist object sort order (#4678) 2024-01-03 21:45:34 +01:00
Paul
be3beabb9b fix: navigation locks when modal is closed with esc (#4664) 2024-01-03 12:06:09 -05:00
Seied Ali Mirkarimi
1fa00cc25c chore: rtl header locale selector (#4670) 2024-01-03 12:04:39 -05:00
James
f70943524b fix(templates): #4662, templates not building after having types generated 2024-01-02 19:49:09 -05:00
Jessica Chowdhury
a67080a291 Merge pull request #4574 from jschuur/patch-1
fix: adjusts json field joi schema to allow editorOptions
2024-01-02 21:58:34 +00:00
Jarrod Flesch
69a99445c9 fix: detect language from request headers accept-language (#4656) 2024-01-02 15:17:00 -05:00
Alessio Gravili
00d8480062 fix: "The punycode module is deprecated" warning by updating nodemailer 2024-01-02 18:26:52 +01:00
Dan Ribbens
7424ba9090 test: e2e await fix (#4646) 2024-01-01 14:09:48 -05:00
Dan Ribbens
ec4d2f97cb fix(db-postgres): query on json properties 2023-12-29 16:42:32 -05:00
Dan Ribbens
9d9ac0ec28 fix(db-postgres): incorrect results querying json field using exists operator 2023-12-29 11:35:12 -05:00
Dan Ribbens
635e7c26e8 fix(plugin-nested-docs): custom parent field slug 2023-12-28 14:30:36 -05:00
Dan Ribbens
c4a4678afb fix(plugin-nested-docs): parent filterOptions errors when specifying breadcrumbsFieldSlug 2023-12-28 14:01:31 -05:00
Dan Ribbens
a5a91c08a9 fix(plugin-nested-docs): breadcrumbsFieldSlug used in resaveSelfAfterCreate hook 2023-12-28 13:05:53 -05:00
Dan Ribbens
7db58b482b fix: custom overrides of breadcrumb and parent fields 2023-12-28 12:56:30 -05:00
Dan Ribbens
1b914083c8 fix: relations with number based ids (postgres) show untitled ID: x 2023-12-27 15:30:30 -05:00
Anthony Bouch
657d14c07b chore(plugin-search): adjusts code comment when attaching hooks (#4595) 2023-12-23 19:24:33 -05:00
yuc
fbf8ab72a4 docs: fix typo in Select Field example (#4593) 2023-12-23 19:15:44 -05:00
Zakher Masri
997f158149 chore(plugin-stripe): fixes broken link in README (#4602) 2023-12-23 19:08:25 -05:00
James Mikrut
c3be5d1d5e Merge pull request #4560 from payloadcms/fix/#4484-graphql-multiple-locales
fix: graphql cannot query multiple locales
2023-12-21 15:29:14 -05:00
James Mikrut
250bcd8189 Merge pull request #4526 from payloadcms/feat/locale-specific-fallbacks
feat: extend locales to have fallbackLocales
2023-12-21 15:25:55 -05:00
Jesse Sivonen
a71d37b398 fix(db-postgres): Wait for transaction to complete on commit (#4582)
* fix(db-postgres): Wait for transaction to complete on commit
* fix session types
2023-12-21 11:03:27 -05:00
Patrik
5c5523195c fix: resets actions array when navigating out of view with actions (#4585) 2023-12-21 10:48:04 -05:00
Joost Schuur
bff4cf518f fix: adjusts json field joi schema to allow editorOptions
Previous fix was not applied to json fields: https://github.com/payloadcms/payload/pull/2731/files
2023-12-21 00:47:14 +08:00
Alessio Gravili
8015e999cd fix(richtext-lexical): z-index issues (#4570) 2023-12-20 15:10:18 +01:00
Sajarin M
0c905f0da7 docs: typo in transactions page (#4565) 2023-12-20 01:31:50 -05:00
Dan Ribbens
e691a90a4c chore: fix failed test 2023-12-19 15:53:20 -05:00
James Mikrut
0b2da4fba7 Merge pull request #4467 from payloadcms/feat/mongodb-transaction-options
feat(db-mongodb): add transactionOptions
2023-12-19 15:30:23 -05:00
Elliot DeNolf
1c6d6788a3 chore: update changelog [skip ci] 2023-12-19 15:03:44 -05:00
Elliot DeNolf
ecc7978184 chore(release): plugin-nested-docs/1.0.10 [skip ci] 2023-12-19 14:49:38 -05:00
Elliot DeNolf
1b9ee64a67 chore(release): live-preview/0.2.2 [skip ci] 2023-12-19 14:48:20 -05:00
Elliot DeNolf
22b02226c3 chore(release): db-postgres/0.2.2 [skip ci] 2023-12-19 14:48:08 -05:00
Elliot DeNolf
e4102b88d8 chore(release): db-mongodb/1.1.1 [skip ci] 2023-12-19 14:47:41 -05:00
Elliot DeNolf
a099f55a69 chore(release): plugin-form-builder/1.1.0 [skip ci] 2023-12-19 14:46:49 -05:00
Elliot DeNolf
1f1445c798 chore(release): richtext-lexical/0.5.0 [skip ci] 2023-12-19 14:45:27 -05:00
Elliot DeNolf
741a5e3650 chore(release): payload/2.5.0 [skip ci] 2023-12-19 14:41:55 -05:00
Dan Ribbens
365047a3fb Merge branch 'feat/locale-specific-fallbacks' into fix/#4484-graphql-multiple-locales 2023-12-19 14:22:09 -05:00
Dan Ribbens
42c06acd18 docs: transaction options 2023-12-19 14:19:28 -05:00
Dan Ribbens
f2c8ac4a9a feat(db-mongodb): add transactionOptions 2023-12-19 14:19:12 -05:00
Dan Ribbens
05e8914db7 fix(db-mongodb): documentDB unique constraint throws incorrect error (#4513) 2023-12-19 14:14:51 -05:00
Dan Ribbens
35191bdd66 docs: improve docs for locales 2023-12-19 14:11:35 -05:00
Dan Ribbens
98890eee1f fix: graphql multiple locales 2023-12-19 14:00:06 -05:00
Ritsu
ef43629502 fix(db-postgres) incorrect currentTableName in find for blocks (#4524) 2023-12-19 10:30:13 -05:00
Dan Ribbens
c703497924 test: improve e2e locale change selector 2023-12-19 09:57:46 -05:00
Dan Ribbens
5caad706bb chore: consistent locale and fallback locale for globals 2023-12-19 09:40:26 -05:00
Dan Ribbens
aa048d5409 fix: req.locale and req.fallbackLocale get reassigned in local operations 2023-12-18 16:50:17 -05:00
Dan Ribbens
aafd538cf8 fix failing e2e test 2023-12-16 00:49:04 -05:00
Dan Ribbens
1b42bd207d fix failing tests 2023-12-16 00:18:59 -05:00
Dan Ribbens
9fac2ef24e feat: extend locales to have fallbackLocales 2023-12-15 23:52:12 -05:00
7807 changed files with 367032 additions and 561290 deletions

38
.eslintrc.js Normal file
View File

@@ -0,0 +1,38 @@
module.exports = {
extends: ['@payloadcms'],
overrides: [
{
extends: ['plugin:@typescript-eslint/disable-type-checked'],
files: ['*.js', '*.cjs', '*.json', '*.md', '*.yml', '*.yaml'],
},
{
files: ['packages/eslint-config-payload/**'],
rules: {
'perfectionist/sort-objects': 'off',
},
},
{
files: ['package.json', 'tsconfig.json'],
rules: {
'perfectionist/sort-array-includes': 'off',
'perfectionist/sort-astro-attributes': 'off',
'perfectionist/sort-classes': 'off',
'perfectionist/sort-enums': 'off',
'perfectionist/sort-exports': 'off',
'perfectionist/sort-imports': 'off',
'perfectionist/sort-interfaces': 'off',
'perfectionist/sort-jsx-props': 'off',
'perfectionist/sort-keys': 'off',
'perfectionist/sort-maps': 'off',
'perfectionist/sort-named-exports': 'off',
'perfectionist/sort-named-imports': 'off',
'perfectionist/sort-object-types': 'off',
'perfectionist/sort-objects': 'off',
'perfectionist/sort-svelte-attributes': 'off',
'perfectionist/sort-union-types': 'off',
'perfectionist/sort-vue-attributes': 'off',
},
},
],
root: true,
}

View File

@@ -16,18 +16,3 @@ fb7d1be2f3325d076b7c967b1730afcef37922c2
# lint and format create-payload-app
5fd3d430001efe86515262ded5e26f00c1451181
# 3.0 prettier & lint everywhere
6789e61488a1d3de56f472ac3214faf344030005
# 3.0 prettier & lint everywhere again
83fd4c66222d7846eeb5cc332dfa99bf1e830831
# Upgrade to typescript-eslint v8, then prettier & lint everywhere
86fdad0bb8ab27810599c8a32f3d8cba1341e1df
# Prettier and lint remaining db packages
7fd736ea5b2e9fc4ef936e9dc9e5e3d722f6d8bf
# Bump all eslint deps, lint and format
03291472d6e427ff94e61fca0616cca7796a3a95

27
.github/CODEOWNERS vendored
View File

@@ -1,23 +1,26 @@
# Order matters. The last matching pattern takes precedence.
# Approvals are not required currently but may be enabled in the future.
### Package Exports ###
/**/exports/ @denolfe @jmikrut @DanRibbens
### Core ###
### Packages ###
/packages/plugin-cloud*/src/ @denolfe
/packages/email-*/src/ @denolfe
/packages/storage-*/src/ @denolfe
/packages/create-payload-app/src/ @denolfe
/packages/eslint-*/ @denolfe @AlessioGr
### Adapters ###
/packages/richtext-*/ @AlessioGr
### Plugins ###
/packages/plugin-cloud*/ @denolfe
### Templates ###
/templates/_data/ @denolfe
/templates/_template/ @denolfe
/templates/ @jacobsfletch @denolfe
### Misc ###
/packages/create-payload-app/ @denolfe
/packages/eslint-*/ @denolfe
### Build Files ###
/**/package.json @denolfe
/tsconfig.json @denolfe
/**/tsconfig*.json @denolfe
/jest.config.js @denolfe
/**/jest.config.js @denolfe
@@ -25,5 +28,5 @@
/package.json @denolfe
/scripts/ @denolfe
/.husky/ @denolfe
/.vscode/ @denolfe @AlessioGr
/.vscode/ @denolfe
/.github/ @denolfe

47
.github/ISSUE_TEMPLATE/1.bug_report.yml vendored Normal file
View File

@@ -0,0 +1,47 @@
name: Bug Report
description: Create a bug report for Payload
labels: ['[possible-bug]']
body:
- type: markdown
attributes:
value: |
*Note:* Feature requests should be opened as [discussions](https://github.com/payloadcms/payload/discussions/new?category=feature-requests-ideas).
- type: input
id: reproduction-link
attributes:
label: Link to reproduction
description: Want us to look into your issue faster? Follow the [reproduction-guide](https://github.com/payloadcms/payload/blob/main/.github/reproduction-guide.md) for more information.
validations:
required: false
- type: textarea
attributes:
label: Describe the Bug
validations:
required: true
- type: textarea
attributes:
label: To Reproduce
description: Steps to reproduce the behavior, please provide a clear description of how to reproduce the issue, based on the linked minimal reproduction. Screenshots can be provided in the issue body below. If using code blocks, make sure that [syntax highlighting is correct](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting) and double check that the rendered preview is not broken.
validations:
required: true
- type: input
id: version
attributes:
label: Payload Version
description: What version of Payload are you running?
validations:
required: true
- type: input
id: adapters-plugins
attributes:
label: Adapters and Plugins
description: What adapters and plugins are you using? ie. db-mongodb, db-postgres, bundler-webpack, etc.
- type: markdown
attributes:
value: Before submitting the issue, go through the steps you've written down to make sure the steps provided are detailed and clear.
- type: markdown
attributes:
value: Contributors should be able to follow the steps provided in order to reproduce the bug.
- type: markdown
attributes:
value: These steps are used to add integration tests to ensure the same issue does not happen again. Thanks in advance!

View File

@@ -1,77 +0,0 @@
name: Functionality Bug
description: '[REPRODUCTION REQUIRED] - Create a bug report'
labels: ['status: needs-triage', 'validate-reproduction']
body:
- type: textarea
attributes:
label: Describe the Bug
validations:
required: true
- type: input
id: reproduction-link
attributes:
label: Link to the code that reproduces this issue
description: >-
_REQUIRED_: Please provide a link to your reproduction. Note, if the URL is invalid (404 or a private repository), we may close the issue.
Either use `pnpx create-payload-app@latest -t blank` then push to a repo or follow the [reproduction-guide](https://github.com/payloadcms/payload/blob/main/.github/reproduction-guide.md) for more information.
validations:
required: true
- type: textarea
attributes:
label: Reproduction Steps
description: Steps to reproduce the behavior, please provide a clear description of how to reproduce the issue, based on the linked minimal reproduction. Screenshots can be provided in the issue body below. If using code blocks, make sure that [syntax highlighting is correct](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting) and double check that the rendered preview is not broken.
validations:
required: true
- type: dropdown
attributes:
label: Which area(s) are affected? (Select all that apply)
multiple: true
options:
- 'Not sure'
- 'area: core'
- 'area: docs'
- 'area: templates'
- 'area: ui'
- 'db-mongodb'
- 'db-postgres'
- 'db-sqlite'
- 'db-vercel-postgres'
- 'email-nodemailer'
- 'plugin: cloud'
- 'plugin: cloud-storage'
- 'plugin: form-builder'
- 'plugin: nested-docs'
- 'plugin: richtext-lexical'
- 'plugin: richtext-slate'
- 'plugin: search'
- 'plugin: sentry'
- 'plugin: seo'
- 'plugin: stripe'
- 'plugin: other'
validations:
required: true
- type: textarea
attributes:
label: Environment Info
description: Paste output from `pnpm payload info` _or_ Payload, Node.js, and Next.js versions.
render: text
placeholder: |
Payload:
Node.js:
Next.js:
validations:
required: true
- type: markdown
attributes:
value: Before submitting the issue, go through the steps you've written down to make sure the steps provided are detailed and clear.
- type: markdown
attributes:
value: Contributors should be able to follow the steps provided in order to reproduce the bug.
- type: markdown
attributes:
value: These steps are used to add integration tests to ensure the same issue does not happen again. Thanks in advance!

View File

@@ -1,40 +0,0 @@
name: Design Issue
description: '[SCREENSHOT REQUIRED] - Create a design issue report'
labels: ['status: needs-triage', 'v3', 'area: ui']
body:
- type: textarea
attributes:
label: Describe the Bug.
description: >-
_REQUIRED:_ Please a screenshot/video of the issue along with a detailed description of the problem.
validations:
required: true
- type: textarea
attributes:
label: Reproduction Steps
description: Steps to reproduce the behavior, please provide a clear description of how to reproduce the issue, based on the linked minimal reproduction. Screenshots can be provided in the issue body below. If using code blocks, make sure that [syntax highlighting is correct](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting) and double check that the rendered preview is not broken.
validations:
required: true
- type: textarea
attributes:
label: Environment Info
description: Paste output from `pnpm payload info` _or_ Payload, Node.js, and Next.js versions.
render: text
placeholder: |
Payload:
Node.js:
Next.js:
validations:
required: true
- type: markdown
attributes:
value: Before submitting the issue, go through the steps you've written down to make sure the steps provided are detailed and clear.
- type: markdown
attributes:
value: Contributors should be able to follow the steps provided in order to reproduce the bug.
- type: markdown
attributes:
value: These steps are used to add integration tests to ensure the same issue does not happen again. Thanks in advance!

View File

@@ -1,47 +0,0 @@
name: v2 Bug Report
description: Report a bug for Payload v2. ONLY CRITICAL bugs will be fixed in v2.
labels: ['status: needs-triage', 'v2']
body:
- type: markdown
attributes:
value: |
ONLY CRITICAL bugs will be fixed in v2.
- type: input
id: reproduction-link
attributes:
label: Link to reproduction
description: Want us to look into your issue faster? Follow the [reproduction-guide](https://github.com/payloadcms/payload/blob/main/.github/reproduction-guide.md) for more information.
validations:
required: false
- type: textarea
attributes:
label: Describe the Bug
validations:
required: true
- type: textarea
attributes:
label: To Reproduce
description: Steps to reproduce the behavior, please provide a clear description of how to reproduce the issue, based on the linked minimal reproduction. Screenshots can be provided in the issue body below. If using code blocks, make sure that [syntax highlighting is correct](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting) and double check that the rendered preview is not broken.
validations:
required: true
- type: input
id: version
attributes:
label: Payload Version
description: What version of Payload are you running?
validations:
required: true
- type: input
id: adapters-plugins
attributes:
label: Adapters and Plugins
description: What adapters and plugins are you using? ie. db-mongodb, db-postgres, bundler-webpack, etc.
- type: markdown
attributes:
value: Before submitting the issue, go through the steps you've written down to make sure the steps provided are detailed and clear.
- type: markdown
attributes:
value: Contributors should be able to follow the steps provided in order to reproduce the bug.
- type: markdown
attributes:
value: These steps are used to add integration tests to ensure the same issue does not happen again. Thanks in advance!

View File

@@ -1,23 +1,23 @@
<!--
## Description
Thank you for the PR! Please go through the checklist below and make sure you've completed all the steps.
<!-- Please include a summary of the pull request and any related issues it fixes. Please also include relevant motivation and context. -->
Please review the [CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md) document in this repository if you haven't already.
- [ ] I have read and understand the [CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md) document in this repository.
The following items will ensure that your PR is handled as smoothly as possible:
## Type of change
- PR Title must follow conventional commits format. For example, `feat: my new feature`, `fix(plugin-seo): my fix`.
- Minimal description explained as if explained to someone not immediately familiar with the code.
- Provide before/after screenshots or code diffs if applicable.
- Link any related issues/discussions from GitHub or Discord.
- Add review comments if necessary to explain to the reviewer the logic behind a change
<!-- Please delete options that are not relevant. -->
### What?
- [ ] Chore (non-breaking change which does not add functionality)
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Change to the [templates](https://github.com/payloadcms/payload/tree/main/templates) directory (does not affect core functionality)
- [ ] Change to the [examples](https://github.com/payloadcms/payload/tree/main/examples) directory (does not affect core functionality)
- [ ] This change requires a documentation update
### Why?
## Checklist:
### How?
Fixes #
-->
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation

View File

@@ -1,13 +0,0 @@
module.exports = {
env: {
es6: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:@typescript-eslint/eslint-recommended'],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
}

View File

@@ -1,74 +0,0 @@
# Release Commenter
This GitHub Action automatically comments on and/or labels Issues and PRs when a fix is released for them.
> [!IMPORTANT]
> 🔧 Heavily modified version of https://github.com/apexskier/github-release-commenter
## Fork Modifications
- Filters to closed PRs only
- Adds tag filter to support non-linear releases
- Better logging
- Moved to pnpm
- Uses @vercel/ncc for packaging
- Comments on locked issues by unlocking then re-locking
## How it works
Use this action in a workflow [triggered by a release](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#release). It will scan commits between that and the prior release, find associated Issues and PRs, and comment on them to let people know a release has been made. Associated Issues and PRs can be directly [linked](https://docs.github.com/en/free-pro-team@latest/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue) to the commit or manually linked from a PR associated with the commit.
## Inputs
**GITHUB_TOKEN**
A GitHub personal access token with repo scope, such as [`secrets.GITHUB_TOKEN`](https://docs.github.com/en/free-pro-team@latest/actions/reference/authentication-in-a-workflow#about-the-github_token-secret).
**comment-template** (optional)
Override the comment posted on Issues and PRs. Set to the empty string to disable commenting. Several variables strings will be automatically replaced:
- `{release_link}` - a markdown link to the release
- `{release_name}` - the release's name
- `{release_tag}` - the release's tag
**label-template** (optional)
Add the given label. Multiple labels can be separated by commas. Several variable strings will be automatically replaced:
- `{release_name}` - the release's name
- `{release_tag}` - the release's tag
**skip-label** (optional)
Skip processing if any of the given labels are present. Same processing rules as **label-template**. Default is "dependencies".
## Example
```yml
on:
release:
types: [published]
jobs:
release:
steps:
- uses: apexskier/github-release-commenter@v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
comment-template: |
Release {release_link} addresses this.
```
## Known limitations
These are some known limitations of this action. I'd like to try to address them in the future.
- Non-linear releases aren't supported. For example, releasing a patch to a prior major release after a new major release has been bumped.
- Non-sequential releases aren't supported. For example, if you release multiple prereleases between two official releases, this will only create a comment for the first prerelease in which a fix is released, not the final release.
- The first release for a project will be ignored. This is intentional, as the use case is unlikely. Most projects will either have several alphas that don't need release comments, or won't use issues/PRs for the first commit.
- If a large number of things are commented on, you may see the error `Error: You have triggered an abuse detection mechanism. Please wait a few minutes before you try again.`. Consider using the `skip-label` input to reduce your load on the GitHub API.
## Versions
Workflows will automatically update the tags `v1` and `latest`, allowing you to reference one of those instead of locking to a specific release.

View File

@@ -1,32 +0,0 @@
name: Release Commenter
description: Comment on PRs and Issues when a fix is released
branding:
icon: message-square
color: blue
inputs:
GITHUB_TOKEN:
description: |
A GitHub personal access token with repo scope, such as
secrets.GITHUB_TOKEN.
required: true
comment-template:
description: |
Text template for the comment string.
required: false
default: |
Included in release {release_link}
label-template:
description: Add the given label. Multiple labels can be separated by commas.
required: false
skip-label:
description: Skip commenting if any of the given label are present. Multiple labels can be separated by commas.
required: false
default: 'dependencies'
tag-filter:
description: |
Filter tags by a regular expression. Must be escaped. e.g. 'v\\d' to isolate tags between major versions.
required: false
default: null
runs:
using: node20
main: dist/index.js

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +0,0 @@
module.exports = {
testEnvironment: 'node',
testPathIgnorePatterns: ['/node_modules/', '<rootDir>/dist/'],
transform: {
'^.+\\.(t|j)sx?$': ['@swc/jest'],
},
}

View File

@@ -1,34 +0,0 @@
{
"name": "release-commenter",
"version": "0.0.0",
"private": true,
"description": "GitHub Action to automatically comment on PRs and Issues when a fix is released.",
"license": "MIT",
"main": "dist/index.js",
"scripts": {
"build": "pnpm build:typecheck && pnpm build:ncc",
"build:ncc": "ncc build src/index.ts -t -o dist",
"build:typecheck": "tsc",
"clean": "rimraf dist",
"test": "jest"
},
"dependencies": {
"@actions/core": "^1.3.0",
"@actions/github": "^5.0.0"
},
"devDependencies": {
"@octokit/webhooks-types": "^7.5.1",
"@swc/jest": "^0.2.37",
"@types/jest": "^27.5.2",
"@types/node": "^20.16.5",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"@vercel/ncc": "0.38.1",
"concurrently": "^8.2.2",
"eslint": "^7.32.0",
"jest": "^29.7.0",
"prettier": "^3.3.3",
"ts-jest": "^26.5.6",
"typescript": "^4.9.5"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,266 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`tests feature tests can apply labels 1`] = `
[
[
{
"issue_number": 123,
"labels": [
":dart: landed",
"release-current_tag_name",
"Release Name",
],
},
],
[
{
"issue_number": 7,
"labels": [
":dart: landed",
"release-current_tag_name",
"Release Name",
],
},
],
]
`;
exports[`tests main test 1`] = `
{
"graphql": [MockFunction] {
"calls": [
[
"
{
resource(url: "http://repository/commit/SHA1") {
... on Commit {
messageHeadlineHTML
messageBodyHTML
associatedPullRequests(first: 10) {
pageInfo {
hasNextPage
}
edges {
node {
bodyHTML
number
state
labels(first: 10) {
pageInfo {
hasNextPage
}
nodes {
name
}
}
timelineItems(itemTypes: [CONNECTED_EVENT, DISCONNECTED_EVENT], first: 100) {
pageInfo {
hasNextPage
}
nodes {
... on ConnectedEvent {
__typename
isCrossRepository
subject {
... on Issue {
number
}
}
}
... on DisconnectedEvent {
__typename
isCrossRepository
subject {
... on Issue {
number
}
}
}
}
}
}
}
}
}
}
}
",
],
[
"
{
resource(url: "http://repository/commit/SHA2") {
... on Commit {
messageHeadlineHTML
messageBodyHTML
associatedPullRequests(first: 10) {
pageInfo {
hasNextPage
}
edges {
node {
bodyHTML
number
state
labels(first: 10) {
pageInfo {
hasNextPage
}
nodes {
name
}
}
timelineItems(itemTypes: [CONNECTED_EVENT, DISCONNECTED_EVENT], first: 100) {
pageInfo {
hasNextPage
}
nodes {
... on ConnectedEvent {
__typename
isCrossRepository
subject {
... on Issue {
number
}
}
}
... on DisconnectedEvent {
__typename
isCrossRepository
subject {
... on Issue {
number
}
}
}
}
}
}
}
}
}
}
}
",
],
],
"results": [
{
"type": "return",
"value": Promise {},
},
{
"type": "return",
"value": Promise {},
},
],
},
"rest": {
"issues": {
"addLabels": [MockFunction],
"createComment": [MockFunction] {
"calls": [
[
{
"body": "Included in release [current_tag_name](http://current_release). Replacements: current_tag_name, current_tag_name.",
"issue_number": 3,
},
],
[
{
"body": "Included in release [current_tag_name](http://current_release). Replacements: current_tag_name, current_tag_name.",
"issue_number": 123,
},
],
[
{
"body": "Included in release [current_tag_name](http://current_release). Replacements: current_tag_name, current_tag_name.",
"issue_number": 7,
},
],
],
"results": [
{
"type": "return",
"value": Promise {},
},
{
"type": "return",
"value": Promise {},
},
{
"type": "return",
"value": Promise {},
},
],
},
"get": [MockFunction] {
"calls": [
[
{
"issue_number": 3,
},
],
[
{
"issue_number": 123,
},
],
[
{
"issue_number": 7,
},
],
],
"results": [
{
"type": "return",
"value": Promise {},
},
{
"type": "return",
"value": Promise {},
},
{
"type": "return",
"value": Promise {},
},
],
},
},
"repos": {
"compareCommits": [MockFunction] {
"calls": [
[
{
"base": "prior_tag_name",
"head": "current_tag_name",
},
],
],
"results": [
{
"type": "return",
"value": Promise {},
},
],
},
"listReleases": [MockFunction] {
"calls": [
[
{
"per_page": 100,
},
],
],
"results": [
{
"type": "return",
"value": Promise {},
},
],
},
},
},
}
`;

View File

@@ -1,399 +0,0 @@
import type * as githubModule from '@actions/github'
import type * as coreModule from '@actions/core'
import { mock } from 'node:test'
jest.mock('@actions/core')
jest.mock('@actions/github')
type Mocked<T> = {
-readonly [P in keyof T]: T[P] extends Function ? jest.Mock<T[P]> : jest.Mocked<Partial<T[P]>>
}
const github = require('@actions/github') as jest.Mocked<Mocked<typeof githubModule>>
const core = require('@actions/core') as jest.Mocked<Mocked<typeof coreModule>>
describe('tests', () => {
let mockOctokit: any = {}
let currentTag: string = 'current_tag_name'
;(core.warning as any) = jest.fn(console.warn.bind(console))
;(core.error as any) = jest.fn(console.error.bind(console))
let commentTempate: string = ''
let labelTemplate: string | null = null
const skipLabelTemplate: string | null = 'skip,test'
let tagFilter: string | RegExp | null = null
let simpleMockOctokit: any = {}
beforeEach(() => {
tagFilter = null
currentTag = 'current_tag_name'
;(github.context as any) = {
payload: {
repo: {
owner: 'owner',
repo: 'repo',
},
release: {
tag_name: currentTag,
},
repository: { html_url: 'http://repository' },
},
}
github.getOctokit.mockReset().mockImplementationOnce(((token: string) => {
expect(token).toBe('GITHUB_TOKEN_VALUE')
return mockOctokit
}) as any)
;(core.getInput as any).mockImplementation((key: string) => {
if (key == 'GITHUB_TOKEN') {
return 'GITHUB_TOKEN_VALUE'
}
if (key == 'comment-template') {
return commentTempate
}
if (key == 'label-template') {
return labelTemplate
}
if (key == 'skip-label') {
return skipLabelTemplate
}
if (key == 'tag-filter') {
return tagFilter
}
fail(`Unexpected input key ${key}`)
})
commentTempate =
'Included in release {release_link}. Replacements: {release_name}, {release_tag}.'
labelTemplate = null
simpleMockOctokit = {
rest: {
issues: {
get: jest.fn(() => Promise.resolve({ data: { locked: false } })),
createComment: jest.fn(() => Promise.resolve()),
addLabels: jest.fn(() => Promise.resolve()),
},
repos: {
listReleases: jest.fn(() =>
Promise.resolve({
data: [
{
name: 'Release Name',
tag_name: 'current_tag_name',
html_url: 'http://current_release',
},
{
tag_name: 'prior_tag_name',
html_url: 'http://prior_release',
},
],
}),
),
compareCommits: jest.fn(() =>
Promise.resolve({
data: { commits: [{ sha: 'SHA1' }] },
}),
),
},
},
graphql: jest.fn(() =>
Promise.resolve({
resource: {
messageHeadlineHTML: '',
messageBodyHTML:
'<span class="issue-keyword tooltipped tooltipped-se" aria-label="This commit closes issue #123.">Closes</span> <p><span class="issue-keyword tooltipped tooltipped-se" aria-label="This pull request closes issue #7.">Closes</span>',
associatedPullRequests: {
pageInfo: { hasNextPage: false },
edges: [],
},
},
}),
),
}
})
afterEach(() => {
expect(core.error).not.toHaveBeenCalled()
expect(core.warning).not.toHaveBeenCalled()
expect(core.setFailed).not.toHaveBeenCalled()
})
test('main test', async () => {
mockOctokit = {
...simpleMockOctokit,
rest: {
issues: {
get: jest.fn(() => Promise.resolve({ data: { locked: false } })),
createComment: jest.fn(() => Promise.resolve()),
addLabels: jest.fn(() => Promise.resolve()),
},
repos: {
listReleases: jest.fn(() =>
Promise.resolve({
data: [
{
tag_name: 'current_tag_name',
html_url: 'http://current_release',
},
{
tag_name: 'prior_tag_name',
html_url: 'http://prior_release',
},
],
}),
),
compareCommits: jest.fn(() =>
Promise.resolve({
data: { commits: [{ sha: 'SHA1' }, { sha: 'SHA2' }] },
}),
),
},
},
graphql: jest.fn(() =>
Promise.resolve({
resource: {
messageHeadlineHTML:
'<span class="issue-keyword tooltipped tooltipped-se" aria-label="This commit closes issue #3.">Closes</span> <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="718013420" data-permission-text="Title is private" data-url="https://github.com/apexskier/github-release-commenter/issues/1" data-hovercard-type="issue" data-hovercard-url="/apexskier/github-release-commenter/issues/1/hovercard" href="https://github.com/apexskier/github-release-commenter/issues/1">#1</a>',
messageBodyHTML:
'<span class="issue-keyword tooltipped tooltipped-se" aria-label="This commit closes issue #123.">Closes</span> <p><span class="issue-keyword tooltipped tooltipped-se" aria-label="This pull request closes issue #7.">Closes</span>',
associatedPullRequests: {
pageInfo: { hasNextPage: false },
edges: [
{
node: {
bodyHTML:
'<span class="issue-keyword tooltipped tooltipped-se" aria-label="This commit closes issue #4.">Closes</span> <span class="issue-keyword tooltipped tooltipped-se" aria-label="This commit closes issue #5.">Closes</span>',
number: 9,
labels: {
pageInfo: { hasNextPage: false },
nodes: [{ name: 'label1' }, { name: 'label2' }],
},
timelineItems: {
pageInfo: { hasNextPage: false },
nodes: [
{
isCrossRepository: true,
__typename: 'ConnectedEvent',
subject: { number: 1 },
},
{
isCrossRepository: false,
__typename: 'ConnectedEvent',
subject: { number: 2 },
},
{
isCrossRepository: false,
__typename: 'DisconnectedEvent',
subject: { number: 2 },
},
{
isCrossRepository: false,
__typename: 'ConnectedEvent',
subject: { number: 2 },
},
],
},
},
},
{
node: {
bodyHTML: '',
number: 42,
labels: {
pageInfo: { hasNextPage: false },
nodes: [{ name: 'label1' }, { name: 'skip' }],
},
timelineItems: {
pageInfo: { hasNextPage: false },
nodes: [
{
isCrossRepository: true,
__typename: 'ConnectedEvent',
subject: { number: 82 },
},
],
},
},
},
],
},
},
}),
),
}
jest.isolateModules(() => {
require('./index')
})
await new Promise<void>(setImmediate)
expect(mockOctokit).toMatchSnapshot()
expect(mockOctokit.rest.issues.createComment).toHaveBeenCalledTimes(3)
})
describe('can filter tags', () => {
const v3prev = 'v3.0.1'
const v3current = 'v3.0.2'
const v2prev = 'v2.0.1'
const v2current = 'v2.0.2'
const listReleasesData = [
{
name: 'Current Release Name',
tag_name: v3current,
html_url: 'http://v3.0.2',
},
{
name: 'Prev Release Name',
tag_name: v3prev,
html_url: 'http://v3.0.1',
},
{
name: 'v2 Current Release Name',
tag_name: v2current,
html_url: 'http://v2.0.2',
},
{
name: 'v2 Prev Release Name',
tag_name: v2prev,
html_url: 'http://v2.0.1',
},
]
it.each`
description | prevTag | currentTag | filter
${'no filter'} | ${v3prev} | ${v3current} | ${null}
${'v3'} | ${v3prev} | ${v3current} | ${'v\\d'}
${'v2'} | ${v2prev} | ${v2current} | ${'v\\d'}
`('should filter tags with $description', async ({ prevTag, currentTag, filter }) => {
// @ts-ignore
github.context.payload.release.tag_name = currentTag
tagFilter = filter
mockOctokit = {
...simpleMockOctokit,
rest: {
issues: {
get: jest.fn(() => Promise.resolve({ data: { locked: false } })),
createComment: jest.fn(() => Promise.resolve()),
addLabels: jest.fn(() => Promise.resolve()),
},
repos: {
listReleases: jest.fn(() =>
Promise.resolve({
data: listReleasesData,
}),
),
compareCommits: jest.fn(() =>
Promise.resolve({
data: { commits: [{ sha: 'SHA1' }] },
}),
),
},
},
graphql: jest.fn(() =>
Promise.resolve({
resource: {
messageHeadlineHTML: '',
messageBodyHTML:
'<span class="issue-keyword tooltipped tooltipped-se" aria-label="This commit closes issue #123.">Closes</span> <p><span class="issue-keyword tooltipped tooltipped-se" aria-label="This pull request closes issue #7.">Closes</span>',
associatedPullRequests: {
pageInfo: { hasNextPage: false },
edges: [],
},
},
}),
),
}
jest.isolateModules(() => {
require('./index')
})
await new Promise<void>((resolve) => setImmediate(() => resolve()))
expect(github.getOctokit).toHaveBeenCalled()
expect(mockOctokit.rest.repos.compareCommits.mock.calls).toEqual([
[{ base: prevTag, head: currentTag }],
])
})
})
describe('feature tests', () => {
beforeEach(() => {
mockOctokit = simpleMockOctokit
})
it('can disable comments', async () => {
commentTempate = ''
jest.isolateModules(() => {
require('./index')
})
await new Promise<void>((resolve) => setImmediate(() => resolve()))
expect(github.getOctokit).toHaveBeenCalled()
expect(mockOctokit.rest.issues.createComment).not.toHaveBeenCalled()
})
it('should unlock and comment', async () => {
mockOctokit = {
...simpleMockOctokit,
rest: {
...simpleMockOctokit.rest,
issues: {
// Return locked for both issues to be commented on
get: jest.fn(() => Promise.resolve({ data: { locked: true } })),
lock: jest.fn(() => Promise.resolve()),
unlock: jest.fn(() => Promise.resolve()),
createComment: jest.fn(() => Promise.resolve()),
},
},
graphql: jest.fn(() =>
Promise.resolve({
resource: {
messageHeadlineHTML: '',
messageBodyHTML:
'<span class="issue-keyword tooltipped tooltipped-se" aria-label="This commit closes issue #123.">Closes</span> <p><span class="issue-keyword tooltipped tooltipped-se" aria-label="This pull request closes issue #7.">Closes</span>',
associatedPullRequests: {
pageInfo: { hasNextPage: false },
edges: [],
},
},
}),
),
}
jest.isolateModules(() => {
require('./index')
})
await new Promise<void>((resolve) => setImmediate(() => resolve()))
expect(github.getOctokit).toHaveBeenCalled()
// Should call once for both linked issues
expect(mockOctokit.rest.issues.unlock).toHaveBeenCalledTimes(2)
expect(mockOctokit.rest.issues.createComment).toHaveBeenCalledTimes(2)
expect(mockOctokit.rest.issues.lock).toHaveBeenCalledTimes(2)
})
it.skip('can apply labels', async () => {
labelTemplate = ':dart: landed,release-{release_tag},{release_name}'
jest.isolateModules(() => {
require('./index')
})
await new Promise<void>((resolve) => setImmediate(() => resolve()))
expect(github.getOctokit).toHaveBeenCalled()
expect(mockOctokit.rest.issues.addLabels.mock.calls).toMatchSnapshot()
})
})
})

View File

@@ -1,349 +0,0 @@
import * as core from '@actions/core'
import * as github from '@actions/github'
import type * as Webhooks from '@octokit/webhooks-types'
const closesMatcher = /aria-label="This (?:commit|pull request) closes issue #(\d+)\."/g
const releaseLinkTemplateRegex = /{release_link}/g
const releaseNameTemplateRegex = /{release_name}/g
const releaseTagTemplateRegex = /{release_tag}/g
;(async function main() {
try {
const payload = github.context.payload as Webhooks.EventPayloadMap['release']
const githubToken = core.getInput('GITHUB_TOKEN')
const tagFilter = core.getInput('tag-filter') || undefined // Accept tag filter as an input
const octokit = github.getOctokit(githubToken)
const commentTemplate = core.getInput('comment-template')
const labelTemplate = core.getInput('label-template') || null
const skipLabelTemplate = core.getInput('skip-label') || null
// Fetch the releases with the optional tag filter applied
const { data: rawReleases } = await octokit.rest.repos.listReleases({
...github.context.repo,
per_page: 100,
})
// Get the current release tag or latest tag
const currentTag = payload?.release?.tag_name || rawReleases?.[0]?.tag_name
let releases = rawReleases
// Filter releases by the tag filter if provided
if (tagFilter) {
core.info(`Filtering releases by tag filter: ${tagFilter}`)
// Get the matching part of the current release tag
const regexMatch = currentTag.match(tagFilter)?.[0]
if (!regexMatch) {
core.error(`Current release tag ${currentTag} does not match the tag filter ${tagFilter}`)
return
}
core.info(`Matched string from filter: ${regexMatch}`)
releases = releases
.filter((release) => {
const match = release.tag_name.match(regexMatch)?.[0]
return match
})
.slice(0, 2)
}
core.info(`Releases: ${JSON.stringify(releases, null, 2)}`)
if (releases.length < 2) {
if (!releases.length) {
core.error(`No releases found with the provided tag filter: '${tagFilter}'`)
return
}
core.info('first release')
return
}
const [currentRelease, priorRelease] = releases
core.info(`${priorRelease.tag_name}...${currentRelease.tag_name}`)
const {
data: { commits },
} = await octokit.rest.repos.compareCommits({
...github.context.repo,
base: priorRelease.tag_name,
head: currentRelease.tag_name,
})
if (!currentRelease.name) {
core.info('Current release has no name, will fall back to the tag name.')
}
const releaseLabel = currentRelease.name || currentRelease.tag_name
const comment = commentTemplate
.trim()
.split(releaseLinkTemplateRegex)
.join(`[${releaseLabel}](${currentRelease.html_url})`)
.split(releaseNameTemplateRegex)
.join(releaseLabel)
.split(releaseTagTemplateRegex)
.join(currentRelease.tag_name)
const parseLabels = (rawInput: string | null) =>
rawInput
?.split(releaseNameTemplateRegex)
.join(releaseLabel)
?.split(releaseTagTemplateRegex)
.join(currentRelease.tag_name)
?.split(',')
?.map((l) => l.trim())
.filter((l) => l)
const labels = parseLabels(labelTemplate)
const skipLabels = parseLabels(skipLabelTemplate)
const linkedIssuesPrs = new Set<number>()
await Promise.all(
commits.map((commit) =>
(async () => {
const query = `
{
resource(url: "${payload.repository.html_url}/commit/${commit.sha}") {
... on Commit {
messageHeadlineHTML
messageBodyHTML
associatedPullRequests(first: 10) {
pageInfo {
hasNextPage
}
edges {
node {
bodyHTML
number
state
labels(first: 10) {
pageInfo {
hasNextPage
}
nodes {
name
}
}
timelineItems(itemTypes: [CONNECTED_EVENT, DISCONNECTED_EVENT], first: 100) {
pageInfo {
hasNextPage
}
nodes {
... on ConnectedEvent {
__typename
isCrossRepository
subject {
... on Issue {
number
}
}
}
... on DisconnectedEvent {
__typename
isCrossRepository
subject {
... on Issue {
number
}
}
}
}
}
}
}
}
}
}
}
`
const response: {
resource: null | {
messageHeadlineHTML: string
messageBodyHTML: string
associatedPullRequests: {
pageInfo: { hasNextPage: boolean }
edges: ReadonlyArray<{
node: {
bodyHTML: string
number: number
state: 'OPEN' | 'CLOSED' | 'MERGED'
labels: {
pageInfo: { hasNextPage: boolean }
nodes: ReadonlyArray<{
name: string
}>
}
timelineItems: {
pageInfo: { hasNextPage: boolean }
nodes: ReadonlyArray<{
__typename: 'ConnectedEvent' | 'DisconnectedEvent'
isCrossRepository: boolean
subject: {
number: number
}
}>
}
}
}>
}
}
} = await octokit.graphql(query)
if (!response.resource) {
return
}
// core.info(JSON.stringify(response.resource, null, 2))
core.info(`Checking commit: ${payload.repository.html_url}/commit/${commit.sha}`)
const associatedClosedPREdges = response.resource.associatedPullRequests.edges.filter(
(e) => e.node.state === 'MERGED',
)
if (associatedClosedPREdges.length) {
core.info(
` Associated Merged PRs:\n ${associatedClosedPREdges.map((pr) => `${payload.repository.html_url}/pull/${pr.node.number}`).join('\n ')}`,
)
} else {
core.info(' No associated merged PRs')
}
const html = [
response.resource.messageHeadlineHTML,
response.resource.messageBodyHTML,
...associatedClosedPREdges.map((pr) => pr.node.bodyHTML),
].join(' ')
for (const match of html.matchAll(closesMatcher)) {
const [, num] = match
linkedIssuesPrs.add(parseInt(num, 10))
core.info(
` Linked issue/PR from closesMatcher: ${payload.repository.html_url}/pull/${num}`,
)
}
if (response.resource.associatedPullRequests.pageInfo.hasNextPage) {
core.warning(`Too many PRs associated with ${commit.sha}`)
}
const seen = new Set<number>()
for (const associatedPR of associatedClosedPREdges) {
if (associatedPR.node.timelineItems.pageInfo.hasNextPage) {
core.warning(`Too many links for #${associatedPR.node.number}`)
}
if (associatedPR.node.labels.pageInfo.hasNextPage) {
core.warning(`Too many labels for #${associatedPR.node.number}`)
}
// a skip labels is present on this PR
if (
skipLabels?.some((l) => associatedPR.node.labels.nodes.some(({ name }) => name === l))
) {
continue
}
linkedIssuesPrs.add(associatedPR.node.number)
core.info(
` Linked issue/PR from associated PR: ${payload.repository.html_url}/pull/${associatedPR.node.number}`,
)
// These are sorted by creation date in ascending order. The latest event for a given issue/PR is all we need
// ignore links that aren't part of this repo
const links = associatedPR.node.timelineItems.nodes
.filter((node) => !node.isCrossRepository)
.reverse()
for (const link of links) {
if (seen.has(link.subject.number)) {
continue
}
if (link.__typename == 'ConnectedEvent') {
linkedIssuesPrs.add(link.subject.number)
core.info(
`Linked issue/PR from connected event: ${payload.repository.html_url}/pull/${link.subject.number}`,
)
}
seen.add(link.subject.number)
}
}
})(),
),
)
core.info(
`Final issues/PRs to be commented on: \n${Array.from(linkedIssuesPrs)
.map((num) => ` ${payload.repository.html_url}/pull/${num}`)
.join('\n')}`,
)
const requests: Array<Promise<unknown>> = []
for (const issueNumber of linkedIssuesPrs) {
const baseRequest = {
...github.context.repo,
issue_number: issueNumber,
}
if (comment) {
const commentRequest = {
...baseRequest,
body: comment,
}
// Check if issue is locked or not
const { data: issue } = await octokit.rest.issues.get(baseRequest)
let createCommentPromise: () => Promise<void>
if (!issue.locked) {
createCommentPromise = async () => {
try {
await octokit.rest.issues.createComment(commentRequest)
} catch (error) {
core.error(error as Error)
core.error(
`Failed to comment on issue/PR: ${issueNumber}. ${payload.repository.html_url}/pull/${issueNumber}`,
)
}
}
} else {
core.info(
`Issue/PR is locked: ${issueNumber}. Unlocking, commenting, and re-locking. ${payload.repository.html_url}/pull/${issueNumber}`,
)
createCommentPromise = async () => {
try {
core.debug(`Unlocking issue/PR: ${issueNumber}`)
await octokit.rest.issues.unlock(baseRequest)
core.debug(`Commenting on issue/PR: ${issueNumber}`)
await octokit.rest.issues.createComment(commentRequest)
core.debug(`Re-locking issue/PR: ${issueNumber}`)
await octokit.rest.issues.lock(baseRequest)
} catch (error) {
core.error(error as Error)
core.error(
`Failed to unlock, comment, and re-lock issue/PR: ${issueNumber}. ${payload.repository.html_url}/pull/${issueNumber}`,
)
}
}
}
requests.push(createCommentPromise())
}
if (labels) {
const request = {
...baseRequest,
labels,
}
// core.info(JSON.stringify(request, null, 2))
requests.push(octokit.rest.issues.addLabels(request))
}
}
await Promise.all(requests)
} catch (error) {
core.error(error as Error)
core.setFailed((error as Error).message)
}
})()

View File

@@ -1,15 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["es2020.string"],
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true,
"downlevelIteration": true,
"skipLibCheck": true,
},
"exclude": ["src/**/*.test.ts"]
}

View File

@@ -1,76 +0,0 @@
name: Setup node and pnpm
description: |
Configures Node, pnpm, cache, performs pnpm install
inputs:
node-version:
description: Node.js version
required: true
default: 22.6.0
pnpm-version:
description: Pnpm version
required: true
default: 9.7.1
pnpm-run-install:
description: Whether to run pnpm install
required: false
default: true
pnpm-restore-cache:
description: Whether to restore cache
required: false
default: true
pnpm-install-cache-key:
description: The cache key for the pnpm install cache
default: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
outputs:
pnpm-store-path:
description: The resolved pnpm store path
pnpm-install-cache-key:
description: The cache key used for pnpm install cache
runs:
using: composite
steps:
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
shell: bash
run: sudo ethtool -K eth0 tx off rx off
- name: Setup Node@${{ inputs.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ inputs.pnpm-version }}
run_install: false
- name: Get pnpm store path
shell: bash
run: |
STORE_PATH=$(pnpm store path --silent)
echo "STORE_PATH=$STORE_PATH" >> $GITHUB_ENV
echo "Pnpm store path resolved to: $STORE_PATH"
- name: Restore pnpm install cache
if: ${{ inputs.pnpm-restore-cache == 'true' }}
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ inputs.pnpm-install-cache-key }}
restore-keys: |
pnpm-store-${{ inputs.pnpm-version }}-
pnpm-store-
- name: Run pnpm install
if: ${{ inputs.pnpm-run-install == 'true' }}
shell: bash
run: pnpm install
# Set the cache key output
- run: |
echo "pnpm-install-cache-key=${{ inputs.pnpm-install-cache-key }}" >> $GITHUB_ENV
shell: bash

View File

@@ -1,22 +0,0 @@
MIT License
Copyright (c) 2024 Payload <info@payloadcms.com>. All modification and additions are copyright of Payload.
---
Original license:
ISC License
Copyright (c) 2023, Balázs Orbán
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -1,21 +0,0 @@
# Triage
Modified version of https://github.com/balazsorban44/nissuer
## Modifications
- Port to TypeScript
- Remove issue locking
- Remove reproduction blocklist
- Uses `@vercel/ncc` for packaging
## Development
> [!IMPORTANT]
> Whenever a modification is made to the action, the action built to `dist` must be committed to the repository.
This is done by running:
```sh
pnpm build
```

View File

@@ -1,40 +0,0 @@
name: Triage
description: Initial triage for issues
inputs:
reproduction-comment:
description: 'Either a string or a path to a .md file inside the repository. Example: ".github/invalid-reproduction.md"'
default: '.github/invalid-reproduction.md'
reproduction-hosts:
description: 'Comma-separated list of hostnames that are allowed for reproductions. Example: "github.com,codesandbox.io"'
default: github.com
reproduction-invalid-label:
description: 'Label to apply to issues without a valid reproduction. Example: "invalid-reproduction"'
default: 'invalid-reproduction'
reproduction-issue-labels:
description: 'Comma-separated list of issue labels. If configured, only verify reproduction URLs of issues with one of these labels present. Adding a comma at the end will handle non-labeled issues as invalid. Example: "bug,", will consider issues with the label "bug" or no label.'
default: ''
reproduction-link-section:
description: 'A regular expression string with "(.*)" matching a valid URL in the issue body. The result is trimmed. Example: "### Link to reproduction(.*)### To reproduce"'
default: '### Link to reproduction(.*)### To reproduce'
actions-to-perform:
description: 'Comma-separated list of actions to perform on the issue. Example: "tag,comment,close"'
default: 'tag,comment,close'
runs:
using: 'composite'
steps:
- name: Checkout code
if: ${{ github.event_name != 'pull_request' }}
uses: actions/checkout@v4
- name: Run action
run: node ${{ github.action_path }}/dist/index.js
shell: sh
# https://github.com/actions/runner/issues/665#issuecomment-676581170
env:
'INPUT_REPRODUCTION_COMMENT': ${{inputs.reproduction-comment}}
'INPUT_REPRODUCTION_HOSTS': ${{inputs.reproduction-hosts}}
'INPUT_REPRODUCTION_INVALID_LABEL': ${{inputs.reproduction-invalid-label}}
'INPUT_REPRODUCTION_ISSUE_LABELS': ${{inputs.reproduction-issue-labels}}
'INPUT_REPRODUCTION_LINK_SECTION': ${{inputs.reproduction-link-section}}
'INPUT_ACTIONS_TO_PERFORM': ${{inputs.actions-to-perform}}

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +0,0 @@
module.exports = {
testEnvironment: 'node',
testPathIgnorePatterns: ['/node_modules/', '<rootDir>/dist/'],
transform: {
'^.+\\.(t|j)sx?$': ['@swc/jest'],
},
}

View File

@@ -1,34 +0,0 @@
{
"name": "triage",
"version": "0.0.0",
"private": true,
"description": "GitHub Action to triage new issues",
"license": "MIT",
"main": "dist/index.js",
"scripts": {
"build": "pnpm build:typecheck && pnpm build:ncc",
"build:ncc": "ncc build src/index.ts -t -o dist",
"build:typecheck": "tsc",
"clean": "rimraf dist",
"test": "jest"
},
"dependencies": {
"@actions/core": "^1.3.0",
"@actions/github": "^5.0.0"
},
"devDependencies": {
"@octokit/webhooks-types": "^7.5.1",
"@swc/jest": "^0.2.36",
"@types/jest": "^27.5.2",
"@types/node": "^20.16.5",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"@vercel/ncc": "0.38.1",
"concurrently": "^8.2.2",
"eslint": "^7.32.0",
"jest": "^29.7.0",
"prettier": "^3.3.3",
"ts-jest": "^26.5.6",
"typescript": "^4.9.5"
}
}

5419
.github/actions/triage/pnpm-lock.yaml generated vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,215 +0,0 @@
import { debug, error, getBooleanInput, getInput, info, setFailed } from '@actions/core'
import { context, getOctokit } from '@actions/github'
import { readFile, access } from 'node:fs/promises'
import { join } from 'node:path'
// Ensure GITHUB_TOKEN and GITHUB_WORKSPACE are present
if (!process.env.GITHUB_TOKEN) throw new TypeError('No GITHUB_TOKEN provided')
if (!process.env.GITHUB_WORKSPACE) throw new TypeError('Not a GitHub workspace')
const validActionsToPerform = ['tag', 'comment', 'close'] as const
type ActionsToPerform = (typeof validActionsToPerform)[number]
// Define the configuration object
interface Config {
invalidLink: {
comment: string
bugLabels: string[]
hosts: string[]
label: string
linkSection: string
}
actionsToPerform: ActionsToPerform[]
token: string
workspace: string
}
const config: Config = {
invalidLink: {
comment: getInput('reproduction_comment') || '.github/invalid-reproduction.md',
bugLabels: getInput('reproduction_issue_labels')
.split(',')
.map((l) => l.trim()),
hosts: (getInput('reproduction_hosts') || 'github.com').split(',').map((h) => h.trim()),
label: getInput('reproduction_invalid_label') || 'invalid-reproduction',
linkSection:
getInput('reproduction_link_section') || '### Link to reproduction(.*)### To reproduce',
},
actionsToPerform: (getInput('actions_to_perform') || validActionsToPerform.join(','))
.split(',')
.map((a) => {
const action = a.trim().toLowerCase() as ActionsToPerform
if (validActionsToPerform.includes(action)) {
return action
}
throw new TypeError(`Invalid action: ${action}`)
}),
token: process.env.GITHUB_TOKEN,
workspace: process.env.GITHUB_WORKSPACE,
}
// Attempt to parse JSON, return parsed object or error
function tryParse(json: string): Record<string, unknown> {
try {
return JSON.parse(json)
} catch (e) {
setFailed(`Could not parse JSON: ${e instanceof Error ? e.message : e}`)
return {}
}
}
// Retrieves a boolean input or undefined based on environment variables
function getBooleanOrUndefined(value: string): boolean | undefined {
const variable = process.env[`INPUT_${value.toUpperCase()}`]
return variable === undefined || variable === '' ? undefined : getBooleanInput(value)
}
// Returns the appropriate label match type
function getLabelMatch(value: string | undefined): 'name' | 'description' {
return value === 'name' ? 'name' : 'description'
}
// Function to check if an issue contains a valid reproduction link
async function checkValidReproduction(): Promise<void> {
const { issue, action } = context.payload as {
issue: { number: number; body: string; labels: { name: string }[] } | undefined
action: string
}
if (action !== 'opened' || !issue?.body) return
const labels = issue.labels.map((l) => l.name)
const issueMatchingLabel =
labels.length &&
config.invalidLink.bugLabels.length &&
labels.some((l) => config.invalidLink.bugLabels.includes(l))
if (!issueMatchingLabel) {
info(
`Issue #${issue.number} does not match required labels: ${config.invalidLink.bugLabels.join(', ')}`,
)
info(`Issue labels: ${labels.join(', ')}`)
return
}
info(`Issue #${issue.number} labels: ${labels.join(', ')}`)
const { rest: client } = getOctokit(config.token)
const common = { ...context.repo, issue_number: issue.number }
const labelsToRemove = labels.filter((l) => config.invalidLink.bugLabels.includes(l))
if (await isValidReproduction(issue.body)) {
await Promise.all(
labelsToRemove.map((label) => client.issues.removeLabel({ ...common, name: label })),
)
return info(`Issue #${issue.number} contains a valid reproduction 💚`)
}
info(`Invalid reproduction, issue will be closed/labeled/commented...`)
// Adjust labels
await Promise.all(
labelsToRemove.map((label) => client.issues.removeLabel({ ...common, name: label })),
)
// Tag
if (config.actionsToPerform.includes('tag')) {
info(`Added label: ${config.invalidLink.label}`)
await client.issues.addLabels({ ...common, labels: [config.invalidLink.label] })
} else {
info('Tag - skipped, not provided in actions to perform')
}
// Comment
if (config.actionsToPerform.includes('comment')) {
const comment = join(config.workspace, config.invalidLink.comment)
await client.issues.createComment({ ...common, body: await getCommentBody(comment) })
info(`Commented with invalid reproduction message`)
} else {
info('Comment - skipped, not provided in actions to perform')
}
// Close
if (config.actionsToPerform.includes('close')) {
await client.issues.update({ ...common, state: 'closed' })
info(`Closed issue #${issue.number}`)
} else {
info('Close - skipped, not provided in actions to perform')
}
}
/**
* Determine if an issue contains a valid/accessible link to a reproduction.
*
* Returns `true` if the link is valid.
* @param body - The body content of the issue
*/
async function isValidReproduction(body: string): Promise<boolean> {
const linkSectionRe = new RegExp(config.invalidLink.linkSection, 'is')
const link = body.match(linkSectionRe)?.[1]?.trim()
if (!link) {
info('Missing link')
info(`Link section regex: ${linkSectionRe}`)
info(`Link section: ${body}`)
return false
}
info(`Checking validity of link: ${link}`)
if (!URL.canParse(link)) {
info(`Invalid URL: ${link}`)
return false
}
const url = new URL(link)
if (!config.invalidLink.hosts.includes(url.hostname)) {
info('Link did not match allowed reproduction hosts')
return false
}
try {
// Verify that the link can be accessed
const response = await fetch(link)
const isOk = response.status < 400 || response.status >= 500
info(`Link status: ${response.status}`)
if (!isOk) {
info(`Link returned status ${response.status}`)
}
return isOk
} catch (error) {
info(`Error fetching link: ${(error as Error).message}`)
return false
}
}
/**
* Return either a file's content or a string
* @param {string} pathOrComment
*/
async function getCommentBody(pathOrComment: string) {
try {
await access(pathOrComment)
return await readFile(pathOrComment, 'utf8')
} catch (error: any) {
if (error.code === 'ENOENT') return pathOrComment
throw error
}
}
async function run() {
const { token, workspace, ...safeConfig } = config
info('Configuration:')
info(JSON.stringify(safeConfig, null, 2))
await checkValidReproduction()
}
run().catch(setFailed)

View File

@@ -1,15 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["es2020.string"],
"noEmit": true,
"strict": true,
"noUnusedLocals": false, // Undo this
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true,
"downlevelIteration": true,
"skipLibCheck": true,
},
"exclude": ["src/**/*.test.ts"]
}

View File

@@ -1,20 +0,0 @@
**Please add a reproduction in order for us to be able to investigate.**
Depending on the quality of reproduction steps, this issue may be closed if no reproduction is provided.
### Why was this issue marked with the `invalid-reproduction` label?
To be able to investigate, we need access to a reproduction to identify what triggered the issue. We prefer a link to a public GitHub repository created with `create-payload-app@beta -t blank` or a forked/branched version of this repository with tests added (more info in the [reproduction-guide](https://github.com/payloadcms/payload/blob/main/.github/reproduction-guide.md)).
To make sure the issue is resolved as quickly as possible, please make sure that the reproduction is as **minimal** as possible. This means that you should **remove unnecessary code, files, and dependencies** that do not contribute to the issue. Ensure your reproduction does not depend on secrets, 3rd party registries, private dependencies, or any other data that cannot be made public. Avoid a reproduction including a whole monorepo (unless relevant to the issue). The easier it is to reproduce the issue, the quicker we can help.
Please test your reproduction against the latest version of Payload to make sure your issue has not already been fixed.
### I added a link, why was it still marked?
Ensure the link is pointing to a codebase that is accessible (e.g. not a private repository). "[example.com](http://example.com/)", "n/a", "will add later", etc. are not acceptable links -- we need to see a public codebase. See the above section for accepted links.
### Useful Resources
- [Reproduction Guide](https://github.com/payloadcms/payload/blob/main/.github/reproduction-guide.md)
- [Contributing to Payload](https://www.youtube.com/watch?v=08Qa3ggR9rw)

View File

@@ -1,69 +0,0 @@
# docs: https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: github-actions
directories:
- /
- /.github/workflows
- /.github/actions/* # Not working until resolved: https://github.com/dependabot/dependabot-core/issues/6345
- /.github/actions/setup
target-branch: main
schedule:
interval: monthly
timezone: America/Detroit
time: '06:00'
groups:
github_actions:
patterns:
- '*'
- package-ecosystem: npm
directory: /
target-branch: main
open-pull-requests-limit: 0 # Only allow security updates
schedule:
interval: weekly
day: sunday
timezone: America/Detroit
time: '06:00'
commit-message:
prefix: 'chore(deps)'
labels:
- dependencies
groups:
production-deps:
dependency-type: production
update-types:
- minor
- patch
patterns:
- '*'
dev-deps:
dependency-type: development
update-types:
- minor
- patch
patterns:
- '*'
- package-ecosystem: npm
directory: /
target-branch: 2.x
open-pull-requests-limit: 0 # Only allow security updates
schedule:
interval: weekly
day: sunday
timezone: America/Detroit
time: '06:00'
commit-message:
prefix: 'chore(deps)'
labels:
- dependencies
groups:
production-deps:
dependency-type: production
update-types:
- patch
patterns:
- '*'

3976
.github/pnpm-lock.yaml generated vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
packages:
- 'actions/*'

View File

@@ -40,7 +40,7 @@ There are a couple ways run integration tests:
- **Granularly** - you can run individual tests in vscode by installing the Jest Runner plugin and using that to run individual tests. Clicking the `debug` button will run the test in debug mode allowing you to set break points.
<img src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/payload/src/assets/images/github/int-debug.png" />
<img src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/payload/src/admin/assets/images/github/int-debug.png" />
- **Manually** - you can run all int tests in the `/test/_community/int.spec.ts` file by running the following command:
@@ -57,7 +57,7 @@ The easiest way to run E2E tests is to install
Once they are installed you can open the `testing` tab in vscode sidebar and drill down to the test you want to run, i.e. `/test/_community/e2e.spec.ts`
<img src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/payload/src/assets/images/github/e2e-debug.png" />
<img src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/payload/src/admin/assets/images/github/e2e-debug.png" />
#### Notes

View File

@@ -1,116 +0,0 @@
name: label-on-change
on:
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
issues:
types:
- assigned
- closed
- labeled
- reopened
# TODO: Handle labeling on comment
jobs:
on-labeled-ensure-one-status:
runs-on: ubuntu-24.04
permissions:
issues: write
# Only run on issue labeled and if label starts with 'status:'
if: github.event.action == 'labeled' && startsWith(github.event.label.name, 'status:')
steps:
- name: Ensure only one status label
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
// Get all labels that start with 'status:' and are not the incoming label
const incomingLabelName = context.payload.label.name;
const labelNamesToRemove = context.payload.issue.labels
.filter(label => label.name.startsWith('status:') && label.name !== incomingLabelName)
.map(label => label.name);
if (!labelNamesToRemove.length) {
console.log('No labels to remove');
return;
}
console.log(`Labels to remove: '${labelNamesToRemove}'`);
// If there is more than one status label, remove all but the incoming label
for (const labelName of labelNamesToRemove) {
await github.rest.issues.removeLabel({
issue_number: context.issue.number,
name: labelName,
owner: context.repo.owner,
repo: context.repo.repo,
});
console.log(`Removed '${labelName}' label`);
}
on-issue-close:
runs-on: ubuntu-24.04
permissions:
issues: write
if: github.event.action == 'closed'
steps:
- name: Remove all labels on issue close
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
// Get all labels that start with 'status:' and 'stale'
const labelNamesToRemove = context.payload.issue.labels
.filter(label => label.name.startsWith('status:') || label.name === 'stale')
.map(label => label.name);
if (!labelNamesToRemove.length) {
console.log('No labels to remove');
return;
}
console.log(`Labels to remove: '${labelNamesToRemove}'`);
for (const labelName of labelNamesToRemove) {
await github.rest.issues.removeLabel({
issue_number: context.issue.number,
name: labelName,
owner: context.repo.owner,
repo: context.repo.repo,
});
console.log(`Removed '${labelName}' label`);
}
on-issue-reopen:
runs-on: ubuntu-24.04
permissions:
issues: write
if: github.event.action == 'reopened'
steps:
- name: Add needs-triage label on issue reopen
uses: actions-ecosystem/action-add-labels@v1
with:
labels: 'status: needs-triage'
on-issue-assigned:
runs-on: ubuntu-24.04
permissions:
issues: write
if: >
github.event.action == 'assigned' &&
contains(github.event.issue.labels.*.name, 'status: needs-triage')
steps:
- name: Remove needs-triage label on issue assign
uses: actions-ecosystem/action-remove-labels@v1
with:
labels: 'status: needs-triage'
# on-pr-merge:
# runs-on: ubuntu-24.04
# if: github.event.pull_request.merged == true
# steps:
# on-pr-close:
# runs-on: ubuntu-24.04
# if: github.event_name == 'pull_request_target' && github.event.pull_request.merged == false
# steps:

View File

@@ -1,26 +0,0 @@
name: lock-issues
on:
schedule:
# Run nightly at 12am EST
- cron: '0 4 * * *'
workflow_dispatch:
permissions:
issues: write
jobs:
lock_issues:
runs-on: ubuntu-24.04
steps:
- name: Lock issues
uses: dessant/lock-threads@v5
with:
process-only: 'issues'
issue-inactive-days: '1'
exclude-any-issue-labels: 'status: awaiting-reply'
log-output: true
issue-comment: >
This issue has been automatically locked.
Please open a new issue if this issue persists with any additional detail.

View File

@@ -2,33 +2,17 @@ name: build
on:
pull_request:
types:
- opened
- reopened
- synchronize
types: [ opened, reopened, synchronize ]
push:
branches:
- main
concurrency:
# <workflow_name>-<branch_name>-<true || commit_sha if branch is protected>
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref_protected && github.sha || ''}}
cancel-in-progress: true
env:
NODE_VERSION: 22.6.0
PNPM_VERSION: 9.7.1
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
branches: [ 'main' ]
jobs:
changes:
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
needs_build: ${{ steps.filter.outputs.needs_build }}
needs_tests: ${{ steps.filter.outputs.needs_tests }}
templates: ${{ steps.filter.outputs.templates }}
steps:
# https://github.com/actions/virtual-environments/issues/1187
@@ -36,7 +20,9 @@ jobs:
run: sudo ethtool -K eth0 tx off rx off
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
with:
fetch-depth: 25
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
@@ -46,60 +32,54 @@ jobs:
- 'test/**'
- 'pnpm-lock.yaml'
- 'package.json'
- 'templates/**'
needs_tests:
- '.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 "needs_tests: ${{ steps.filter.outputs.needs_tests }}"
echo "templates: ${{ steps.filter.outputs.templates }}"
lint:
if: >
github.event_name == 'pull_request' && !contains(github.event.pull_request.title, 'no-lint') && !contains(github.event.pull_request.title, 'skip-lint')
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Node setup
uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
pnpm-install-cache-key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Lint staged
run: |
git diff --name-only --diff-filter=d origin/${GITHUB_BASE_REF}...${GITHUB_SHA}
npx lint-staged --diff="origin/${GITHUB_BASE_REF}...${GITHUB_SHA}"
build:
core-build:
needs: changes
if: ${{ needs.changes.outputs.needs_build == 'true' }}
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Node setup
uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
pnpm-install-cache-key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
fetch-depth: 25
- run: pnpm run build:all
env:
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 8
run_install: false
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
- run: pnpm install
- run: pnpm run build
- name: Cache build
uses: actions/cache@v4
@@ -107,75 +87,13 @@ jobs:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
tests-unit:
runs-on: ubuntu-24.04
needs: [changes, build]
if: ${{ needs.changes.outputs.needs_tests == 'true' }}
steps:
- uses: actions/checkout@v4
- name: Node setup
uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
pnpm-run-install: false
pnpm-restore-cache: false # Full build is restored below
pnpm-install-cache-key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Restore build
uses: actions/cache@v4
with:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- name: Unit Tests
run: pnpm test:unit
env:
NODE_OPTIONS: --max-old-space-size=8096
tests-types:
runs-on: ubuntu-24.04
needs: [changes, build]
if: ${{ needs.changes.outputs.needs_tests == 'true' }}
steps:
- uses: actions/checkout@v4
- name: Node setup
uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
pnpm-run-install: false
pnpm-restore-cache: false # Full build is restored below
pnpm-install-cache-key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Restore build
uses: actions/cache@v4
with:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- name: Types Tests
run: pnpm test:types --target '>=5.7'
env:
NODE_OPTIONS: --max-old-space-size=8096
tests-int:
runs-on: ubuntu-24.04
needs: [changes, build]
if: ${{ needs.changes.outputs.needs_tests == 'true' }}
name: int-${{ matrix.database }}
tests:
runs-on: ubuntu-latest
needs: core-build
strategy:
fail-fast: false
matrix:
database:
- mongodb
- postgres
- postgres-custom-schema
- postgres-uuid
- supabase
- sqlite
database: [mongoose, postgres, postgres-custom-schema, postgres-uuid, supabase]
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
@@ -185,30 +103,21 @@ jobs:
AWS_SECRET_ACCESS_KEY: localstack
AWS_REGION: us-east-1
services:
postgres:
image: ${{ (startsWith(matrix.database, 'postgres') ) && 'postgis/postgis:16-3.4' || '' }}
env:
# must specify password for PG Docker container image, see: https://registry.hub.docker.com/_/postgres?tab=description&page=1&name=10
POSTGRES_USER: ${{ env.POSTGRES_USER }}
POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
POSTGRES_DB: ${{ env.POSTGRES_DB }}
ports:
- 5432:5432
# needed because the postgres container does not provide a healthcheck
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v4
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Node setup
uses: ./.github/actions/setup
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
pnpm-run-install: false
pnpm-restore-cache: false # Full build is restored below
pnpm-install-cache-key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
node-version: 20
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 8
run_install: false
- name: Restore build
uses: actions/cache@v4
@@ -219,6 +128,15 @@ jobs:
- name: Start LocalStack
run: pnpm docker:start
- name: Start PostgreSQL
uses: CasperWA/postgresql-action@v1.2
with:
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
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:
@@ -231,6 +149,10 @@ jobs:
supabase start
if: matrix.database == 'supabase'
- name: Wait for PostgreSQL
run: sleep 30
if: startsWith(matrix.database, 'postgres')
- name: Configure PostgreSQL
run: |
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "CREATE ROLE runner SUPERUSER LOGIN;"
@@ -248,75 +170,39 @@ jobs:
echo "POSTGRES_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres" >> $GITHUB_ENV
if: matrix.database == 'supabase'
- name: Component Tests
run: pnpm test:components
- name: Integration Tests
uses: nick-fields/retry@v3
run: pnpm test:int
env:
NODE_OPTIONS: --max-old-space-size=8096
PAYLOAD_DATABASE: ${{ matrix.database }}
POSTGRES_URL: ${{ env.POSTGRES_URL }}
with:
retry_on: any
max_attempts: 5
timeout_minutes: 15
command: pnpm test:int
on_retry_command: pnpm clean:build && pnpm install --no-frozen-lockfile
tests-e2e:
runs-on: ubuntu-24.04
needs: [changes, build]
if: ${{ needs.changes.outputs.needs_tests == 'true' }}
name: e2e-${{ matrix.suite }}
runs-on: ubuntu-latest
needs: core-build
strategy:
fail-fast: false
matrix:
# find test -type f -name 'e2e.spec.ts' | sort | xargs dirname | xargs -I {} basename {}
suite:
- _community
- access-control
- admin__e2e__1
- admin__e2e__2
- admin__e2e__3
- admin-root
- auth
- auth-basic
- field-error-states
- fields-relationship
- fields
- fields__collections__Blocks
- fields__collections__Array
- fields__collections__Relationship
- fields__collections__RichText
- fields__collections__Lexical__e2e__main
- fields__collections__Lexical__e2e__blocks
- fields__collections__Date
- fields__collections__Number
- fields__collections__Point
- fields__collections__Tabs
- fields__collections__Text
- fields__collections__Upload
- live-preview
- localization
- locked-documents
- i18n
- plugin-cloud-storage
- plugin-form-builder
- plugin-nested-docs
- plugin-seo
- versions
- uploads
env:
SUITE_NAME: ${{ matrix.suite }}
steps:
- uses: actions/checkout@v4
part: [ 1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 8/8 ]
- name: Node setup
uses: ./.github/actions/setup
steps:
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
pnpm-run-install: false
pnpm-restore-cache: false # Full build is restored below
pnpm-install-cache-key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
node-version: 20
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 8
run_install: false
- name: Restore build
uses: actions/cache@v4
@@ -324,154 +210,40 @@ jobs:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- name: Start LocalStack
run: pnpm docker:start
if: ${{ matrix.suite == 'plugin-cloud-storage' }}
- name: Store Playwright's Version
run: |
# Extract the version number using a more targeted regex pattern with awk
PLAYWRIGHT_VERSION=$(pnpm ls @playwright/test --depth=0 | awk '/@playwright\/test/ {print $2}')
echo "Playwright's Version: $PLAYWRIGHT_VERSION"
echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV
- name: Cache Playwright Browsers for Playwright's Version
id: cache-playwright-browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }}
- name: Setup Playwright - Browsers and Dependencies
if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
run: pnpm exec playwright install --with-deps chromium
- name: Setup Playwright - Dependencies-only
if: steps.cache-playwright-browsers.outputs.cache-hit == 'true'
run: pnpm exec playwright install-deps chromium
- name: E2E Tests
uses: nick-fields/retry@v3
uses: nick-fields/retry@v2
with:
retry_on: any
max_attempts: 5
timeout_minutes: 20
command: PLAYWRIGHT_JSON_OUTPUT_NAME=results_${{ matrix.suite }}.json pnpm test:e2e:prod:ci ${{ matrix.suite }}
on_retry_command: pnpm clean:build && pnpm install --no-frozen-lockfile && pnpm build:all
env:
PLAYWRIGHT_JSON_OUTPUT_NAME: results_${{ matrix.suite }}.json
NEXT_TELEMETRY_DISABLED: 1
retry_on: error
max_attempts: 2
timeout_minutes: 15
command: pnpm test:e2e --part ${{ matrix.part }} --bail
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v3
if: always()
with:
name: test-results-${{ matrix.suite }}
path: test/test-results/
if-no-files-found: ignore
name: test-results
path: test-results/
retention-days: 1
# Disabled until this is fixed: https://github.com/daun/playwright-report-summary/issues/156
# - uses: daun/playwright-report-summary@v3
# with:
# report-file: results_${{ matrix.suite }}.json
# report-tag: ${{ matrix.suite }}
# job-summary: true
# Build listed templates with packed local packages
build-templates:
runs-on: ubuntu-24.04
needs: build
strategy:
matrix:
include:
- template: blank
database: mongodb
- template: website
database: mongodb
- template: with-payload-cloud
database: mongodb
- template: with-vercel-mongodb
database: mongodb
# Postgres
- template: with-postgres
database: postgres
- template: with-vercel-postgres
database: postgres
# Re-enable once PG conncection is figured out
# - template: with-vercel-website
# database: postgres
name: ${{ matrix.template }}-${{ matrix.database }}
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: payloadtests
steps:
- uses: actions/checkout@v4
- name: Node setup
uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
pnpm-run-install: false
pnpm-restore-cache: false # Full build is restored below
pnpm-install-cache-key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Restore build
uses: actions/cache@v4
with:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- name: Start PostgreSQL
uses: CasperWA/postgresql-action@v1.2
with:
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
postgresql db: ${{ env.POSTGRES_DB }}
postgresql user: ${{ env.POSTGRES_USER }}
postgresql password: ${{ env.POSTGRES_PASSWORD }}
if: matrix.database == 'postgres'
- name: Wait for PostgreSQL
run: sleep 30
if: matrix.database == 'postgres'
- 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: matrix.database == 'postgres'
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.11.0
with:
mongodb-version: 6.0
- name: Build Template
run: |
pnpm run script:pack --dest templates/${{ matrix.template }}
pnpm runts scripts/build-template-with-local-pkgs.ts ${{ matrix.template }} $POSTGRES_URL
tests-type-generation:
runs-on: ubuntu-24.04
needs: [changes, build]
if: ${{ needs.changes.outputs.needs_tests == 'true' }}
steps:
- uses: actions/checkout@v4
runs-on: ubuntu-latest
needs: core-build
- name: Node setup
uses: ./.github/actions/setup
steps:
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
pnpm-run-install: false
pnpm-restore-cache: false # Full build is restored below
pnpm-install-cache-key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
node-version: 20
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 8
run_install: false
- name: Restore build
uses: actions/cache@v4
@@ -485,33 +257,124 @@ jobs:
- name: Generate GraphQL schema file
run: pnpm dev:generate-graphql-schema graphql-schema-gen
all-green:
name: All Green
if: always()
runs-on: ubuntu-24.04
needs:
- lint
- build
- build-templates
- tests-unit
- tests-int
- tests-e2e
- tests-types
- tests-type-generation
build-packages:
runs-on: ubuntu-latest
needs: core-build
strategy:
fail-fast: false
matrix:
pkg:
- db-mongodb
- db-postgres
- bundler-webpack
- bundler-vite
- richtext-slate
- richtext-lexical
- live-preview
- live-preview-react
steps:
- if: ${{ always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }}
run: exit 1
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
publish-canary:
name: Publish Canary
runs-on: ubuntu-24.04
if: ${{ needs.all-green.result == 'success' && github.ref_name == 'main' }}
needs:
- all-green
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 8
run_install: false
- name: Restore build
uses: actions/cache@v4
with:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- name: Build ${{ matrix.pkg }}
run: pnpm turbo run build --filter=${{ matrix.pkg }}
plugins:
runs-on: ubuntu-latest
needs: core-build
strategy:
fail-fast: false
matrix:
pkg:
- create-payload-app
- plugin-cloud
- plugin-cloud-storage
- plugin-form-builder
- plugin-nested-docs
- plugin-search
- plugin-sentry
- plugin-seo
steps:
# debug github.ref output
- run: |
echo github.ref: ${{ github.ref }}
echo isV3: ${{ github.ref == 'refs/heads/main' }}
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 8
run_install: false
- name: Restore build
uses: actions/cache@v4
with:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- name: Build ${{ matrix.pkg }}
run: pnpm turbo run build --filter=${{ matrix.pkg }}
- name: Test ${{ matrix.pkg }}
run: pnpm --filter ${{ matrix.pkg }} run test
if: matrix.pkg != 'create-payload-app' # degit doesn't work within GitHub Actions
templates:
needs: changes
if: ${{ needs.changes.outputs.templates == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
template: [ blank, website, ecommerce ]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 25
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0
with:
mongodb-version: 6.0
- name: Build Template
run: |
cd templates/${{ matrix.template }}
cp .env.example .env
yarn install
yarn build
yarn generate:types

View File

@@ -1,105 +0,0 @@
name: post-release-templates
on:
release:
types:
- published
workflow_dispatch:
env:
NODE_VERSION: 22.6.0
PNPM_VERSION: 9.7.1
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
jobs:
update_templates:
runs-on: ubuntu-24.04
permissions:
contents: write
pull-requests: write
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: payloadtests
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed for tags
- name: Setup
uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
- name: Start PostgreSQL
uses: CasperWA/postgresql-action@v1.2
with:
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
postgresql db: ${{ env.POSTGRES_DB }}
postgresql user: ${{ env.POSTGRES_USER }}
postgresql password: ${{ env.POSTGRES_PASSWORD }}
- name: Wait for PostgreSQL
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
echo "DATABASE_URI=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" >> $GITHUB_ENV
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.11.0
with:
mongodb-version: 6.0
- name: Update template lockfiles and migrations
run: pnpm script:gen-templates
- name: Determine Release Tag
id: determine_tag
run: |
if [ "${{ github.event_name }}" == "release" ]; then
echo "Using tag from release event: ${{ github.event.release.tag_name }}"
echo "release_tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
else
# pull latest tag from github, must match any version except v2. Should match v3, v4, v99, etc.
echo "Fetching latest tag from github..."
LATEST_TAG=$(git describe --tags --abbrev=0 --match 'v[0-9]*' --exclude 'v2*')
echo "Latest tag: $LATEST_TAG"
echo "release_tag=$LATEST_TAG" >> "$GITHUB_OUTPUT"
fi
- name: Commit and push changes
id: commit
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -ex
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git diff --name-only
export BRANCH_NAME=templates/bump-${{ steps.determine_tag.outputs.release_tag }}-$(date +%s)
echo "branch=$BRANCH_NAME" >> "$GITHUB_OUTPUT"
- name: Create pull request
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.GH_TOKEN_POST_RELEASE_TEMPLATES }}
labels: 'area: templates'
author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
commit-message: 'templates: bump templates for ${{ steps.determine_tag.outputs.release_tag }}'
branch: ${{ steps.commit.outputs.branch }}
base: main
assignees: ${{ github.actor }}
title: 'templates: bump for ${{ steps.determine_tag.outputs.release_tag }}'
body: |
🤖 Automated bump of templates for ${{ steps.determine_tag.outputs.release_tag }}
Triggered by user: @${{ github.actor }}

View File

@@ -1,52 +0,0 @@
name: post-release
on:
release:
types:
- published
workflow_dispatch:
inputs:
tag:
description: 'Release tag to process (optional)'
required: false
default: ''
env:
NODE_VERSION: 22.6.0
PNPM_VERSION: 9.7.1
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
jobs:
post_release:
runs-on: ubuntu-24.04
if: ${{ github.event_name != 'workflow_dispatch' }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/release-commenter
continue-on-error: true
env:
ACTIONS_STEP_DEBUG: true
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag-filter: 'v\d'
# Change to blank to disable commenting
# comment-template: ''
comment-template: |
🚀 This is included in version {release_link}
github-releases-to-discord:
runs-on: ubuntu-24.04
if: ${{ github.event_name != 'workflow_dispatch' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Github Releases To Discord
uses: SethCohen/github-releases-to-discord@v1.16.2
with:
webhook_url: ${{ secrets.DISCORD_RELEASES_WEBHOOK_URL }}
color: '16777215'
username: 'Payload Releases'
avatar_url: 'https://l4wlsi8vxy8hre4v.public.blob.vercel-storage.com/discord-bot-logo.png'

View File

@@ -1,117 +0,0 @@
name: pr-title
on:
pull_request_target:
types:
- opened
- edited
permissions:
pull-requests: write
jobs:
main:
name: lint-pr-title
runs-on: ubuntu-24.04
steps:
- uses: amannn/action-semantic-pull-request@v5
id: lint_pr_title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
build
chore
ci
docs
examples
feat
fix
perf
refactor
revert
style
templates
test
scopes: |
cpa
db-\*
db-mongodb
db-postgres
db-vercel-postgres
db-sqlite
drizzle
email-nodemailer
eslint
graphql
live-preview
live-preview-react
next
payload-cloud
plugin-cloud
plugin-cloud-storage
plugin-form-builder
plugin-nested-docs
plugin-redirects
plugin-search
plugin-sentry
plugin-seo
plugin-stripe
richtext-\*
richtext-lexical
richtext-slate
storage-\*
storage-azure
storage-gcs
storage-uploadthing
storage-vercel-blob
storage-s3
translations
ui
templates
examples(\/(\w|-)+)?
deps
# Disallow uppercase letters at the beginning of the subject
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}"
didn't match the configured pattern. Please ensure that the subject
doesn't start with an uppercase character.
- uses: marocchino/sticky-pull-request-comment@v2
# When the previous steps fails, the workflow would stop. By adding this
# condition you can continue the execution with the populated error message.
if: always() && (steps.lint_pr_title.outputs.error_message != null)
with:
header: pr-title-lint-error
message: |
Pull Request titles must follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and have valid scopes.
${{ steps.lint_pr_title.outputs.error_message }}
```
feat(ui): add Button component
^ ^ ^
| | |__ Subject
| |_______ Scope
|____________ Type
```
# Delete a previous comment when the issue has been resolved
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
uses: marocchino/sticky-pull-request-comment@v2
with:
header: pr-title-lint-error
delete: true
label-pr-on-open:
name: label-pr-on-open
runs-on: ubuntu-24.04
if: github.event.action == 'opened'
steps:
- name: Tag with 2.x branch with v2
if: github.event.pull_request.base.ref == '2.x'
uses: actions-ecosystem/action-add-labels@v1
with:
labels: v2

View File

@@ -3,33 +3,9 @@ name: release-canary
on:
workflow_dispatch:
env:
NODE_VERSION: 22.6.0
PNPM_VERSION: 9.7.1
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
jobs:
release:
name: release-canary-${{ github.ref_name }}-${{ github.sha }}
permissions:
id-token: write
runs-on: ubuntu-24.04
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup
uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
- name: Load npm token
run: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Canary release script
# dry run hard-coded to true for testing and no npm token provided
run: pnpm tsx ./scripts/publish-canary.ts
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
- name: Echo
run: echo "Register release-canary workflow"

View File

@@ -1,57 +0,0 @@
name: stale
on:
schedule:
# Run nightly at 1am EST
- cron: '0 5 * * *'
workflow_dispatch:
inputs:
dry-run:
description: Run the stale action in debug-only mode
default: false
required: false
type: boolean
jobs:
stale:
runs-on: ubuntu-24.04
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
id: stale
with:
debug-only: ${{ inputs.dry-run || false }}
days-before-stale: 23
days-before-close: 7
days-before-pr-close: -1 # Never close PRs
ascending: true
operations-per-run: 300
# Issues
stale-issue-label: stale
exempt-issue-labels: 'prioritized,keep,created-by: Payload team,created-by: Contributor,status: verified'
stale-issue-message: |
This issue has been marked as stale due to lack of activity.
To keep this issue open, please indicate that it is still relevant in a comment below.
close-issue-message: |
This issue was automatically closed due to lack of activity.
# Pull Requests
stale-pr-label: stale
exempt-pr-labels: 'prioritized,keep,created-by: Payload team,created-by: Contributor'
stale-pr-message: |
This PR is stale due to lack of activity.
To keep the PR open, please indicate that it is still relevant in a comment below.
close-pr-message: |
This pull request was automatically closed due to lack of activity.
# TODO: Add a step to notify team
- name: Print outputs
run: echo ${{ format('{0},{1}', toJSON(steps.stale.outputs.staled-issues-prs), toJSON(steps.stale.outputs.closed-issues-prs)) }}

View File

@@ -1,102 +0,0 @@
name: triage
on:
pull_request_target:
types:
- opened
issues:
types:
- opened
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
permissions:
contents: read
issues: write
pull-requests: write
jobs:
debug-context:
runs-on: ubuntu-24.04
steps:
- name: View context attributes
uses: actions/github-script@v7
with:
script: console.log({ context })
label-created-by:
name: label-on-open
runs-on: ubuntu-24.04
steps:
- name: Tag with 'created-by'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const payloadTeamUsernames = [
'denolfe',
'jmikrut',
'DanRibbens',
'jacobsfletch',
'JarrodMFlesch',
'AlessioGr',
'JessChowdhury',
'kendelljoseph',
'PatrikKozak',
'tylandavis',
'paulpopus',
'r1tsuu',
'GermanJablo',
];
const type = context.payload.pull_request ? 'pull_request' : 'issue';
const isTeamMember = payloadTeamUsernames
.map(n => n.toLowerCase())
.includes(context.payload[type].user.login.toLowerCase());
if (isTeamMember) {
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['created-by: Payload team'],
});
console.log(`Added 'created-by: Payload team' label`);
return;
}
const association = context.payload[type].author_association;
let label = ''
if (association === 'MEMBER' || association === 'OWNER') {
label = 'created-by: Payload team';
} else if (association === 'CONTRIBUTOR') {
label = 'created-by: Contributor';
}
if (!label) return;
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: [label],
});
console.log(`Added '${label}' label.`);
triage:
name: initial-triage
if: github.event_name == 'issues'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}
token: ${{ secrets.GITHUB_TOKEN }}
- uses: ./.github/actions/triage
with:
reproduction-comment: '.github/comments/invalid-reproduction.md'
reproduction-link-section: '### Link to the code that reproduces this issue(.*)### Reproduction Steps'
reproduction-issue-labels: 'validate-reproduction'
actions-to-perform: 'tag,comment'

36
.gitignore vendored
View File

@@ -3,34 +3,12 @@ package-lock.json
dist
/.idea/*
!/.idea/runConfigurations
!/.idea/payload.iml
# Custom actions
!.github/actions/**/dist
test/packed
test-results
.devcontainer
.localstack
/migrations
.localstack
.turbo
meta_client.json
meta_server.json
meta_index.json
meta_shared.json
.turbo
# Ignore test directory media folder/files
/media
test/media
*payloadtests.db
*payloadtests.db-journal
*payloadtests.db-shm
*payloadtests.db-wal
/versions
# 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
@@ -157,7 +135,6 @@ out
# Nuxt.js build / generate output
.nuxt
dist
dist_optimized
# Gatsby files
.cache/
@@ -304,16 +281,3 @@ $RECYCLE.BIN/
# End of https://www.toptal.com/developers/gitignore/api/node,macos,windows,webstorm,sublimetext,visualstudiocode
/build
.swc
app/(payload)/admin/importMap.js
test/live-preview/app/(payload)/admin/importMap.js
/test/live-preview/app/(payload)/admin/importMap.js
test/admin-root/app/(payload)/admin/importMap.js
/test/admin-root/app/(payload)/admin/importMap.js
test/app/(payload)/admin/importMap.js
/test/app/(payload)/admin/importMap.js
test/pnpm-lock.yaml
test/databaseAdapter.js
/filename-compound-index
/media-with-relation-preview
/media-without-relation-preview

View File

@@ -1 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm run lint-staged --quiet

87
.idea/payload.iml generated
View File

@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
<excludeFolder url="file://$MODULE_DIR$/packages/payload/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/payload/components" />
<excludeFolder url="file://$MODULE_DIR$/packages/payload/dist" />
<excludeFolder url="file://$MODULE_DIR$/.swc" />
<excludeFolder url="file://$MODULE_DIR$/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/examples" />
<excludeFolder url="file://$MODULE_DIR$/media" />
<excludeFolder url="file://$MODULE_DIR$/packages/create-payload-app/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/create-payload-app/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/db-mongodb/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/db-mongodb/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/db-postgres/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/db-postgres/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/graphql/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/graphql/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-react/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-react/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/next/.swc" />
<excludeFolder url="file://$MODULE_DIR$/packages/next/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/next/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/payload/fields" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud-storage/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud-storage/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-form-builder/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-nested-docs/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-nested-docs/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-redirects/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-redirects/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-search/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-search/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-sentry/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-seo/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-seo/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-stripe/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-lexical/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-lexical/dist" />
<excludeFolder url="file://$MODULE_DIR$/templates" />
<excludeFolder url="file://$MODULE_DIR$/test/.swc" />
<excludeFolder url="file://$MODULE_DIR$/versions" />
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-slate/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-slate/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/email-nodemailer/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/email-nodemailer/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/email-resend/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/email-resend/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-vue/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-vue/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/payload/.swc" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-form-builder/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-relationship-object-ids/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-relationship-object-ids/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-stripe/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-azure/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-azure/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-gcs/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-gcs/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-s3/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-s3/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-uploadthing/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-uploadthing/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-vercel-blob/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/storage-vercel-blob/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/translations/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/translations/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/ui/.swc" />
<excludeFolder url="file://$MODULE_DIR$/packages/ui/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/ui/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/drizzle/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/drizzle/dist" />
<excludeFolder url="file://$MODULE_DIR$/packages/db-sqlite/.turbo" />
<excludeFolder url="file://$MODULE_DIR$/packages/db-sqlite/dist" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -1,13 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Dev Fields" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="dev" />
</scripts>
<arguments value="fields" />
<node-interpreter value="project" />
<envs />
<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$">
<method v="2" />
</configuration>
</component>

View File

@@ -1,13 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Dev _community" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="dev" />
</scripts>
<arguments value="_community" />
<node-interpreter value="project" />
<envs />
<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$">
<method v="2" />
</configuration>
</component>

View File

@@ -1,13 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Dev admin" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="dev" />
</scripts>
<arguments value="admin" />
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@@ -1,9 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="true" type="JavaScriptTestRunnerJest">
<node-interpreter value="project" />
<node-options value="--no-deprecation" />
<envs />
<scope-kind value="ALL" />
<method v="2" />
</configuration>
</component>

View File

@@ -1 +1 @@
v22.6.0
v18.17.1

3
.npmrc
View File

@@ -1,3 +1,2 @@
symlink=true
node-linker=isolated
hoist-workspace-packages=false # the default in pnpm v9 is true, but that can break our runtime dependency checks
node-linker=isolated # due to a typescript bug, isolated mode requires @types/express-serve-static-core, terser and monaco-editor to be installed https://github.com/microsoft/TypeScript/issues/47663#issuecomment-1519138189 along with two other changes in the code which I've marked with (tsbugisolatedmode) in the code

2
.nvmrc
View File

@@ -1 +1 @@
v22.6.0
v18.17.1

View File

@@ -9,8 +9,3 @@
**/node_modules
**/temp
**/docs/**
tsconfig.json
packages/payload/*.js
packages/payload/*.d.ts
payload-types.ts
tsconfig.tsbuildinfo

16
.release-it.pre.js Normal file
View File

@@ -0,0 +1,16 @@
module.exports = {
verbose: true,
git: {
requireCleanWorkingDir: false,
commit: false,
push: false,
tag: false,
},
npm: {
skipChecks: true,
tag: 'beta',
},
hooks: {
'before:init': ['pnpm install', 'pnpm clean', 'pnpm build'],
},
}

24
.swcrc
View File

@@ -1,24 +0,0 @@
{
"$schema": "https://json.schemastore.org/swcrc",
"sourceMaps": "inline",
"jsc": {
"target": "esnext",
"parser": {
"syntax": "typescript",
"tsx": true,
"dts": true
},
"transform": {
"react": {
"runtime": "automatic",
"pragmaFrag": "React.Fragment",
"throwIfNamespace": true,
"development": false,
"useBuiltins": true
}
}
},
"module": {
"type": "es6"
}
}

View File

@@ -1,2 +0,0 @@
pnpm 9.7.1
nodejs 22.6.0

View File

@@ -1,8 +1,3 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"firsttris.vscode-jest-runner",
"ms-playwright.playwright"
]
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
}

107
.vscode/launch.json vendored
View File

@@ -3,73 +3,12 @@
// Hover to view descriptions of existing attributes.
"configurations": [
{
"command": "pnpm generate:types",
"name": "Generate Types CLI",
"request": "launch",
"type": "node-terminal",
"cwd": "${workspaceFolder}"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts _community",
"command": "pnpm run dev _community",
"cwd": "${workspaceFolder}",
"name": "Run Dev Community",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts storage-uploadthing",
"cwd": "${workspaceFolder}",
"name": "Uploadthing",
"request": "launch",
"type": "node-terminal",
"envFile": "${workspaceFolder}/test/storage-uploadthing/.env"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts live-preview",
"cwd": "${workspaceFolder}",
"name": "Run Dev Live Preview",
"request": "launch",
"type": "node-terminal"
},
{
"command": "node --no-deprecation test/loader/init.js",
"cwd": "${workspaceFolder}",
"name": "Run Loader",
"request": "launch",
"type": "node-terminal",
"env": {
"LOADER_TEST_FILE_PATH": "./dependency-test.js"
// "LOADER_TEST_FILE_PATH": "../fields/config.ts"
}
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts admin",
"cwd": "${workspaceFolder}",
"name": "Run Dev Admin",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts auth",
"cwd": "${workspaceFolder}",
"name": "Run Dev Auth",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts fields-relationship",
"cwd": "${workspaceFolder}",
"name": "Run Dev Fields-Relationship",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts login-with-username",
"cwd": "${workspaceFolder}",
"name": "Run Dev Login-With-Username",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm run dev plugin-cloud-storage",
"cwd": "${workspaceFolder}",
@@ -81,63 +20,56 @@
}
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts collections-graphql",
"command": "pnpm run dev collections-graphql",
"cwd": "${workspaceFolder}",
"name": "Run Dev GraphQL",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts fields",
"command": "pnpm run dev fields",
"cwd": "${workspaceFolder}",
"name": "Run Dev Fields",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts versions",
"command": "pnpm run dev:postgres fields",
"cwd": "${workspaceFolder}",
"name": "Run Dev Postgres",
"request": "launch",
"type": "node-terminal",
"env": {
"PAYLOAD_DATABASE": "postgres"
}
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts versions",
"command": "pnpm run dev versions",
"cwd": "${workspaceFolder}",
"name": "Run Dev Versions",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts localization",
"command": "pnpm run dev localization",
"cwd": "${workspaceFolder}",
"name": "Run Dev Localization",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts locked-documents",
"cwd": "${workspaceFolder}",
"name": "Run Dev Locked Documents",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts uploads",
"command": "pnpm run dev uploads",
"cwd": "${workspaceFolder}",
"name": "Run Dev Uploads",
"request": "launch",
"type": "node-terminal"
},
{
"command": "pnpm tsx --no-deprecation test/dev.ts field-error-states",
"command": "PAYLOAD_BUNDLER=vite pnpm run dev fields",
"cwd": "${workspaceFolder}",
"name": "Run Dev Field Error States",
"name": "Run Dev Fields (Vite)",
"request": "launch",
"type": "node-terminal"
"type": "node-terminal",
"env": {
"NODE_ENV": "production"
}
},
{
"command": "pnpm run test:int live-preview",
@@ -177,6 +109,17 @@
"request": "launch",
"type": "node-terminal"
},
{
"command": "ts-node ./packages/payload/src/bin/index.ts generate:types",
"env": {
"PAYLOAD_CONFIG_PATH": "test/_community/config.ts",
"DISABLE_SWC": "true" // SWC messes up debugging the bin scripts
},
"name": "Generate Types CLI",
"outputCapture": "std",
"request": "launch",
"type": "node-terminal"
},
{
"command": "ts-node ./packages/payload/src/bin/index.ts migrate:status",
"env": {

26
.vscode/settings.json vendored
View File

@@ -31,29 +31,9 @@
"editor.formatOnSave": true
},
"editor.formatOnSaveMode": "file",
"eslint.rules.customizations": [
// Defaultt all ESLint errors to 'warn' to differentate from TypeScript's 'error' level
{ "rule": "*", "severity": "warn" },
// Silence some warnings that will get auto-fixed
{ "rule": "perfectionist/*", "severity": "off", "fixable": true },
{ "rule": "curly", "severity": "off", "fixable": true },
{ "rule": "object-shorthand", "severity": "off", "fixable": true }
],
// All ESLint rules to 'warn' to differentate from TypeScript's 'error' level
"eslint.rules.customizations": [{ "rule": "*", "severity": "warn" }],
"typescript.tsdk": "node_modules/typescript/lib",
// Load .git-blame-ignore-revs file
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"],
"[javascript][typescript][typescriptreact]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
},
"files.insertFinalNewline": true,
"jestrunner.jestCommand": "pnpm exec cross-env NODE_OPTIONS=\"--no-deprecation\" node 'node_modules/jest/bin/jest.js'",
"jestrunner.debugOptions": {
"runtimeArgs": ["--no-deprecation"]
},
"search.exclude": {
"**/docs/V2_(excluded_from_search)/**": true
}
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"]
}

4720
CHANGELOG.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -63,7 +63,7 @@ Each test directory is split up in this way specifically to reduce friction when
The following command will start Payload with your config: `pnpm dev my-test-dir`. Example: `pnpm dev fields` for the test/`fields` test suite. This command will start up Payload using your config and refresh a test database on every restart. If you're using VS Code, the most common run configs are automatically added to your editor - you should be able to find them in your VS Code launch tab.
By default, payload will [automatically log you in](https://payloadcms.com/docs/authentication/overview#admin-autologin) with the default credentials. To disable that, you can either pass in the --no-auto-login flag (example: `pnpm dev my-test-dir --no-auto-login`) or set the `PAYLOAD_PUBLIC_DISABLE_AUTO_LOGIN` environment variable to `false`.
By default, payload will [automatically log you in](https://payloadcms.com/docs/authentication/config#admin-autologin) with the default credentials. To disable that, you can either pass in the --no-auto-login flag (example: `pnpm dev my-test-dir --no-auto-login`) or set the `PAYLOAD_PUBLIC_DISABLE_AUTO_LOGIN` environment variable to `false`.
The default credentials are `dev@payloadcms.com` as E-Mail and `test` as password. These are used in the auto-login.
@@ -116,25 +116,9 @@ For all Pull Requests, you should be extremely descriptive about both your probl
This is how you can preview changes you made locally to the docs:
1. Clone our [website repository](https://github.com/payloadcms/website) `git clone https://github.com/payloadcms/website.git && cd website`
2. Run `pnpm install`
3. Duplicate the `.env.example` file and rename it to `.env` (`cp .env.example .env`)
1. Clone our [website repository](https://github.com/payloadcms/website)
2. Run `yarn install`
3. Duplicate the `.env.example` file and rename it to `.env`
4. Add a `DOCS_DIR` environment variable to the `.env` file which points to the absolute path of your modified docs folder. For example `DOCS_DIR=/Users/yourname/Documents/GitHub/payload/docs`
5. Run `pnpm run fetchDocs:local`. If this was successful, you should see no error messages and the following output: _Docs successfully written to /.../website/src/app/docs.json_. There could be error messages if you have incorrect markdown in your local docs folder. In this case, it will tell you how you can fix it
6. You're done! Now you can start the website locally using `pnpm run dev` and preview the docs under [http://localhost:3000/docs/](http://localhost:3000/docs/)
## Internationalization (i18n)
If your PR adds a string to the UI, we need to make sure to translate it into all the languages that Payload supports. To do that:
- Find the appropriate internationalization file for your package. These are typically located in `packages/translations/src/languages`, although some packages (e.g., richtext-lexical) have separate i18n files for each feature.
- Add the string to the English locale "en".
- Translate it to other languages. You can use the `translateNewKeys` script if you have an OpenAI API key in your `.env` (under `OPENAI_KEY`), or you can use ChatGPT or Google translate - whatever is easier for you. For payload core translations (in packages/translations) you can run the `translateNewKeys` script using `cd packages/translations && pnpm translateNewKeys`. For lexical translations, you can run it using `cd packages/richtext-lexical && pnpm translateNewKeys`. External contributors can skip this step and leave it to us.
To display translation strings in the UI, make sure to use the `t` utility of the `useTranslation` hook:
```ts
const { t } = useTranslation()
// ...
t('yourStringKey')
```
5. Run `yarn run fetchDocs:local`. If this was successful, you should see no error messages and the following output: *Docs successfully written to /.../website/src/app/docs.json*. There could be error messages if you have incorrect markdown in your local docs folder. In this case, it will tell you how you can fix it
6. You're done! Now you can start the website locally using `yarn run dev` and preview the docs under [http://localhost:3000/docs/](http://localhost:3000/docs/)

View File

@@ -45,7 +45,7 @@ There are a couple ways to do this:
- **Granularly** - you can run individual tests in vscode by installing the Jest Runner plugin and using that to run individual tests. Clicking the `debug` button will run the test in debug mode allowing you to set break points.
<img src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/payload/src/assets/images/github/int-debug.png" />
<img src="https://raw.githubusercontent.com/payloadcms/payload/main/src/admin/assets/images/github/int-debug.png" />
- **Manually** - you can run all int tests in the `/test/_community/int.spec.ts` file by running the following command:
@@ -62,7 +62,7 @@ The easiest way to run E2E tests is to install
Once they are installed you can open the `testing` tab in vscode sidebar and drill down to the test you want to run, i.e. `/test/_community/e2e.spec.ts`
<img src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/payload/src/assets/images/github/e2e-debug.png" />
<img src="https://raw.githubusercontent.com/payloadcms/payload/main/src/admin/assets/images/github/e2e-debug.png" />
#### Notes

View File

@@ -1,60 +1,62 @@
<a href="https://payloadcms.com"><img width="100%" src="https://l4wlsi8vxy8hre4v.public.blob.vercel-storage.com/github-banner-new-logo.jpg" alt="Payload headless CMS Admin panel built with React" /></a>
<a href="https://payloadcms.com"><img width="100%" src="https://github.com/payloadcms/payload/blob/main/packages/payload/src/admin/assets/images/github-banner-alt.jpg?raw=true" alt="Payload headless CMS Admin panel built with React" /></a>
<br />
<br />
<p align="left">
<a href="https://github.com/payloadcms/payload/actions"><img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/payloadcms/payload/main.yml?style=flat-square"></a>
&nbsp;
<a href="https://discord.gg/payload"><img alt="Discord" src="https://img.shields.io/discord/967097582721572934?label=Discord&color=7289da&style=flat-square" /></a>
&nbsp;
<a href="https://www.npmjs.com/package/payload"><img alt="npm" src="https://img.shields.io/npm/dw/payload?style=flat-square" /></a>
&nbsp;
<a href="https://github.com/payloadcms/payload/graphs/contributors"><img alt="npm" src="https://img.shields.io/github/contributors-anon/payloadcms/payload?color=yellow&style=flat-square" /></a>
&nbsp;
<a href="https://www.npmjs.com/package/payload"><img alt="npm" src="https://img.shields.io/npm/v/payload?style=flat-square" /></a>
&nbsp;
<a href="https://twitter.com/payloadcms"><img src="https://img.shields.io/badge/follow-payloadcms-1DA1F2?logo=twitter&style=flat-square" alt="Payload Twitter" /></a>
</p>
<hr/>
<h4>
<a target="_blank" href="https://payloadcms.com/docs/getting-started/what-is-payload" rel="dofollow"><strong>Explore the Docs</strong></a>&nbsp;·&nbsp;<a target="_blank" href="https://payloadcms.com/community-help" rel="dofollow"><strong>Community Help</strong></a>&nbsp;·&nbsp;<a target="_blank" href="https://github.com/payloadcms/payload/discussions/1539" rel="dofollow"><strong>Roadmap</strong></a>&nbsp;·&nbsp;<a target="_blank" href="https://www.g2.com/products/payload-cms/reviews#reviews" rel="dofollow"><strong>View G2 Reviews</strong></a>
<a target="_blank" href="https://payloadcms.com/docs/getting-started/what-is-payload" rel="dofollow"><strong>Explore the Docs</strong></a>&nbsp;·&nbsp;<a target="_blank" href="https://payloadcms.com/community-help" rel="dofollow"><strong>Community Help</strong></a>&nbsp;·&nbsp;<a target="_blank" href="https://demo.payloadcms.com/" rel="dofollow"><strong>Try Live Demo</strong></a>&nbsp;·&nbsp;<a target="_blank" href="https://github.com/payloadcms/payload/discussions/1539" rel="dofollow"><strong>Roadmap</strong></a>&nbsp;·&nbsp;<a target="_blank" href="https://www.g2.com/products/payload-cms/reviews#reviews" rel="dofollow"><strong>View G2 Reviews</strong></a>
</h4>
<hr/>
> [!IMPORTANT]
> 🎉 <strong>We've released 3.0!</strong> Star this repo or keep an eye on it to follow along.
Payload is the first-ever Next.js native CMS that can install directly in your existing `/app` folder. It's the start of a new era for headless CMS.
> 🎉 <strong>Payload 3.0 beta released!</strong> You can now deploy Payload fully in any Next.js app folder. Read more in the <a target="_blank" href="https://payloadcms.com/blog/30-beta-install-payload-into-any-nextjs-app-with-one-line" rel="dofollow"><strong>announcement post</strong></a>.
<h3>Benefits over a regular CMS</h3>
<ul>
<li>Deploy anywhere, including serverless on Vercel for free</li>
<li>Combine your front+backend in the same <code>/app</code> folder if you want</li>
<li>Don't sign up for yet another SaaS - Payload is open source</li>
<li>Query your database in React Server Components</li>
<li>Both admin and backend are 100% extensible</li>
<li>Dont hit some third-party SaaS API, hit your own API</li>
<li>Use your own database and own your data</li>
<li>It's just Express - do what you want outside of Payload</li>
<li>No need to learn how Payload works - if you know JS, you know Payload</li>
<li>No vendor lock-in</li>
<li>Avoid microservices hell - get everything (even auth) in one place</li>
<li>Never touch ancient WP code again</li>
<li>Build faster, never hit a roadblock</li>
<li>Both admin and backend are 100% extensible</li>
</ul>
## Quickstart
## ☁️ Deploy instantly with Payload Cloud.
Create a cloud account, connect your GitHub, and [deploy in minutes](https://payloadcms.com/new).
## 🚀 Get started by self-hosting completely free, forever.
Before beginning to work with Payload, make sure you have all of the [required software](https://payloadcms.com/docs/getting-started/installation).
```text
pnpx create-payload-app@latest
npx create-payload-app@latest
```
**If you're new to Payload, you should start with the website template** (`pnpx create-payload-app@latest -t website`). It shows how to do _everything_ - including custom Rich Text blocks, on-demand revalidation, live preview, and more. It comes with a frontend built with Tailwind all in one `/app` folder.
Alternatively, it only takes about five minutes to [create an app from scratch](https://payloadcms.com/docs/getting-started/installation#from-scratch).
## One-click templates
## 🖱️ One-click templates
Jumpstart your next project by starting with a pre-made template. These are production-ready, end-to-end solutions designed to get you to market as fast as possible.
### [🛒 E-Commerce](https://github.com/payloadcms/payload/tree/main/templates/ecommerce)
Eliminate the need to combine Shopify and a CMS, and instead do it all with Payload + Stripe. Comes with a beautiful, fully functional front-end complete with shopping cart, checkout, orders, and much more.
### [🌐 Website](https://github.com/payloadcms/payload/tree/main/templates/website)
Build any kind of website, blog, or portfolio from small to enterprise. Comes with a fully functional front-end built with RSCs and Tailwind.
Build any kind of website, blog, or portfolio from small to enterprise. Comes with a beautiful, fully functional front-end complete with posts, projects, comments, and much more.
We're constantly adding more templates to our [Templates Directory](https://github.com/payloadcms/payload/tree/main/templates). If you maintain your own template, consider adding the `payload-template` topic to your GitHub repository for others to find.
@@ -64,19 +66,20 @@ We're constantly adding more templates to our [Templates Directory](https://gith
## ✨ Features
- Completely free and open-source
- Next.js native, built to run inside _your_ `/app` folder
- Use server components to extend Payload UI
- Query your database directly in server components, no need for REST / GraphQL
- Fully TypeScript with automatic types for your data
- [Auth out of the box](https://payloadcms.com/docs/authentication/overview)
- [Versions and drafts](https://payloadcms.com/docs/versions/overview)
- [Localization](https://payloadcms.com/docs/configuration/localization)
- [Block-based layout builder](https://payloadcms.com/docs/fields/blocks)
- [Customizable React admin](https://payloadcms.com/docs/admin/overview)
- [Lexical rich text editor](https://payloadcms.com/docs/fields/rich-text)
- [Conditional field logic](https://payloadcms.com/docs/fields/overview#conditional-logic)
- [GraphQL](https://payloadcms.com/docs/graphql/overview), [REST](https://payloadcms.com/docs/rest-api/overview), and [Local](https://payloadcms.com/docs/local-api/overview) APIs
- [Easily customizable ReactJS Admin](https://payloadcms.com/docs/admin/overview)
- [Fully self-hosted](https://payloadcms.com/docs/production/deployment)
- [Extensible Authentication](https://payloadcms.com/docs/authentication/overview)
- [Local file storage & upload](https://payloadcms.com/docs/upload/overview)
- [Version History and Drafts](https://payloadcms.com/docs/versions/overview)
- [Field-based Localization](https://payloadcms.com/docs/configuration/localization)
- [Block-based Layout Builder](https://payloadcms.com/docs/fields/blocks)
- [Extensible SlateJS rich text editor](https://payloadcms.com/docs/fields/rich-text)
- [Array field type](https://payloadcms.com/docs/fields/array)
- [Field conditional logic](https://payloadcms.com/docs/fields/overview#conditional-logic)
- Extremely granular [Access Control](https://payloadcms.com/docs/access-control/overview)
- [Document and field-level hooks](https://payloadcms.com/docs/hooks/overview) for every action Payload provides
- Built with Typescript & very Typescript-friendly
- Intensely fast API
- Highly secure thanks to HTTP-only cookies, CSRF protection, and more
@@ -86,7 +89,7 @@ We're constantly adding more templates to our [Templates Directory](https://gith
Check out the [Payload website](https://payloadcms.com/docs/getting-started/what-is-payload) to find in-depth documentation for everything that Payload offers.
Migrating from v2 to v3? Check out the [3.0 Migration Guide](https://github.com/payloadcms/payload/blob/main/docs/migration-guide/overview.mdx) on how to do it.
Migrating from v1 to v2? Check out the [2.0 Release Notes](https://github.com/payloadcms/payload/releases/tag/v2.0.0) on how to do it.
## 🙋 Contributing
@@ -96,10 +99,6 @@ If you want to add contributions to this repository, please follow the instructi
The [Examples Directory](./examples) is a great resource for learning how to setup Payload in a variety of different ways, but you can also find great examples in our blog and throughout our social media.
If you'd like to run the examples, you can either copy them to a folder outside this repo or run them directly by (1) navigating to the example's subfolder (`cd examples/your-example-folder`) and (2) using the `--ignore-workspace` flag to bypass workspace restrictions (e.g., `pnpm --ignore-workspace install` or `pnpm --ignore-workspace dev`).
You can see more examples at:
- [Examples Directory](./examples)
- [Payload Blog](https://payloadcms.com/blog)
- [Payload YouTube](https://www.youtube.com/@payloadcms)

View File

@@ -1,14 +0,0 @@
import React from 'react'
export const metadata = {
description: 'Generated by Next.js',
title: 'Next.js',
}
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}

View File

@@ -1,11 +0,0 @@
import configPromise from '@payload-config'
import { getPayloadHMR } from '@payloadcms/next/utilities'
export const Page = async ({ params, searchParams }) => {
const payload = await getPayloadHMR({
config: configPromise,
})
return <div>test ${payload?.config?.collections?.length}</div>
}
export default Page

View File

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

View File

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

View File

@@ -1,10 +0,0 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import config from '@payload-config'
import { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST } from '@payloadcms/next/routes'
export const GET = REST_GET(config)
export const POST = REST_POST(config)
export const DELETE = REST_DELETE(config)
export const PATCH = REST_PATCH(config)
export const OPTIONS = REST_OPTIONS(config)

View File

@@ -1,6 +0,0 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import config from '@payload-config'
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
export const GET = GRAPHQL_PLAYGROUND_GET(config)

View File

@@ -1,8 +0,0 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import config from '@payload-config'
import { GRAPHQL_POST, REST_OPTIONS } from '@payloadcms/next/routes'
export const POST = GRAPHQL_POST(config)
export const OPTIONS = REST_OPTIONS(config)

View File

@@ -1,32 +0,0 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
// import '@payloadcms/ui/styles.css' // Uncomment this line if `@payloadcms/ui` in `tsconfig.json` points to `/ui/dist` instead of `/ui/src`
import type { ServerFunctionClient } from 'payload'
import config from '@payload-config'
import { handleServerFunctions, RootLayout } from '@payloadcms/next/layouts'
import React from 'react'
import { importMap } from './admin/importMap.js'
import './custom.scss'
type Args = {
children: React.ReactNode
}
const serverFunction: ServerFunctionClient = async function (args) {
'use server'
return handleServerFunctions({
...args,
config,
importMap,
})
}
const Layout = ({ children }: Args) => (
<RootLayout config={config} importMap={importMap} serverFunction={serverFunction}>
{children}
</RootLayout>
)
export default Layout

View File

@@ -1,27 +0,0 @@
/* eslint-disable no-restricted-exports */
'use client'
import * as Sentry from '@sentry/nextjs'
import NextError from 'next/error.js'
import { useEffect } from 'react'
export default function GlobalError({ error }: { error: { digest?: string } & Error }) {
useEffect(() => {
if (process.env.NEXT_PUBLIC_SENTRY_DSN) {
Sentry.captureException(error)
}
}, [error])
return (
<html lang="en-US">
<body>
{/* `NextError` is the default Next.js error page component. Its type
definition requires a `statusCode` prop. However, since the App Router
does not expose status codes for errors, we simply pass 0 to render a
generic error message. */}
{/* @ts-expect-error types repo */}
<NextError statusCode={0} />
</body>
</html>
)
}

View File

@@ -1,5 +0,0 @@
export const GET = () => {
return Response.json({
hello: 'elliot',
})
}

39
changelog.config.js Normal file
View File

@@ -0,0 +1,39 @@
module.exports = {
// gitRawCommitsOpts: {
// from: 'v2.0.9',
// path: 'packages/payload',
// },
// infile: 'CHANGELOG.md',
options: {
preset: {
name: 'conventionalcommits',
types: [
{ section: 'Features', type: 'feat' },
{ section: 'Features', type: 'feature' },
{ section: 'Bug Fixes', type: 'fix' },
{ section: 'Documentation', type: 'docs' },
],
},
},
// outfile: 'NEW.md',
writerOpts: {
commitGroupsSort: (a, b) => {
const groupOrder = ['Features', 'Bug Fixes', 'Documentation']
return groupOrder.indexOf(a.title) - groupOrder.indexOf(b.title)
},
// Scoped commits at the end, alphabetical sort
commitsSort: (a, b) => {
if (a.scope || b.scope) {
if (!a.scope) return -1
if (!b.scope) return 1
return a.scope === b.scope
? a.subject.localeCompare(b.subject)
: a.scope.localeCompare(b.scope)
}
// Alphabetical sort
return a.subject.localeCompare(b.subject)
},
},
}

View File

@@ -0,0 +1,83 @@
---
title: Access Control
label: Overview
order: 10
desc: Payload makes it simple to define and manage access control. By declaring roles, you can set permissions and restrict what your users can interact with.
keywords: overview, access control, permissions, documentation, Content Management System, cms, headless, javascript, node, react, express
---
Access control within Payload is extremely powerful while remaining easy and intuitive to manage. Declaring who should have access to what documents is no more complex than writing a simple JavaScript function that either returns a `boolean` or a [`query`](/docs/queries/overview) constraint to restrict which documents users can interact with.
<YouTube id="DoPLyXG26Dg" title="Overview of Payload Access Control" />
**Example use cases:**
- Allowing anyone `read` access to all `Post`s
- Only allowing public access to `Post`s where a `status` field is equal to `published`
- Giving only `User`s with a `role` field equal to `admin` the ability to delete `Page`(s)
- Allowing anyone to create `ContactSubmission`s, but only logged in users to `read`, `update` or `delete` them
- Restricting a `User` to only be able to see their own `Order`(s), but no others
- Allowing `User`s that belong to a certain `Organization` to access only that `Organization`'s `Resource`s
### Default Settings
**By default, all Collections and Globals require that a user is logged in to be able to interact in any way.** The default Access Control function evaluates the `user` from the Express `req` and returns `true` if a user is logged in, and `false` if not.
**Default Access function:**
```ts
const defaultPayloadAccess = ({ req: { user } }) => {
// Return `true` if a user is found
// and `false` if it is undefined or null
return Boolean(user)
}
```
<Banner type="success">
<strong>Note:</strong>
<br />
In the Local API, all Access Control functions are skipped by default, allowing your server to do
whatever it needs. But, you can opt back in by setting the option <strong>
overrideAccess
</strong>{' '}
to <strong>false</strong>.
</Banner>
### Access Control Types
You can manage access within Payload on three different levels:
- [Collections](/docs/access-control/collections)
- [Fields](/docs/access-control/fields)
- [Globals](/docs/access-control/globals)
### When Access Control is Executed
<Banner type="success">
<strong>Note:</strong>
<br />
Access control functions are utilized in two places. It's important to understand how and when
your access control is executed.
</Banner>
#### As you execute operations
When you perform Payload operations like `create`, `read`, `update`, and `delete`, your access control functions will be executed before any changes or operations are completed.
#### Within the Admin UI
The Payload Admin UI responds dynamically to the access control that you define. For example, if you restrict editing a `ExampleCollection` to only users that feature a `role` of `admin`, the Payload Admin UI will **hide** the `ExampleCollection` from the Admin UI entirely. This is super powerful and allows you to control who can do what with your Admin UI.
To accomplish this, Payload ships with an `Access` operation, which is executed when a user logs into the Admin UI. Payload will execute each one of your access control functions, across all collections, globals, and fields, at the top level and return a response that contains a reflection of what the currently authenticated user can do with your application.
### Argument Availability
<Banner type="warning">
<strong>Important:</strong>
<br />
When your access control functions are executed via the <strong>access</strong> operation, the{' '}
<strong>id</strong> and <strong>data</strong> arguments will be <strong>undefined</strong>,
because Payload is executing your functions without referencing a specific document.
</Banner>
If you use `id` or `data` within your access control functions, make sure to check that they are defined first. If they are not, then you can assume that your access control is being executed via the `access` operation, to determine solely what the user can do within the Admin UI.

711
docs/admin/components.mdx Normal file
View File

@@ -0,0 +1,711 @@
---
title: Swap in your own React components
label: Custom Components
order: 20
desc: Fully customize your Admin Panel by swapping in your own React components. Add fields, remove views, update routes and change functions to sculpt your perfect Dashboard.
keywords: admin, components, custom, documentation, Content Management System, cms, headless, javascript, node, react, express
---
While designing the Payload Admin panel, we determined it should be as minimal and straightforward as possible to allow easy customization and control. There are many times where you may want to completely control how a whole view or a field works. You might even want to add in new views entirely. In order for Payload to support this level of customization without introducing versioning / future-proofing issues, Payload provides for a pattern to supply your own React components via your Payload config.
To swap in your own React component, first, consult the list of available component overrides below. Determine the scope that corresponds to what you are trying to accomplish, and then author your React component accordingly.
<Banner type="success">
<strong>Tip:</strong>
<br />
Custom components will automatically be provided with all props that the default component normally
accepts.
</Banner>
### Base Component Overrides
You can override a set of admin panel-wide components by providing a component to your base Payload config's `admin.components` property. The following options are available:
| Path | Description |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`Nav`** | Contains the sidebar / mobile menu in its entirety. |
| **`BeforeNavLinks`** | Array of components to inject into the built-in Nav, _before_ the links themselves. |
| **`AfterNavLinks`** | Array of components to inject into the built-in Nav, _after_ the links. |
| **`BeforeDashboard`** | Array of components to inject into the built-in Dashboard, _before_ the default dashboard contents. |
| **`AfterDashboard`** | Array of components to inject into the built-in Dashboard, _after_ the default dashboard contents. [Demo](https://github.com/payloadcms/payload/tree/main/test/admin/components/AfterDashboard/index.tsx) |
| **`BeforeLogin`** | Array of components to inject into the built-in Login, _before_ the default login form. |
| **`AfterLogin`** | Array of components to inject into the built-in Login, _after_ the default login form. |
| **`logout.Button`** | A custom React component. |
| **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. |
| **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. |
| **`providers`** | Define your own provider components that will wrap the Payload Admin UI. [More](#custom-providers) |
| **`actions`** | Array of custom components to be rendered in the Payload Admin UI header, providing additional interactivity and functionality. |
| **`views`** | Override or create new views within the Payload Admin UI. [More](#views) |
Here is a full example showing how to swap some of these components for your own.
`payload.config.js`
```ts
import { buildConfig } from 'payload/config'
import {
MyCustomNav,
MyCustomLogo,
MyCustomIcon,
MyCustomAccount,
MyCustomDashboard,
MyProvider,
MyCustomAdminAction,
} from './customComponents'
export default buildConfig({
admin: {
components: {
Nav: MyCustomNav,
graphics: {
Icon: MyCustomIcon,
Logo: MyCustomLogo,
},
actions: [MyCustomAdminAction],
views: {
Account: MyCustomAccount,
Dashboard: MyCustomDashboard,
},
providers: [MyProvider],
},
},
})
```
#### Views
You can easily swap entire views with your own by using the `admin.components.views` property. At the root level, Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| **`Account`** | The Account view is used to show the currently logged in user's Account page. |
| **`Dashboard`** | The main landing page of the Admin panel. |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. For example:
```ts
// payload.config.ts
{
// ...
admin: {
components: {
views: {
Account: MyCustomAccountView,
Dashboard: MyCustomDashboardView,
},
},
},
}
```
For more granular control, pass a configuration object instead. Each view corresponds to its own `<Route />` component in [React Router v5](https://v5.reactrouter.com). Payload exposes all of the properties of React Router:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| **`Component`** \* | Pass in the component that should be rendered when a user navigates to this route. |
| **`path`** \* | React Router `path`. [See the React Router docs](https://v5.reactrouter.com/web/api/Route/path-string-string) for more info. |
| **`exact`** | React Router `exact` property. [More](https://v5.reactrouter.com/web/api/Route/exact-bool) |
| **`strict`** | React Router `strict` property. [More](https://v5.reactrouter.com/web/api/Route/strict-bool) |
| **`sensitive`** | React Router `sensitive` property. [More](https://v5.reactrouter.com/web/api/Route/sensitive-bool) |
_\* An asterisk denotes that a property is required._
#### Adding new views
To add a _new_ view to the Admin Panel, simply add another key to the `views` object with at least a `path` and `Component` property. For example:
```ts
// payload.config.ts
{
// ...
admin: {
components: {
views: {
MyCustomView: {
Component: MyCustomView,
path: '/my-custom-view',
},
},
},
},
}
```
<Banner type="warning">
<strong>Note:</strong>
<br />
Routes are cascading. This means that unless explicitly given the `exact` property, they will match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all routes in your application. Alternatively, you could define your nested route _before_ your parent route.
</Banner>
_For more examples regarding how to customize components, look at the following [examples](https://github.com/payloadcms/payload/tree/main/test/admin/components)._
For help on how to build your own custom view components, see [building a custom view component](#building-a-custom-view-component).
### Collections
You can override components on a collection-by-collection basis via the `admin.components` property.
| Path | Description |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **`BeforeList`** | Array of components to inject _before_ the built-in List view |
| **`BeforeListTable`** | Array of components to inject _before_ the built-in List view's table |
| **`AfterList`** | Array of components to inject _after_ the built-in List view |
| **`AfterListTable`** | Array of components to inject _after_ the built-in List view's table |
| **`edit.SaveButton`** | Replace the default `Save` button with a custom component. Drafts must be disabled |
| **`edit.SaveDraftButton`** | Replace the default `Save Draft` button with a custom component. Drafts must be enabled and autosave must be disabled. |
| **`edit.PublishButton`** | Replace the default `Publish` button with a custom component. Drafts must be enabled. |
| **`edit.PreviewButton`** | Replace the default `Preview` button with a custom component. |
| **`views`** | Override or create new views within the Payload Admin UI. [More](#collection-views) |
Here is a full example showing how to swap some of these components for your own:
`Collection.ts`
```tsx
import * as React from 'react'
import {
CustomSaveButtonProps,
CustomSaveDraftButtonProps,
CustomPublishButtonType,
CustomPreviewButtonProps,
} from 'payload/types'
export const CustomSaveButton: CustomSaveButtonProps = ({ DefaultButton, label, save }) => {
return <DefaultButton label={label} save={save} />
}
export const CustomSaveDraftButton: CustomSaveDraftButtonProps = ({
DefaultButton,
disabled,
label,
saveDraft,
}) => {
return <DefaultButton label={label} disabled={disabled} saveDraft={saveDraft} />
}
export const CustomPublishButton: CustomPublishButtonType = ({
DefaultButton,
disabled,
label,
publish,
}) => {
return <DefaultButton label={label} disabled={disabled} publish={publish} />
}
export const CustomPreviewButton: CustomPreviewButtonProps = ({
DefaultButton,
disabled,
label,
preview,
}) => {
return <DefaultButton label={label} disabled={disabled} preview={preview} />
}
export const MyCollection: SanitizedCollectionConfig = {
slug: 'my-collection',
admin: {
components: {
edit: {
SaveButton: CustomSaveButton,
SaveDraftButton: CustomSaveDraftButton,
PublishButton: CustomPublishButton,
PreviewButton: CustomPreviewButton,
},
},
}
}
```
#### Collection views
To swap out entire views on collections, you can use the `admin.components.views` property on the collection's config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| **`Edit`** | The Edit view is used to edit a single document for a given collection. |
| **`List`** | The List view is used to show a list of documents for a given collection. |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, tabs, etc, _as well as all nested routes_.
```ts
// Collection.ts
{
// ...
admin: {
components: {
views: {
Edit: MyCustomEditView,
List: MyCustomListView,
},
},
},
}
```
_For help on how to build your own custom view components, see [building a custom view component](#building-a-custom-view-component)._
**Customizing Nested Views within 'Edit' in Collections**
The `Edit` view in collections consists of several nested views, each serving a unique purpose. You can customize these nested views using the `admin.components.views.Edit` property in the collection's configuration. This approach allows you to replace specific nested views while keeping the overall structure of the `Edit` view intact, including the page breadcrumbs, title, tabs, etc.
Here's an example of how you can customize nested views within the `Edit` view in collections, including the use of the `actions` property:
```ts
// Collection.ts
{
// ...
admin: {
components: {
views: {
Edit: {
Default: {
Component: MyCustomDefaultTab,
actions: [CollectionEditButton], // Custom actions for the default edit view
},
API: {
Component: MyCustomAPIView,
actions: [CollectionAPIButton], // Custom actions for API view
},
LivePreview: {
Component: MyCustomLivePreviewView,
actions: [CollectionLivePreviewButton], // Custom actions for Live Preview
},
Version: {
Component: MyCustomVersionView,
actions: [CollectionVersionButton], // Custom actions for Version view
},
Versions: {
Component: MyCustomVersionsView,
actions: [CollectionVersionsButton], // Custom actions for Versions view
},
},
List: {
actions: [CollectionListButton],
},
},
},
},
}
```
**Adding New Tabs to 'Edit' View**
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
### Globals
As with Collections, you can override components on a global-by-global basis via the `admin.components` property.
| Path | Description |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| **`elements.SaveButton`** | Replace the default `Save` button with a custom component. Drafts must be disabled |
| **`elements.SaveDraftButton`** | Replace the default `Save Draft` button with a custom component. Drafts must be enabled and autosave must be disabled. |
| **`elements.PublishButton`** | Replace the default `Publish` button with a custom component. Drafts must be enabled. |
| **`elements.PreviewButton`** | Replace the default `Preview` button with a custom component. |
| **`views`** | Override or create new views within the Payload Admin UI. [More](#global-views) |
#### Global views
To swap out views for globals, you can use the `admin.components.views` property on the global's config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| **`Edit`** | The Edit view is used to edit a single document for a given Global. |
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, and tabs, _as well as all nested views_.
```ts
// Global.ts
{
// ...
admin: {
components: {
views: {
Edit: MyCustomEditView,
},
},
},
}
```
_For help on how to build your own custom view components, see [building a custom view component](#building-a-custom-view-component)._
**Customizing Nested Views within 'Edit' in Globals**
Similar to collections, Globals allow for detailed customization within the `Edit` view. This includes the ability to swap specific nested views while maintaining the overall structure of the `Edit` view. You can use the `admin.components.views.Edit` property in the Globals configuration to achieve this, and this will only replace the nested view, leaving the page breadcrumbs, title, and tabs intact.
Here's how you can customize nested views within the `Edit` view in Globals, including the use of the `actions` property:
```ts
// Global.ts
{
// ...
admin: {
components: {
views: {
Edit: {
Default: {
Component: MyCustomGlobalDefaultTab,
actions: [GlobalEditButton], // Custom actions for the default edit view
},
API: {
Component: MyCustomGlobalAPIView,
actions: [GlobalAPIButton], // Custom actions for API view
},
LivePreview: {
Component: MyCustomGlobalLivePreviewView,
actions: [GlobalLivePreviewButton], // Custom actions for Live Preview
},
Version: {
Component: MyCustomGlobalVersionView,
actions: [GlobalVersionButton], // Custom actions for Version view
},
Versions: {
Component: MyCustomGlobalVersionsView,
actions: [GlobalVersionsButton], // Custom actions for Versions view
},
},
},
},
},
}
```
You can also add _new_ tabs to the `Edit` view by adding another key to the `components.views.Edit[key]` object with a `path` and `Component` property. See [Custom Tabs](#custom-tabs) for more information.
### Custom Tabs
You can easily swap individual collection or global edit views. To do this, pass an _object_ to the `admin.components.views.Edit` property of the config. Payload renders the following views by default, all of which can be overridden:
| Property | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| **`Default`** | The Default view is the primary view in which your document is edited. |
| **`Versions`** | The Versions view is used to view the version history of a single document. [More details](../versions) |
| **`Version`** | The Version view is used to view a single version of a single document for a given collection. [More details](../versions). |
| **`API`** | The API view is used to display the REST API JSON response for a given document. |
| **`LivePreview`** | The LivePreview view is used to display the Live Preview interface. [More details](../live-preview) |
Here is an example:
```ts
// Collection.ts or Global.ts
export const MyCollection: SanitizedCollectionConfig = {
slug: 'my-collection',
admin: {
components: {
views: {
Edit: { // You can also define `components.views.Edit` as a component, this will override _all_ nested views
Default: MyCustomDefaultTab,
Versions: MyCustomVersionsTab,
Version: MyCustomVersionTab,
API: MyCustomAPITab,
LivePreview: MyCustomLivePreviewTab,
},
},
},
},
}
```
To add a _new_ tab to the `Edit` view, simply add another key to `components.views.Edit[key]` with at least a `path` and `Component` property. For example:
```ts
// `Collection.ts` or `Global.ts`
export const MyCollection: SanitizedCollectionConfig = {
slug: 'my-collection',
admin: {
components: {
views: {
Edit: {
MyCustomTab: {
Component: MyCustomTab,
path: '/my-custom-tab',
// You an swap the entire tab component out for your own
Tab: MyCustomTab
},
AnotherCustomView: {
Component: AnotherCustomView,
path: '/another-custom-view',
// Or you can use the default tab component and just pass in your own label and href
Tab: {
label: 'Another Custom View',
href: '/another-custom-view',
}
},
},
},
},
},
}
```
### Building a custom view component
Your custom view components will be given all the props that a React Router `<Route />` typically would receive, as well as two props from Payload:
| Prop | Description |
| ----------------------- | ---------------------------------------------------------------------------- |
| **`user`** | The currently logged in user. Will be `null` if no user is logged in. |
| **`canAccessAdmin`** \* | If the currently logged in user is allowed to access the admin panel or not. |
<Banner type="warning">
<strong>Note:</strong>
<br />
It's up to you to secure your custom views. If your view requires a user to be logged in or to
have certain access rights, you should handle that within your view component yourself.
</Banner>
#### Example
You can find examples of custom views in the [Payload source code `/test/admin/components/views` folder](https://github.com/payloadcms/payload/tree/main/test/admin/components/views). There, you'll find two custom views:
1. A custom view that uses the `DefaultTemplate`, which is the built-in Payload template that displays the sidebar and "eyebrow nav"
1. A custom view that uses the `MinimalTemplate` - which is just a centered template used for things like logging in or out
To see how to pass in your custom views to create custom views of your own, take a look at the `admin.components.views` property of the [Payload test admin config](https://github.com/payloadcms/payload/blob/main/test/admin/config.ts).
### Fields
All Payload fields support the ability to swap in your own React components. So, for example, instead of rendering a default Text input, you might need to render a color picker that provides the editor with a custom color picker interface to restrict the data entered to colors only.
<Banner type="success">
<strong>Tip:</strong>
<br />
Don't see a built-in field type that you need? Build it! Using a combination of custom validation
and custom components, you can override the entirety of how a component functions within the admin
panel and effectively create your own field type.
</Banner>
**Fields support the following custom components:**
| Component | Description |
| ------------ | --------------------------------------------------------------------------------------------------------------------------- |
| **`Filter`** | Override the text input that is presented in the `List` view when a user is filtering documents by the customized field. |
| **`Cell`** | Used in the `List` view's table to represent a table-based preview of the data stored in the field. [More](#cell-component) |
| **`Field`** | Swap out the field itself within all `Edit` views. [More](#field-component) |
As an alternative to replacing the entire Field component, you may want to keep the majority of the default Field component and only swap components within. This allows you to replace the **`Label`** or **`Error`** within a field component or add additional components inside the field with **`beforeInput`** or **`afterInput`**. **`beforeInput`** and **`afterInput`** are allowed in any fields that don't contain other fields, except [UI](/docs/fields/ui) and [Rich Text](/docs/fields/rich-text).
| Component | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
| **`Label`** | Override the default Label in the Field Component. [More](#label-component) |
| **`Error`** | Override the default Label in the Field Component. [More](#error-component) |
| **`beforeInput`** | An array of elements that will be added before `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
| **`afterInput`** | An array of elements that will be added after `input`/`textarea` elements. [More](#afterinput-and-beforeinput) |
## Cell Component
These are the props that will be passed to your custom Cell to use in your own components.
| Property | Description |
| ---------------- | ----------------------------------------------------------------- |
| **`field`** | An object that includes the field configuration. |
| **`colIndex`** | A unique number for the column in the list. |
| **`collection`** | An object with the config of the collection that the field is in. |
| **`cellData`** | The data for the field that the cell represents. |
| **`rowData`** | An object with all the field values for the row. |
#### Example
```tsx
import React from 'react'
import type { Props } from 'payload/components/views/Cell'
import './index.scss'
const baseClass = 'custom-cell'
const CustomCell: React.FC<Props> = (props) => {
const { field, colIndex, collection, cellData, rowData } = props
return <span className={baseClass}>{cellData}</span>
}
```
## Field Component
When writing your own custom components you can make use of a number of hooks to set data, get reactive changes to other fields, get the id of the document or interact with a context from a custom provider.
### Sending and receiving values from the form
When swapping out the `Field` component, you'll be responsible for sending and receiving the field's `value` from the form itself. To do so, import the `useField` hook as follows:
```tsx
import { useField } from 'payload/components/forms'
const CustomTextField: React.FC<{ path: string }> = ({ path }) => {
// highlight-start
const { value, setValue } = useField<string>({ path })
// highlight-end
return <input onChange={(e) => setValue(e.target.value)} value={value} />
}
```
<Banner type="success">
For more information regarding the hooks that are available to you while you build custom
components, including the <strong>useField</strong> hook, [click here](/docs/admin/hooks).
</Banner>
## Label Component
These are the props that will be passed to your custom Label.
| Property | Description |
| ---------------- | ---------------------------------------------------------------- |
| **`htmlFor`** | Property used to set `for` attribute for label. |
| **`label`** | Label value provided in field, it can be used with i18n. |
| **`required`** | A boolean value that represents if the field is required or not. |
#### Example
```tsx
import React from 'react'
import { useTranslation } from 'react-i18next'
import { getTranslation } from 'payload/utilities/getTranslation'
type Props = {
htmlFor?: string
label?: Record<string, string> | false | string
required?: boolean
}
const CustomLabel: React.FC<Props> = (props) => {
const { htmlFor, label, required = false } = props
const { i18n } = useTranslation()
if (label) {
return (<span>
{getTranslation(label, i18n)}
{required && <span className="required">*</span>}
</span>);
}
return null
}
```
## Error Component
These are the props that will be passed to your custom Error.
| Property | Description |
| ---------------- | ------------------------------------------------------------- |
| **`message`** | The error message. |
| **`showError`** | A boolean value that represents if the error should be shown. |
#### Example
```tsx
import React from 'react'
type Props = {
message: string
showError?: boolean
}
const CustomError: React.FC<Props> = (props) => {
const { message, showError } = props
if (showError) {
return <p style={{color: 'red'}}>{message}</p>
} else return null;
}
```
## afterInput and beforeInput
With these properties you can add multiple components before and after the input element. For example, you can add an absolutely positioned button to clear the current field value.
#### Example
```tsx
import React from 'react'
import { Field } from 'payload/types'
import './style.scss'
const ClearButton: React.FC = () => {
return <button onClick={() => {/* ... */}}>X</button>
}
const titleField: Field = {
name: 'title',
type: 'text',
admin: {
components: {
afterInput: [ClearButton]
}
}
}
export default titleField;
```
## Custom providers
As your admin customizations gets more complex you may want to share state between fields or other components. You can add custom providers to do add your own context to any Payload app for use in other custom components within the admin panel. Within your config add `admin.components.providers`, these can be used to share context or provide other custom functionality. Read the [React context](https://reactjs.org/docs/context.html) docs to learn more.
<Banner type="warning">
<strong>Reminder:</strong> Don't forget to pass the **children** prop through the provider
component for the admin UI to show
</Banner>
### Styling Custom Components
Payload exports its SCSS variables and mixins for reuse in your own custom components. This is helpful in cases where you might want to style a custom input similarly to Payload's built-in styling, so it blends more thoroughly into the existing admin UI.
To make use of Payload SCSS variables / mixins to use directly in your own components, you can import them as follows:
```
@import '~payload/scss';
```
### Getting the current language
When developing custom components you can support multiple languages to be consistent with Payload's i18n support. The best way to do this is to add your translation resources to the [i18n configuration](https://payloadcms.com/docs/configuration/i18n) and import `useTranslation` from `react-i18next` in your components.
For example:
```tsx
import { useTranslation } from 'react-i18next'
const CustomComponent: React.FC = () => {
// highlight-start
const { t, i18n } = useTranslation('namespace1')
// highlight-end
return (
<ul>
<li>{t('key', { variable: 'value' })}</li>
<li>{t('namespace2:key', { variable: 'value' })}</li>
<li>{i18n.language}</li>
</ul>
)
}
```
### Getting the current locale
In any custom component you can get the selected locale with `useLocale` hook. `useLocale` returns the full locale object, consisting of a `label`, `rtl`(right-to-left) property, and then `code`. Here is a simple example:
```tsx
import { useLocale } from 'payload/components/utilities'
const Greeting: React.FC = () => {
// highlight-start
const locale = useLocale()
// highlight-end
const trans = {
en: 'Hello',
es: 'Hola',
}
return <span> {trans[locale.code]} </span>
}
```

View File

@@ -0,0 +1,405 @@
---
title: Authentication Operations
label: Operations
order: 30
desc: Enabling Authentication automatically makes key operations available such as Login, Logout, Verify, Unlock, Reset Password and more.
keywords: authentication, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
---
Enabling Authentication on a Collection automatically exposes additional auth-based operations in the Local, REST, and GraphQL APIs.
### Access
The Access operation returns what a logged in user can and can't do with the collections and globals that are registered via your config. This data can be immensely helpful if your app needs to show and hide certain features based on access control, as the Payload Admin panel does.
**REST API endpoint**:
`GET http://localhost:3000/api/access`
Example response:
```ts
{
canAccessAdmin: true,
collections: {
pages: {
create: {
permission: true,
},
read: {
permission: true,
},
update: {
permission: true,
},
delete: {
permission: true,
},
fields: {
title: {
create: {
permission: true,
},
read: {
permission: true,
},
update: {
permission: true,
},
}
}
}
}
}
```
**Example GraphQL Query**:
```graphql
query {
Access {
pages {
read {
permission
}
}
}
}
```
Document access can also be queried on a collection/global basis. Access on a global can queried like `http://localhost:3000/api/global-slug/access`, Collection document access can be queried like `http://localhost:3000/api/collection-slug/access/:id`.
### Me
Returns either a logged in user with token or null when there is no logged in user.
**REST API endpoint**:
`GET http://localhost:3000/api/[collection-slug]/me`
Example response:
```ts
{
user: { // The JWT "payload" ;) from the logged in user
email: 'dev@payloadcms.com',
createdAt: "2020-12-27T21:16:45.645Z",
updatedAt: "2021-01-02T18:37:41.588Z",
id: "5ae8f9bde69e394e717c8832"
},
token: '34o4345324...', // The token that can be used to authenticate the user
exp: 1609619861, // Unix timestamp representing when the user's token will expire
}
```
**Example GraphQL Query**:
```graphql
query {
me[collection-singular-label] {
user {
email
}
exp
}
}
```
### Login
Accepts an `email` and `password`. On success, it will return the logged in user as well as a token that can be used to authenticate. In the GraphQL and REST APIs, this operation also automatically sets an HTTP-only cookie including the user's token. If you pass an Express `res` to the Local API operation, Payload will set a cookie there as well.
**Example REST API login**:
```ts
const res = await fetch('http://localhost:3000/api/[collection-slug]/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'dev@payloadcms.com',
password: 'this-is-not-our-password...or-is-it?',
}),
})
const json = await res.json()
// JSON will be equal to the following:
/*
{
user: {
email: 'dev@payloadcms.com',
createdAt: "2020-12-27T21:16:45.645Z",
updatedAt: "2021-01-02T18:37:41.588Z",
id: "5ae8f9bde69e394e717c8832"
},
token: '34o4345324...',
exp: 1609619861
}
*/
```
**Example GraphQL Mutation**:
```graphql
mutation {
login[collection-singular-label](email: "dev@payloadcms.com", password: "yikes") {
user {
email
}
exp
token
}
}
```
**Example Local API login**:
```ts
const result = await payload.login({
collection: '[collection-slug]',
data: {
email: 'dev@payloadcms.com',
password: 'get-out',
},
})
```
### Logout
As Payload sets HTTP-only cookies, logging out cannot be done by just removing a cookie in JavaScript, as HTTP-only cookies are inaccessible by JS within the browser. So, Payload exposes a `logout` operation to delete the token in a safe way.
**Example REST API logout**:
```ts
const res = await fetch('http://localhost:3000/api/[collection-slug]/logout', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
```
**Example GraphQL Mutation**:
```
mutation {
logout[collection-singular-label]
}
```
### Refresh
Allows for "refreshing" JWTs. If your user has a token that is about to expire, but the user is still active and using the app, you might want to use the `refresh` operation to receive a new token by sending the operation the token that is about to expire.
This operation requires a non-expired token to send back a new one. If the user's token has already expired, you will need to allow them to log in again to retrieve a new token.
If successful, this operation will automatically renew the user's HTTP-only cookie and will send back the updated token in JSON.
**Example REST API token refresh**:
```ts
const res = await fetch('http://localhost:3000/api/[collection-slug]/refresh-token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
const json = await res.json()
// JSON will be equal to the following:
/*
{
user: {
email: 'dev@payloadcms.com',
createdAt: "2020-12-27T21:16:45.645Z",
updatedAt: "2021-01-02T18:37:41.588Z",
id: "5ae8f9bde69e394e717c8832"
},
refreshedToken: '34o4345324...',
exp: 1609619861
}
*/
```
**Example GraphQL Mutation**:
```
mutation {
refreshToken[collection-singular-label] {
user {
email
}
refreshedToken
}
}
```
<Banner type="success">
The Refresh operation will automatically find the user's token in either a JWT header or the
HTTP-only cookie. But, you can specify the token you're looking to refresh by providing the REST
API with a `token` within the JSON body of the request, or by providing the GraphQL resolver a
`token` arg.
</Banner>
### Verify by Email
If your collection supports email verification, the Verify operation will be exposed which accepts a verification token and sets the user's `_verified` property to `true`, thereby allowing the user to authenticate with the Payload API.
**Example REST API user verification**:
```ts
const res = await fetch(`http://localhost:3000/api/[collection-slug]/verify/${TOKEN_HERE}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
```
**Example GraphQL Mutation**:
```graphql
mutation {
verifyEmail[collection-singular-label](token: "TOKEN_HERE")
}
```
**Example Local API verification**:
```ts
const result = await payload.verifyEmail({
collection: '[collection-slug]',
token: 'TOKEN_HERE',
})
```
### Unlock
If a user locks themselves out and you wish to deliberately unlock them, you can utilize the Unlock operation. The Admin panel features an Unlock control automatically for all collections that feature max login attempts, but you can programmatically unlock users as well by using the Unlock operation.
To restrict who is allowed to unlock users, you can utilize the [`unlock`](/docs/access-control/overview#unlock) access control function.
**Example REST API unlock**:
```ts
const res = await fetch(`http://localhost:3000/api/[collection-slug]/unlock`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
```
**Example GraphQL Mutation**:
```
mutation {
unlock[collection-singular-label]
}
```
**Example Local API unlock**:
```ts
const result = await payload.unlock({
collection: '[collection-slug]',
})
```
### Forgot Password
Payload comes with built-in forgot password functionality. Submitting an email address to the Forgot Password operation will generate an email and send it to the respective email address with a link to reset their password.
The link to reset the user's password contains a token which is what allows the user to securely reset their password.
By default, the Forgot Password operations send users to the Payload Admin panel to reset their password, but you can customize the generated email to send users to the frontend of your app instead by [overriding the email HTML](/docs/authentication/config#forgot-password).
**Example REST API Forgot Password**:
```ts
const res = await fetch(`http://localhost:3000/api/[collection-slug]/forgot-password`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'dev@payloadcms.com',
}),
})
```
**Example GraphQL Mutation**:
```
mutation {
forgotPassword[collection-singular-label](email: "dev@payloadcms.com")
}
```
**Example Local API forgot password**:
```ts
const token = await payload.forgotPassword({
collection: '[collection-slug]',
data: {
email: 'dev@payloadcms.com',
},
disableEmail: false, // you can disable the auto-generation of email via local API
})
```
<Banner type="success">
<strong>Tip:</strong>
<br />
You can stop the reset-password email from being sent via using the local API. This is helpful if
you need to create user accounts programmatically, but not set their password for them. This
effectively generates a reset password token which you can then use to send to a page you create,
allowing a user to "complete" their account by setting their password. In the background, you'd
use the token to "reset" their password.
</Banner>
### Reset Password
After a user has "forgotten" their password and a token is generated, that token can be used to send to the reset password operation along with a new password which will allow the user to reset their password securely.
**Example REST API Reset Password**:
```ts
const res = await fetch(`http://localhost:3000/api/[collection-slug]/reset-password`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
token: 'TOKEN_GOES_HERE'
password: 'not-today',
}),
});
const json = await res.json();
// JSON will be equal to the following:
/*
{
user: {
email: 'dev@payloadcms.com',
createdAt: "2020-12-27T21:16:45.645Z",
updatedAt: "2021-01-02T18:37:41.588Z",
id: "5ae8f9bde69e394e717c8832"
},
token: '34o4345324...',
exp: 1609619861
}
*/
```
**Example GraphQL Mutation**:
```graphql
mutation {
resetPassword[collection-singular-label](token: "TOKEN_GOES_HERE", password: "not-today")
}
```

View File

@@ -0,0 +1,235 @@
---
title: Collection Configs
label: Collections
order: 20
desc: Structure your Collections for your needs by defining fields, adding slugs and labels, establishing access control, tying in hooks, setting timestamps and more.
keywords: collections, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
---
Payload Collections are defined through configs of their own, and you can define as many as your application needs. Each
Collection will scaffold a new collection automatically in your database of choice, based on fields that you define.
It's often best practice to write your Collections in separate files and then import them into the main Payload config.
## Options
| Option | Description |
|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-options). |
| **`hooks`** | Entry points to "tie in" to Collection actions at specific points. [More](/docs/hooks/overview#collection-hooks) |
| **`access`** | Provide access control functions to define exactly who should be able to do what with Documents in this Collection. [More](/docs/access-control/overview/#collections) |
| **`auth`** | Specify options if you would like this Collection to feature authentication. For more, consult the [Authentication](/docs/authentication/config) documentation. |
| **`upload`** | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](/docs/upload/overview) documentation. |
| **`timestamps`** | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. |
| **`versions`** | Set to true to enable default options, or configure with object properties. [More](/docs/versions/overview#collection-config) |
| **`endpoints`** | Add custom routes to the REST API. Set to `false` to disable routes. [More](/docs/rest-api/overview#custom-endpoints) |
| **`graphQL`** | An object with `singularName` and `pluralName` strings used in schema generation. Auto-generated from slug if not defined. Set to `false` to disable GraphQL. |
| **`typescript`** | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
| **`defaultSort`** | Pass a top-level field to sort by default in the collection List view. Prefix the name of the field with a minus symbol ("-") to sort in descending order. |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`dbName`** | Custom table or collection name depending on the database adapter. Auto-generated from slug if not defined.
_\* An asterisk denotes that a property is required._
#### Simple collection example
```ts
import { CollectionConfig } from 'payload/types'
export const Orders: CollectionConfig = {
slug: 'orders',
fields: [
{
name: 'total',
type: 'number',
required: true,
},
{
name: 'placedBy',
type: 'relationship',
relationTo: 'customers',
required: true,
},
],
}
```
#### More collection config examples
You can find an assortment
of [example collection configs](https://github.com/payloadcms/public-demo/tree/master/src/payload/collections) in the
Public
Demo source code on GitHub.
### Admin options
You can customize the way that the Admin panel behaves on a collection-by-collection basis by defining the `admin`
property on a collection's config.
| Option | Description |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this collection from navigation and admin routing. |
| `hooks` | Admin-specific hooks for this collection. [More](#admin-hooks) |
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin panel. If no field is defined, the ID of the document is used as the title. |
| `description` | Text or React component to display below the Collection label in the List view to give editors more information. |
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this collection's List view. |
| `disableDuplicate ` | Disables the "Duplicate" button while editing documents within this collection. |
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
| `enableRichTextLink` | The [Rich Text](/docs/fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| `enableRichTextRelationship` | The [Rich Text](/docs/fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
| `preview` | Function to generate preview URLS within the Admin panel that can point to your app. [More](#preview). |
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
| `components` | Swap in your own React components to be used within this collection. [More](/docs/admin/components#collections) |
| `listSearchableFields` | Specify which fields should be searched in the List search view. [More](#list-searchable-fields) |
| **`pagination`** | Set pagination-specific options for this collection. [More](#pagination) |
### Preview
Collection `admin` options can accept a `preview` function that will be used to generate a link pointing to the frontend
of your app to preview data.
If the function is specified, a Preview button will automatically appear in the corresponding collection's Edit view.
Clicking the Preview button will link to the URL that is generated by the function.
**The preview function accepts two arguments:**
1. The document being edited
1. An `options` object, containing `locale` and `token` properties. The `token` is the currently logged-in user's JWT.
**Example collection with preview function:**
```ts
import { CollectionConfig } from 'payload/types'
export const Posts: CollectionConfig = {
slug: 'posts',
fields: [
{
name: 'slug',
type: 'text',
required: true,
},
],
admin: {
preview: (doc, { locale }) => {
if (doc?.slug) {
return `https://bigbird.com/preview/posts/${doc.slug}?locale=${locale}`
}
return null
},
},
}
```
### Pagination
Here are a few options that you can specify options for pagination on a collection-by-collection basis:
| Option | Description |
|----------------|-----------------------------------------------------------------------------------------------------|
| `defaultLimit` | Integer that specifies the default per-page limit that should be used. Defaults to 10. |
| `limits` | Provide an array of integers to use as per-page options for admins to choose from in the List view. |
### Access control
You can specify extremely granular access control (what users can do with documents in a collection) on a collection by
collection basis. To learn more, go to the [Access Control](/docs/access-control/overview) docs.
### Hooks
Hooks are a powerful way to extend collection functionality and execute your own logic, and can be defined on a
collection by collection basis. To learn more, go to the [Hooks](/docs/hooks/overview) documentation.
### Field types
Collections support all field types that Payload has to offer—including simple fields like text and checkboxes all the
way to more complicated layout-building field groups like Blocks. [Click here](/docs/fields/overview) to learn more
about field types.
### List Searchable Fields
In the List view, there is a "search" box that allows you to quickly find a document with a search. By default, it
searches on the ID field. If you have `admin.useAsTitle` defined, the list search will use that field. However, you can
define more than one field to search to make it easier on your admin editors to find the data they need.
For example, let's say you have a Posts collection with `title`, `metaDescription`, and `tags` fields - and you want all
three of those fields to be searchable in the List view. You can simply
add `admin.listSearchableFields: ['title', 'metaDescription', 'tags']` - and the admin UI will automatically search on
those three fields plus the ID field.
<Banner type="warning">
<strong>Note:</strong>
<br />
If you are adding <strong>listSearchableFields</strong>, make sure you index each of these fields
so your admin queries can remain performant.
</Banner>
### Admin Hooks
In addition to collection hooks themselves, Payload provides for admin UI-specific hooks that you can leverage.
**`beforeDuplicate`**
The `beforeDuplicate` hook is an async function that accepts an object containing the data to duplicate, as well as the
locale of the doc to duplicate. Within this hook, you can modify the data to be duplicated, which is useful in cases
where you have unique fields that need to be incremented or similar, as well as if you want to automatically modify a
document's `title`.
Example:
```ts
import { BeforeDuplicate, CollectionConfig } from 'payload/types'
// Your auto-generated Page type
import { Page } from '../payload-types.ts'
const beforeDuplicate: BeforeDuplicate<Page> = ({ data }) => {
return {
...data,
title: `${data.title} Copy`,
uniqueField: data.uniqueField ? `${data.uniqueField}-copy` : '',
}
}
export const Page: CollectionConfig = {
slug: 'pages',
admin: {
hooks: {
beforeDuplicate,
},
},
fields: [
{
name: 'title',
type: 'text',
},
{
name: 'uniqueField',
type: 'text',
unique: true,
},
],
}
```
### TypeScript
You can import collection types as follows:
```ts
import { CollectionConfig } from 'payload/types'
// This is the type used for incoming collection configs.
// Only the bare minimum properties are marked as required.
```
```ts
import { SanitizedCollectionConfig } from 'payload/types'
// This is the type used after an incoming collection config is fully sanitized.
// Generally, this is only used internally by Payload.
```

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