Compare commits

...

45 Commits

Author SHA1 Message Date
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
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
107 changed files with 2056 additions and 1554 deletions

View File

@@ -1,3 +1,150 @@
## [2.6.0](https://github.com/payloadcms/payload/compare/v2.5.0...v2.6.0) (2024-01-03)
### Features
* **db-mongodb:** add transactionOptions ([f2c8ac4](https://github.com/payloadcms/payload/commit/f2c8ac4a9aa9120339af6759170f5a708469698d))
* extend locales to have fallbackLocales ([9fac2ef](https://github.com/payloadcms/payload/commit/9fac2ef24e2ade4cf55b0d6a0e7f67e0edf57539))
### Bug Fixes
* "The punycode module is deprecated" warning by updating nodemailer ([00d8480](https://github.com/payloadcms/payload/commit/00d8480062d99dee56ef61a955f48a92efa6cbea))
* adjusts json field joi schema to allow editorOptions ([bff4cf5](https://github.com/payloadcms/payload/commit/bff4cf518f748efb9179f112c606d11d25db3d99))
* **db-postgres:** Wait for transaction to complete on commit ([#4582](https://github.com/payloadcms/payload/issues/4582)) ([a71d37b](https://github.com/payloadcms/payload/commit/a71d37b39806cd5956378a10246802d01d06c2dd))
* detect language from request headers accept-language ([#4656](https://github.com/payloadcms/payload/issues/4656)) ([69a9944](https://github.com/payloadcms/payload/commit/69a99445c9f1638a962a9c08ffe0bdc22e538bf6))
* graphql multiple locales ([98890ee](https://github.com/payloadcms/payload/commit/98890eee1f527c8f245b2353d7e1caca4d2a7d8c))
* navigation locks when modal is closed with esc ([#4664](https://github.com/payloadcms/payload/issues/4664)) ([be3beab](https://github.com/payloadcms/payload/commit/be3beabb9bafa137aa89e84cf47246017e969be8))
* req.locale and req.fallbackLocale get reassigned in local operations ([aa048d5](https://github.com/payloadcms/payload/commit/aa048d5409acd42b8f56367a16934085df9fbce2))
* resets actions array when navigating out of view with actions ([#4585](https://github.com/payloadcms/payload/issues/4585)) ([5c55231](https://github.com/payloadcms/payload/commit/5c5523195ccfa94a9bf42441e2a378f87836e64d))
* **richtext-lexical:** z-index issues ([#4570](https://github.com/payloadcms/payload/issues/4570)) ([8015e99](https://github.com/payloadcms/payload/commit/8015e999cd5834f532a200ef03fd392d04b3209f))
* tab field error when using the same interface name ([#4657](https://github.com/payloadcms/payload/issues/4657)) ([f1fa374](https://github.com/payloadcms/payload/commit/f1fa374ed12b50fdf210f17ae1dda603f09a9726))
## [2.5.0](https://github.com/payloadcms/payload/compare/v2.4.0...v2.5.0) (2023-12-19)
### Features
* add Chinese Traditional translation ([#4372](https://github.com/payloadcms/payload/issues/4372)) ([50253f6](https://github.com/payloadcms/payload/commit/50253f617c22d0d185bbac7f9d4304cddbc01f06))
* add context to auth and globals local API ([#4449](https://github.com/payloadcms/payload/issues/4449)) ([168d629](https://github.com/payloadcms/payload/commit/168d6296974042c3ff2a113f9f6c2bded7ba2b3e))
* adds new `actions` property to admin customization ([#4468](https://github.com/payloadcms/payload/issues/4468)) ([9e8f14a](https://github.com/payloadcms/payload/commit/9e8f14a897e77f6933eedb2410956a468f4187c3))
* async live preview urls ([#4339](https://github.com/payloadcms/payload/issues/4339)) ([5f17324](https://github.com/payloadcms/payload/commit/5f173241df6dc316d498767b1c81718e9c2b9a51))
* pass path to FieldDescription ([#4364](https://github.com/payloadcms/payload/issues/4364)) ([3b8a27d](https://github.com/payloadcms/payload/commit/3b8a27d199b3969cbca6ca750450798cb70f21e8))
* **plugin-form-builder:** Lexical support ([#4487](https://github.com/payloadcms/payload/issues/4487)) ([c6c5cab](https://github.com/payloadcms/payload/commit/c6c5cabfbb7eb954eea51170a6af7582b1f9b84b))
* prevent querying relationship when filterOptions returns false ([#4392](https://github.com/payloadcms/payload/issues/4392)) ([c1bd338](https://github.com/payloadcms/payload/commit/c1bd338d0d5e899f3892f1d18e355c00b265447a))
* **richtext-lexical:** improve floating select menu Dropdown classNames ([#4444](https://github.com/payloadcms/payload/issues/4444)) ([9331204](https://github.com/payloadcms/payload/commit/9331204295bfeaf7dd10bc075f42995b2cab2de4))
* **richtext-lexical:** improve link URL validation ([#4442](https://github.com/payloadcms/payload/issues/4442)) ([9babf68](https://github.com/payloadcms/payload/commit/9babf6804ce04d5828167eb8e7717727fe1cd472))
* **richtext-lexical:** lazy import React components to prevent client-only code from leaking into the server ([#4290](https://github.com/payloadcms/payload/issues/4290)) ([5de347f](https://github.com/payloadcms/payload/commit/5de347ffffca3bf38315d3d87d2ccc5c28cd2723))
* **richtext-lexical:** Link & Relationship Feature: field-level configurable allowed relationships ([#4182](https://github.com/payloadcms/payload/issues/4182)) ([7af8f29](https://github.com/payloadcms/payload/commit/7af8f29b4a8dddf389356e4db142f8d434cdc964))
* **richtext-lexical:** link node: change doc data format to be consistent with relationship field ([#4504](https://github.com/payloadcms/payload/issues/4504)) ([cc0ba89](https://github.com/payloadcms/payload/commit/cc0ba895188f40181c6ba3779f66d547d4ea66f9))
* **richtext-lexical:** rename TreeviewFeature into TreeViewFeature ([#4520](https://github.com/payloadcms/payload/issues/4520)) ([c49fd66](https://github.com/payloadcms/payload/commit/c49fd6692231b68ca61b079103a0fd7aa4673be1))
* **richtext-lexical:** Slate to Lexical converter: add blockquote conversion, convert custom link fields ([#4486](https://github.com/payloadcms/payload/issues/4486)) ([31f8f3c](https://github.com/payloadcms/payload/commit/31f8f3cac6bfd08f3adfa0a026a57c4b1b510045))
* **richtext-lexical:** Upload html serializer: Output picture element if the image has multiple sizes, improve absolute URL creation ([e558894](https://github.com/payloadcms/payload/commit/e55889480fceb8995646621923159d92de6e89c9))
### Bug Fixes
* adds bg color for year/month select options in datepicker ([#4508](https://github.com/payloadcms/payload/issues/4508)) ([07371b9](https://github.com/payloadcms/payload/commit/07371b9cad111999f2df4e1f709d6b95cd511c15))
* correctly fetches externally stored files when passing uploadEdits ([#4505](https://github.com/payloadcms/payload/issues/4505)) ([228d45c](https://github.com/payloadcms/payload/commit/228d45cf52e592cea6377cd93648fba75d73c88d))
* cursor jumping around inside json field ([#4453](https://github.com/payloadcms/payload/issues/4453)) ([6300037](https://github.com/payloadcms/payload/commit/63000373e66fb39443f882689e0ecf5c11ed8ad0))
* **db-mongodb:** documentDB unique constraint throws incorrect error ([#4513](https://github.com/payloadcms/payload/issues/4513)) ([05e8914](https://github.com/payloadcms/payload/commit/05e8914db70fa64bfb2d15ecfb58e9c229d71108))
* **db-postgres:** findOne correctly querying with where queries ([#4550](https://github.com/payloadcms/payload/issues/4550)) ([8bc31cd](https://github.com/payloadcms/payload/commit/8bc31cd5923517ab39ae1427aa0d0fb19d876dab))
* **db-postgres:** querying nested blocks fields ([#4404](https://github.com/payloadcms/payload/issues/4404)) ([6e9ae65](https://github.com/payloadcms/payload/commit/6e9ae65374124ee000cc2988ef77247c94b0dd18))
* **db-postgres:** sorting on a not-configured field throws error ([#4382](https://github.com/payloadcms/payload/issues/4382)) ([dbaecda](https://github.com/payloadcms/payload/commit/dbaecda0e92fcb0fa67b4c5ac085e025f02de53a))
* defaultValues computed on new globals ([#4380](https://github.com/payloadcms/payload/issues/4380)) ([b6cffce](https://github.com/payloadcms/payload/commit/b6cffcea07b9fa21698b00b8bbed6f27197ded41))
* disallow duplicate fieldNames to be used on the same level in the config ([#4381](https://github.com/payloadcms/payload/issues/4381)) ([a1d66b8](https://github.com/payloadcms/payload/commit/a1d66b83e0dbea21e8da549b73cd25c537a57938))
* ensure ui fields do not make it into gql schemas ([#4457](https://github.com/payloadcms/payload/issues/4457)) ([3a20ddc](https://github.com/payloadcms/payload/commit/3a20ddc5f85162a316006f22ba66ee1c7aab99e3))
* format fields within tab for list controls ([#4516](https://github.com/payloadcms/payload/issues/4516)) ([2650c70](https://github.com/payloadcms/payload/commit/2650c70960a7374307a8862c3940c97d337d1d30))
* formats locales with multiple labels for versions locale selector ([#4495](https://github.com/payloadcms/payload/issues/4495)) ([8257661](https://github.com/payloadcms/payload/commit/8257661c47b5b968a57fb2228d7045d876a3f484))
* graphql schema generation for fields without queryable subfields ([#4463](https://github.com/payloadcms/payload/issues/4463)) ([13e3e06](https://github.com/payloadcms/payload/commit/13e3e0671353ca34e603fece57a12199f2082ca0))
* handles null upload field values ([#4397](https://github.com/payloadcms/payload/issues/4397)) ([cf9a370](https://github.com/payloadcms/payload/commit/cf9a3704df21ce8b32feb0680793cba804cd66f7))
* **live-preview:** populates rte uploads and relationships ([#4379](https://github.com/payloadcms/payload/issues/4379)) ([4090aeb](https://github.com/payloadcms/payload/commit/4090aebb0e94e776258f0c1c761044a4744a1857))
* **live-preview:** sends raw js objects through window.postMessage instead of json ([#4354](https://github.com/payloadcms/payload/issues/4354)) ([03a3872](https://github.com/payloadcms/payload/commit/03a387233d1b8876a2fcaa5f3b3fd5ed512c0bc4))
* make admin navigation transition smoother ([#4217](https://github.com/payloadcms/payload/issues/4217)) ([eb6572e](https://github.com/payloadcms/payload/commit/eb6572e9e56e680cad331c1bc5da47e91306deb9))
* omit field default value if read access returns false ([#4518](https://github.com/payloadcms/payload/issues/4518)) ([3e9ef84](https://github.com/payloadcms/payload/commit/3e9ef849cd8e69e1e8d7f2f653f0647e93c8ab39))
* pin ts-node versions which are causing swc errors ([#4447](https://github.com/payloadcms/payload/issues/4447)) ([b9c0248](https://github.com/payloadcms/payload/commit/b9c024882350d14edd57f0f662a2269ed37975e3))
* properly spreads collection fields into non-tabbed configs [#50](https://github.com/payloadcms/payload/issues/50) ([#51](https://github.com/payloadcms/payload/issues/51)) ([7e88159](https://github.com/payloadcms/payload/commit/7e88159e99e2afdc10addc02cf299c11fe188be7))
* **plugin-form-builder:** removes use of slate in rich-text serializer ([#4451](https://github.com/payloadcms/payload/issues/4451)) ([3df52a8](https://github.com/payloadcms/payload/commit/3df52a88568622f8fafeabad47c7501229e4ea5f))
* **plugin-nested-docs:** properly exports field utilities ([#4462](https://github.com/payloadcms/payload/issues/4462)) ([1cc87bd](https://github.com/payloadcms/payload/commit/1cc87bd8ea575dfa2e1f5ce5b38414bbba95b2cb))
* **richtext-*:** loosen RichTextAdapter types due to re-occuring ts strict mode errors ([#4416](https://github.com/payloadcms/payload/issues/4416)) ([48f1299](https://github.com/payloadcms/payload/commit/48f1299fcba3e3811c6a7f31499f238537f9a5e3))
* **richtext-lexical:** Blocks field: should not prompt for unsaved changes due to value comparison between null and non-existent props ([#4450](https://github.com/payloadcms/payload/issues/4450)) ([548e78c](https://github.com/payloadcms/payload/commit/548e78c598cb6d029e7cc40f80d9855754f043bc))
* **richtext-lexical:** do not add unnecessary paragraph before upload, relationship and blocks nodes ([#4441](https://github.com/payloadcms/payload/issues/4441)) ([5c2739e](https://github.com/payloadcms/payload/commit/5c2739ebd144620cfd4ff02531f5812dd62ac61d))
* **richtext-lexical:** lexicalHTML field not working when used inside of Blocks field ([128f9c4](https://github.com/payloadcms/payload/commit/128f9c4e7e6e20dd1ee221f49428a5bce5179c5f))
* **richtext-lexical:** lexicalHTML field now works when used inside of row fields ([#4440](https://github.com/payloadcms/payload/issues/4440)) ([0421173](https://github.com/payloadcms/payload/commit/0421173f9e2d6db1b6a94b25884ea807921f2d09))
* **richtext-lexical:** not all types of URLs are validated correctly ([ac7f980](https://github.com/payloadcms/payload/commit/ac7f9809bc2b9fb6a52b48c10f7d51414801e4de))
* searching by id sends undefined in where query param ([#4464](https://github.com/payloadcms/payload/issues/4464)) ([46e8c01](https://github.com/payloadcms/payload/commit/46e8c01fbed68856be68804f2bd9744c4c6f5a95))
* simplifies query validation and fixes nested relationship fields ([#4391](https://github.com/payloadcms/payload/issues/4391)) ([4b5453e](https://github.com/payloadcms/payload/commit/4b5453e8e5484f7afcadbf5bccf8369b552969c6))
* updates return value of empty arrays in getDataByPath ([#4553](https://github.com/payloadcms/payload/issues/4553)) ([f3748a1](https://github.com/payloadcms/payload/commit/f3748a1534a13e6d844aadd9f0e3e6acbe483d03))
* upload editing error with plugin-cloud ([#4170](https://github.com/payloadcms/payload/issues/4170)) ([fcbe574](https://github.com/payloadcms/payload/commit/fcbe5744d945dc43642cdaa2007ddc252ecafafa))
* upload related issues, cropping, fetching local file, external preview image ([#4461](https://github.com/payloadcms/payload/issues/4461)) ([45c472d](https://github.com/payloadcms/payload/commit/45c472d6b35c41e597038089ad1755cdb88193b6))
* uploads files after validation ([#4218](https://github.com/payloadcms/payload/issues/4218)) ([65adfd2](https://github.com/payloadcms/payload/commit/65adfd21ed538b79628dc4f8ce9e1a5a1bba6aed))
### ⚠ BREAKING CHANGES
#### @payloadcms/richtext-lexical
* **richtext-lexical:** rename TreeviewFeature into TreeViewFeature ([#4520](https://github.com/payloadcms/payload/issues/4520)) ([c49fd66](https://github.com/payloadcms/payload/commit/c49fd6692231b68ca61b079103a0fd7aa4673be1))
If you import TreeviewFeature, you have to rename the import to use TreeViewFeature (capitalized "V")
* **richtext-lexical:** link node: change doc data format to be consistent with relationship field ([#4504](https://github.com/payloadcms/payload/issues/4504)) ([cc0ba89](https://github.com/payloadcms/payload/commit/cc0ba895188f40181c6ba3779f66d547d4ea66f9))
An unpopulated, internal link node no longer saves the doc id under fields.doc.value.id. Now, it saves it under fields.doc.value.
Migration inside of payload is automatic. If you are reading from the link node inside of your frontend though, you will have to adjust it.
* **richtext-lexical:** improve floating select menu Dropdown classNames ([#4444](https://github.com/payloadcms/payload/issues/4444)) ([9331204](https://github.com/payloadcms/payload/commit/9331204295bfeaf7dd10bc075f42995b2cab2de4))
Dropdown component has a new mandatory sectionKey prop
* **richtext-lexical:** lazy import React components to prevent client-only code from leaking into the server ([#4290](https://github.com/payloadcms/payload/issues/4290)) ([5de347f](https://github.com/payloadcms/payload/commit/5de347ffffca3bf38315d3d87d2ccc5c28cd2723))
1. Most important: If you are updating `@payloadcms/richtext-lexical` to v0.4.0 or higher, you will HAVE to update payload to the latest version as well. If you don't update it, payload likely won't start up due to validation errors. It's generally good practice to upgrade packages prefixed with @payloadcms/ together with payload and keep the versions in sync.
2. `@payloadcms/richtext-slate` is not affected by this.
3. Every single property in the `Feature` interface which accepts a React component now no longer accepts a React component, but a function which imports a React component instead. This is done to ensure no unnecessary client-only code is leaked to the server when importing Features on a server.
Here's an example migration:
Old:
```ts
import { BlockIcon } from '../../lexical/ui/icons/Block'
...
Icon: BlockIcon,
```
New:
```ts
// import { BlockIcon } from '../../lexical/ui/icons/Block' // <= Remove this import
...
Icon: () =>
// @ts-expect-error
import('../../lexical/ui/icons/Block').then((module) => module.BlockIcon),
```
Or alternatively, if you're using default exports instead of named exports:
```ts
// import BlockIcon from '../../lexical/ui/icons/Block' // <= Remove this import
...
Icon: () =>
// @ts-expect-error
import('../../lexical/ui/icons/Block'),
```
4. The types for `SanitizedEditorConfig` and `EditorConfig` have changed. Their respective `lexical` property no longer expects the `LexicalEditorConfig`. It now expects a function returning the `LexicalEditorConfig`. You will have to adjust this if you adjusted that property anywhere, e.g. when initializing the lexical field editor property, or when initializing a new headless editor.
5. The following exports are now exported from the `@payloadcms/richtext-lexical/components` subpath exports instead of `@payloadcms/richtext-lexical`:
- `ToolbarButton`
- `ToolbarDropdown`
- `RichTextCell`
- `RichTextField`
- `defaultEditorLexicalConfig`
You will have to adjust your imports, only if you import any of those properties in your project.
## @payloadcms/richtext-*
### [@payloadcms/richtext-lexical 0.4.1](https://github.com/payloadcms/payload/compare/richtext-lexical/0.4.0...richtext-lexical/0.4.1) (2023-12-07)

View File

@@ -6,11 +6,13 @@ desc: Add and maintain as many locales as you need by adding Localization to you
keywords: localization, internationalization, i18n, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
---
Payload features deep field-based localization support. Maintaining as many locales as you need is easy. All localization support is opt-in by default. To do so, follow the two steps below.
Payload features deep field-based localization support. Maintaining as many locales as you need is easy. All
localization support is opt-in by default. To do so, follow the two steps below.
### Enabling in the Payload config
Add the `localization` property to your Payload config to enable localization project-wide. You'll need to provide a list of all locales that you'd like to support as well as set a few other options.
Add the `localization` property to your Payload config to enable localization project-wide. You'll need to provide a
list of all locales that you'd like to support as well as set a few other options.
**Example Payload config set up for localization:**
@@ -57,7 +59,8 @@ export default buildConfig({
})
```
**Example Payload config set up for localization with full locales objects (including [internationalization](/docs/configuration/i18n) support):**
**Example Payload config set up for localization with full locales objects (
including [internationalization](/docs/configuration/i18n) support):**
```ts
import { buildConfig } from 'payload/config'
@@ -93,35 +96,60 @@ export default buildConfig({
**`locales`**
Array-based list of all locales that you would like to support. These can be strings of locale codes or objects with a `label`, a locale `code`, and the `rtl` (right-to-left) property. The locale codes do not need to be in any specific format. It's up to you to define how to represent your locales. Common patterns are to use two-letter ISO 639 language codes or four-letter language and country codes (ISO 31661) such as `en-US`, `en-UK`, `es-MX`, etc.
Array-based list of all the languages that you would like to support. This can be an array containing strings for each
language code you want your project to store and serve or objects with a `label`, a locale `code`, `rtl` (
right-to-left), and `fallbackLocale` property. The locale codes do not need to be in any specific format. It's up to you
to define how to represent your locales. Common patterns are to use two-letter ISO 639 language codes or four-letter
language and country codes (ISO 31661) such as `en-US`, `en-UK`, `es-MX`, etc.
### Locale Properties:
| Option | Description |
|----------------------|--------------------------------------------------------------------------------------------------------------------------------|
| **`code`** \* | Unique code to identify the language throughout the APIs for `locale` and `fallbackLocale` |
| **`label`** | A string to use for the selector when choosing a language, or an object keyed on the i18n keys for different languages in use. |
| **`rtl`** | A boolean that when true will make the admin UI display in Right-To-Left. |
| **`fallbackLocale`** | The code for this language to fallback to when properties of a document are not present. |
_\* An asterisk denotes that a property is required._
**`defaultLocale`**
Required string that matches one of the locale codes from the array provided. By default, if no locale is specified, documents will be returned in this locale.
Required string that matches one of the locale codes from the array provided. By default, if no locale is specified,
documents will be returned in this locale.
**`fallback`**
Boolean enabling "fallback" locale functionality. If a document is requested in a locale, but a field does not have a localized value corresponding to the requested locale, then if this property is enabled, the document will automatically fall back to the fallback locale value. If this property is not enabled, the value will not be populated.
Boolean enabling "fallback" locale functionality. If a document is requested in a locale, but a field does not have a
localized value corresponding to the requested locale, then if this property is enabled, the document will automatically
fall back to the fallback locale value. If this property is not enabled, the value will not be populated.
### Field by field localization
Payload localization works on a **field** level—not a document level. In addition to configuring the base Payload config to support localization, you need to specify each field that you would like to localize.
Payload localization works on a **field** level—not a document level. In addition to configuring the base Payload config
to support localization, you need to specify each field that you would like to localize.
**Here is an example of how to enable localization for a field:**
```js
{
name: 'title',
type: 'text',
type
:
'text',
// highlight-start
localized: true,
localized
:
true,
// highlight-end
}
```
With the above configuration, the `title` field will now be saved in the database as an object of all locales instead of a single string.
With the above configuration, the `title` field will now be saved in the database as an object of all locales instead of
a single string.
All field types with a `name` property support the `localized` property—even the more complex field types like `array`s and `block`s.
All field types with a `name` property support the `localized` property—even the more complex field types like `array`s
and `block`s.
<Banner>
<strong>Note:</strong>
@@ -143,7 +171,8 @@ All field types with a `name` property support the `localized` property—even t
### Retrieving localized docs
When retrieving documents, you can specify which locale you'd like to receive as well as which fallback locale should be used.
When retrieving documents, you can specify which locale you'd like to receive as well as which fallback locale should be
used.
##### REST API
@@ -155,7 +184,8 @@ Specify your desired locale by providing the `locale` query parameter directly i
**`?fallback-locale=`**
Specify fallback locale to be used by providing the `fallback-locale` query parameter. This can be provided as either a valid locale as provided to your base Payload config, or `'null'`, `'false'`, or `'none'` to disable falling back.
Specify fallback locale to be used by providing the `fallback-locale` query parameter. This can be provided as either a
valid locale as provided to your base Payload config, or `'null'`, `'false'`, or `'none'` to disable falling back.
**Example:**
@@ -167,7 +197,9 @@ fetch('https://localhost:3000/api/pages?locale=es&fallback-locale=none');
In the GraphQL API, you can specify `locale` and `fallbackLocale` args to all relevant queries and mutations.
The `locale` arg will only accept valid locales, but locales will be formatted automatically as valid GraphQL enum values (dashes or special characters will be converted to underscores, spaces will be removed, etc.). If you are curious to see how locales are auto-formatted, you can use the [GraphQL playground](/docs/graphql/overview#graphql-playground).
The `locale` arg will only accept valid locales, but locales will be formatted automatically as valid GraphQL enum
values (dashes or special characters will be converted to underscores, spaces will be removed, etc.). If you are curious
to see how locales are auto-formatted, you can use the [GraphQL playground](/docs/graphql/overview#graphql-playground).
The `fallbackLocale` arg will accept valid locales as well as `none` to disable falling back.
@@ -191,7 +223,9 @@ query {
##### Local API
You can specify `locale` as well as `fallbackLocale` within the Local API as well as properties on the `options` argument. The `locale` property will accept any valid locale, and the `fallbackLocale` property will accept any valid locale as well as `'null'`, `'false'`, `false`, and `'none'`.
You can specify `locale` as well as `fallbackLocale` within the Local API as well as properties on the `options`
argument. The `locale` property will accept any valid locale, and the `fallbackLocale` property will accept any valid
locale as well as `'null'`, `'false'`, `false`, and `'none'`.
**Example:**

View File

@@ -6,7 +6,8 @@ desc: Payload has supported MongoDB natively since we started. The flexible natu
keywords: MongoDB, documentation, typescript, Content Management System, cms, headless, javascript, node, react, express
---
To use Payload with MongoDB, install the package `@payloadcms/db-mongodb`. It will come with everything you need to store your Payload data in MongoDB.
To use Payload with MongoDB, install the package `@payloadcms/db-mongodb`. It will come with everything you need to
store your Payload data in MongoDB.
Then from there, pass it to your Payload config as follows:
@@ -30,15 +31,17 @@ export default buildConfig({
### Options
| Option | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `autoPluralization` | Tell Mongoose to auto-pluralize any collection names if it encounters any singular words used as collection `slug`s. |
| `connectOptions` | Customize MongoDB connection options. Payload will connect to your MongoDB database using default options which you can override and extend to include all the [options](https://mongoosejs.com/docs/connections.html#options) available to mongoose. |
| `disableIndexHints` | Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination, as it increases the speed of the count function used in that query. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false |
| `migrationDir` | Customize the directory that migrations are stored. |
| `transactionOptions` | An object with configuration properties used in [transactions](https://www.mongodb.com/docs/manual/core/transactions/) or `false` which will disable the use of transactions. | |
### Access to Mongoose models
After Payload is initialized, this adapter exposes all of your Mongoose models and they are available for you to work with directly.
After Payload is initialized, this adapter exposes all of your Mongoose models and they are available for you to work
with directly.
You can access Mongoose models as follows:

View File

@@ -48,7 +48,7 @@ const afterChange: CollectionAfterChangeHook = async ({ req }) => {
})
// Should this call fail, it will not rollback other changes
// because the req (and its transationID) is not passed through
// because the req (and its transactionID) is not passed through
const safelyIgnoredAsync = req.payload.create({
collection: 'my-slug',
data: {

View File

@@ -133,7 +133,7 @@ import * as React from 'react';
import { SelectInput, useField } from 'payload/components/forms';
import { useAuth } from 'payload/components/utilities';
type customSelectProps = {
type CustomSelectProps = {
path: string;
options: {
label: string;
@@ -164,7 +164,7 @@ export const CustomSelectComponent: React.FC<CustomSelectProps> = ({ path, optio
name={path}
options={adjustedOptions}
value={value}
onChange={() => setValue(e.value)}
onChange={(e) => setValue(e.value)}
/>
</div>
)

View File

@@ -287,5 +287,5 @@ import {
## Examples
The [Templates Directory](https://github.com/payloadcms/payload/tree/main/templates) contains an official [E-commerce Template](https://github.com/payloadcms/payload/tree/main/templates/ecommere) which demonstrates exactly how to configure this plugin in Payload and implement it on your front-end. You can also check out [How to Build An E-Commerce Site With Next.js](https://payloadcms.com/blog/how-to-build-an-e-commerce-site-with-nextjs) post for a bit more context around this template.
The [Templates Directory](https://github.com/payloadcms/payload/tree/main/templates) contains an official [E-commerce Template](https://github.com/payloadcms/payload/tree/main/templates/ecommerce) which demonstrates exactly how to configure this plugin in Payload and implement it on your front-end. You can also check out [How to Build An E-Commerce Site With Next.js](https://payloadcms.com/blog/how-to-build-an-e-commerce-site-with-nextjs) post for a bit more context around this template.

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-mongodb",
"version": "1.1.0",
"version": "1.2.0",
"description": "The officially supported MongoDB database adapter for Payload",
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",
@@ -23,15 +23,17 @@
"bson-objectid": "2.0.4",
"deepmerge": "4.3.1",
"get-port": "5.1.1",
"mongoose": "6.12.0",
"mongoose": "6.12.3",
"mongoose-aggregate-paginate-v2": "1.0.6",
"mongoose-paginate-v2": "1.7.22",
"prompts": "2.4.2",
"http-status": "1.6.2",
"uuid": "9.0.0"
},
"devDependencies": {
"@payloadcms/eslint-config": "workspace:*",
"@types/mongoose-aggregate-paginate-v2": "1.0.9",
"mongodb": "4.17.1",
"mongodb-memory-server": "8.13.0",
"payload": "workspace:*"
},

View File

@@ -48,6 +48,13 @@ export const connect: Connect = async function connect(this: MongooseAdapter, pa
try {
this.connection = (await mongoose.connect(urlToConnect, connectionOptions)).connection
const client = this.connection.getClient()
if (!client.options.replicaSet || this.transactionOptions === false) {
this.transactionOptions = false
this.beginTransaction = undefined
}
if (process.env.PAYLOAD_DROP_DATABASE === 'true') {
this.payload.logger.info('---- DROPPING DATABASE ----')
await mongoose.connection.dropDatabase()

View File

@@ -3,9 +3,8 @@ import type { Document, PayloadRequest } from 'payload/types'
import type { MongooseAdapter } from '.'
import handleError from './utilities/handleError'
import { withSession } from './withSession'
import { ValidationError } from 'payload/errors'
import { i18nInit } from 'payload/utilities'
export const create: Create = async function create(
this: MongooseAdapter,
@@ -17,18 +16,7 @@ export const create: Create = async function create(
try {
;[doc] = await Model.create([data], options)
} catch (error) {
// Handle uniqueness error from MongoDB
throw error.code === 11000 && error.keyValue
? new ValidationError(
[
{
field: Object.keys(error.keyValue)[0],
message: req.t('error:valueMustBeUnique'),
},
],
req?.t ?? i18nInit(this.payload.config.i18n).t,
)
: error
handleError(error, req)
}
// doc.toJSON does not do stuff like converting ObjectIds to string, or date strings to date objects. That's why we use JSON.parse/stringify here

View File

@@ -1,3 +1,4 @@
import type { TransactionOptions } from 'mongodb'
import type { ClientSession, ConnectOptions, Connection } from 'mongoose'
import type { Payload } from 'payload'
import type { BaseDatabaseAdapter } from 'payload/database'
@@ -7,8 +8,6 @@ import mongoose from 'mongoose'
import path from 'path'
import { createDatabaseAdapter } from 'payload/database'
export type { MigrateDownArgs, MigrateUpArgs } from './types'
import type { CollectionModel, GlobalModel } from './types'
import { connect } from './connect'
@@ -39,6 +38,8 @@ import { updateGlobalVersion } from './updateGlobalVersion'
import { updateOne } from './updateOne'
import { updateVersion } from './updateVersion'
export type { MigrateDownArgs, MigrateUpArgs } from './types'
export interface Args {
/** Set to false to disable auto-pluralization of collection names, Defaults to true */
autoPluralization?: boolean
@@ -50,6 +51,7 @@ export interface Args {
/** Set to true to disable hinting to MongoDB to use 'id' as index. This is currently done when counting documents for pagination. Disabling this optimization might fix some problems with AWS DocumentDB. Defaults to false */
disableIndexHints?: boolean
migrationDir?: string
transactionOptions?: TransactionOptions | false
/** The URL to connect to MongoDB or false to start payload and prevent connecting */
url: false | string
}
@@ -81,6 +83,7 @@ declare module 'payload' {
globals: GlobalModel
mongoMemoryServer: any
sessions: Record<number | string, ClientSession>
transactionOptions: TransactionOptions
versions: {
[slug: string]: CollectionModel
}
@@ -92,15 +95,21 @@ export function mongooseAdapter({
connectOptions,
disableIndexHints = false,
migrationDir: migrationDirArg,
transactionOptions,
url,
}: Args): MongooseAdapterResult {
function adapter({ payload }: { payload: Payload }) {
const migrationDir = findMigrationDir(migrationDirArg)
let beginTransactionFunction = beginTransaction
mongoose.set('strictQuery', false)
extendWebpackConfig(payload.config)
extendViteConfig(payload.config)
if (transactionOptions === false) {
beginTransactionFunction = undefined
}
return createDatabaseAdapter<MongooseAdapter>({
name: 'mongoose',
@@ -113,11 +122,12 @@ export function mongooseAdapter({
globals: undefined,
mongoMemoryServer: undefined,
sessions: {},
transactionOptions: transactionOptions === false ? undefined : transactionOptions,
url,
versions: {},
// DatabaseAdapter
beginTransaction,
beginTransaction: beginTransactionFunction,
commitTransaction,
connect,
create,

View File

@@ -1,34 +1,30 @@
// @ts-expect-error // TODO: Fix this import
import type { TransactionOptions } from 'mongodb'
import type { BeginTransaction } from 'payload/database'
import { APIError } from 'payload/errors'
import { v4 as uuid } from 'uuid'
let transactionsNotAvailable: boolean
import type { MongooseAdapter } from '../index'
export const beginTransaction: BeginTransaction = async function beginTransaction(
options: TransactionOptions = {},
this: MongooseAdapter,
options: TransactionOptions,
) {
let id = null
if (!this.connection) {
throw new APIError('beginTransaction called while no connection to the database exists')
}
if (transactionsNotAvailable) return id
const client = this.connection.getClient()
if (!client.options.replicaSet) {
transactionsNotAvailable = true
} else {
id = uuid()
const id = uuid()
if (!this.sessions[id]) {
this.sessions[id] = await client.startSession()
this.sessions[id] = client.startSession()
}
if (this.sessions[id].inTransaction()) {
this.payload.logger.warn('beginTransaction called while transaction already exists')
} else {
await this.sessions[id].startTransaction(options)
}
this.sessions[id].startTransaction(options || (this.transactionOptions as TransactionOptions))
}
return id
}

View File

@@ -1,11 +1,9 @@
import type { UpdateOne } from 'payload/database'
import type { PayloadRequest } from 'payload/types'
import { ValidationError } from 'payload/errors'
import { i18nInit } from 'payload/utilities'
import type { MongooseAdapter } from '.'
import handleError from './utilities/handleError'
import sanitizeInternalFields from './utilities/sanitizeInternalFields'
import { withSession } from './withSession'
@@ -31,18 +29,7 @@ export const updateOne: UpdateOne = async function updateOne(
try {
result = await Model.findOneAndUpdate(query, data, options)
} catch (error) {
// Handle uniqueness error from MongoDB
throw error.code === 11000 && error.keyValue
? new ValidationError(
[
{
field: Object.keys(error.keyValue)[0],
message: 'Value must be unique',
},
],
req?.t ?? i18nInit(this.payload.config.i18n).t,
)
: error
handleError(error, req)
}
result = JSON.parse(JSON.stringify(result))

View File

@@ -0,0 +1,23 @@
import httpStatus from 'http-status'
import { APIError, ValidationError } from 'payload/errors'
const handleError = (error, req) => {
// Handle uniqueness error from MongoDB
if (error.code === 11000 && error.keyValue) {
throw new ValidationError(
[
{
field: Object.keys(error.keyValue)[0],
message: req.t('error:valueMustBeUnique'),
},
],
req.t,
)
} else if (error.code === 11000) {
throw new APIError(req.t('error:valueMustBeUnique'), httpStatus.BAD_REQUEST)
} else {
throw error
}
}
export default handleError

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-postgres",
"version": "0.2.1",
"version": "0.2.3",
"description": "The officially supported Postgres database adapter for Payload",
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",

View File

@@ -128,15 +128,16 @@ export const traverseFields = ({
with: {},
}
if (adapter.tables[`${topLevelTableName}_blocks_${toSnakeCase(block.slug)}_locales`])
withBlock.with._locales = _locales
const tableName = `${topLevelTableName}_blocks_${toSnakeCase(block.slug)}`
if (adapter.tables[`${tableName}_locales`]) withBlock.with._locales = _locales
topLevelArgs.with[blockKey] = withBlock
traverseFields({
_locales,
adapter,
currentArgs: withBlock,
currentTableName,
currentTableName: tableName,
depth,
fields: block.fields,
path: '',

View File

@@ -11,11 +11,11 @@ export const beginTransaction: BeginTransaction = async function beginTransactio
try {
id = uuid()
let reject: (value?: unknown) => void
let resolve: (value?: unknown) => void
let reject: () => Promise<void>
let resolve: () => Promise<void>
let transaction: DrizzleTransaction
let transactionReady: (value?: unknown) => void
let transactionReady: () => void
// Drizzle only exposes a transactions API that is sufficient if you
// can directly pass around the `tx` argument. But our operations are spread
@@ -24,13 +24,19 @@ export const beginTransaction: BeginTransaction = async function beginTransactio
// and will call them in our respective transaction methods
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.drizzle
const done = this.drizzle
.transaction(async (tx) => {
transaction = tx
await new Promise((res, rej) => {
await new Promise<void>((res, rej) => {
resolve = () => {
res()
return done
}
reject = () => {
rej()
return done
}
transactionReady()
resolve = res
reject = rej
})
})
.catch(() => {
@@ -39,7 +45,7 @@ export const beginTransaction: BeginTransaction = async function beginTransactio
// Need to wait until the transaction is ready
// before binding its `resolve` and `reject` methods below
await new Promise((resolve) => (transactionReady = resolve))
await new Promise<void>((resolve) => (transactionReady = resolve))
this.sessions[id] = {
db: transaction,

View File

@@ -7,9 +7,9 @@ export const commitTransaction: CommitTransaction = async function commitTransac
}
try {
this.sessions[id].resolve()
await this.sessions[id].resolve()
} catch (err: unknown) {
this.sessions[id].reject()
await this.sessions[id].reject()
}
delete this.sessions[id]

View File

@@ -56,8 +56,8 @@ export type PostgresAdapter = BaseDatabaseAdapter & {
sessions: {
[id: string]: {
db: DrizzleTransaction
reject: () => void
resolve: () => void
reject: () => Promise<void>
resolve: () => Promise<void>
}
}
tables: Record<string, GenericTable>
@@ -86,8 +86,8 @@ declare module 'payload' {
sessions: {
[id: string]: {
db: DrizzleTransaction
reject: () => void
resolve: () => void
reject: () => Promise<void>
resolve: () => Promise<void>
}
}
tables: Record<string, GenericTable>

View File

@@ -62,7 +62,7 @@ module.exports = {
'partition-by-comment': true,
groups: ['top', 'unknown'],
'custom-groups': {
top: ['_id', 'id', 'name'],
top: ['_id', 'id', 'name', 'slug', 'type'],
},
},
],

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/live-preview",
"version": "0.2.1",
"version": "0.2.2",
"description": "The official live preview JavaScript SDK for Payload",
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",

View File

@@ -1,6 +1,6 @@
{
"name": "payload",
"version": "2.4.0",
"version": "2.6.0",
"description": "Node, React and MongoDB Headless CMS and Application Framework",
"license": "MIT",
"main": "./dist/index.js",
@@ -105,7 +105,7 @@
"minimist": "1.2.8",
"mkdirp": "1.0.4",
"monaco-editor": "0.38.0",
"nodemailer": "6.9.4",
"nodemailer": "6.9.8",
"object-to-formdata": "4.5.1",
"passport": "0.6.0",
"passport-anonymous": "1.0.1",

View File

@@ -12,6 +12,11 @@
// place the localizer outside the `overflow: hidden` container so that the popup is visible
// this means we need to use a placeholder div so that the space is retained in the DOM
[dir='rtl'] &__localizer {
right: unset;
left: base(4.5)
}
&__localizer {
position: absolute;
top: 50%;

View File

@@ -97,7 +97,7 @@ const RelationshipField: React.FC<Props> = (props) => {
}
}
} else {
setErrorLoading(t('errors:unspecific'))
setErrorLoading(t('error:unspecific'))
}
}
}, Promise.resolve())

View File

@@ -17,9 +17,16 @@ const Component: React.FC<{
onCancel: () => void
onConfirm: () => void
}> = ({ isActive, onCancel, onConfirm }) => {
const { closeModal, openModal } = useModal()
const { closeModal, openModal, modalState } = useModal()
const { t } = useTranslation('general')
// Manually check for modal state as 'esc' key will not trigger the nav inactivity
useEffect(() => {
if (!modalState?.[modalSlug]?.isOpen && isActive) {
onCancel()
}
}, [modalState])
useEffect(() => {
if (isActive) openModal(modalSlug)
else closeModal(modalSlug)

View File

@@ -219,6 +219,10 @@ export const API: React.FC<EditViewProps> = (props) => {
editConfig && 'API' in editConfig && 'actions' in editConfig.API ? editConfig.API.actions : []
setViewActions(apiActions)
return () => {
setViewActions([])
}
}, [collection, global, setViewActions])
const localeOptions =

View File

@@ -58,6 +58,10 @@ const DefaultGlobalView: React.FC<DefaultGlobalViewProps> = (props) => {
: []
setViewActions(defaultActions)
return () => {
setViewActions([])
}
}, [global.slug, location.pathname, global?.admin?.components?.views?.Edit, setViewActions])
return (

View File

@@ -193,6 +193,10 @@ export const LivePreviewView: React.FC<
: []
setViewActions(livePreviewActions)
return () => {
setViewActions([])
}
}, [collection, global, setViewActions])
const breakpoints: LivePreviewConfig['breakpoints'] = [

View File

@@ -184,6 +184,10 @@ const VersionView: React.FC<Props> = ({ collection, global }) => {
: []
setViewActions(versionActions)
return () => {
setViewActions([])
}
}, [collection, global, setViewActions])
let metaTitle: string

View File

@@ -136,6 +136,10 @@ const VersionsView: React.FC<IndexProps> = (props) => {
: []
setViewActions(versionsActions)
return () => {
setViewActions([])
}
}, [collection, global, setViewActions])
return (

View File

@@ -91,6 +91,10 @@ const DefaultEditView: React.FC<DefaultEditViewProps> = (props) => {
: []
setViewActions(defaultActions)
return () => {
setViewActions([])
}
}, [id, location.pathname, collection?.admin?.components?.views?.Edit, setViewActions])
return (

View File

@@ -83,6 +83,10 @@ const ListView: React.FC<ListIndexProps> = (props) => {
if (CustomList && typeof CustomList === 'object' && 'actions' in CustomList) {
setViewActions(CustomList.actions || [])
}
return () => {
setViewActions([])
}
}, [CustomList, setViewActions])
useEffect(() => {

View File

@@ -1,7 +1,8 @@
import type { PayloadRequest } from '../../../express/types'
import type { Payload } from '../../../payload'
import formatName from '../../../graphql/utilities/formatName'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import access from '../../operations/access'
const formatConfigNames = (results, configs) => {
@@ -19,7 +20,7 @@ const formatConfigNames = (results, configs) => {
function accessResolver(payload: Payload) {
async function resolver(_, args, context) {
const options = {
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
}
const accessResults = await access(options)

View File

@@ -1,6 +1,7 @@
import type { Collection } from '../../../collections/config/types'
import type { PayloadRequest } from '../../../express/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import forgotPassword from '../../operations/forgotPassword'
function forgotPasswordResolver(collection: Collection): any {
@@ -12,7 +13,7 @@ function forgotPasswordResolver(collection: Collection): any {
},
disableEmail: args.disableEmail,
expiration: args.expiration,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
}
await forgotPassword(options)

View File

@@ -1,11 +1,13 @@
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import type { PayloadRequest } from '../../../express/types'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import init from '../../operations/init'
function initResolver(collection: string) {
async function resolver(_, args, context) {
const options = {
collection,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
}
return init(options)

View File

@@ -1,6 +1,7 @@
import type { Collection } from '../../../collections/config/types'
import type { PayloadRequest } from '../../../express/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import login from '../../operations/login'
function loginResolver(collection: Collection) {
@@ -12,7 +13,7 @@ function loginResolver(collection: Collection) {
password: args.password,
},
depth: 0,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
res: context.res,
}

View File

@@ -1,13 +1,14 @@
import type { Collection } from '../../../collections/config/types'
import type { PayloadRequest } from '../../../express/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import logout from '../../operations/logout'
function logoutResolver(collection: Collection): any {
async function resolver(_, args, context) {
const options = {
collection,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
res: context.res,
}

View File

@@ -1,6 +1,7 @@
import type { Collection } from '../../../collections/config/types'
import type { PayloadRequest } from '../../../express/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import me from '../../operations/me'
function meResolver(collection: Collection): any {
@@ -8,7 +9,7 @@ function meResolver(collection: Collection): any {
const options = {
collection,
depth: 0,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
}
return me(options)
}

View File

@@ -1,6 +1,7 @@
import type { Collection } from '../../../collections/config/types'
import type { PayloadRequest } from '../../../express/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import getExtractJWT from '../../getExtractJWT'
import refresh from '../../operations/refresh'
@@ -18,7 +19,7 @@ function refreshResolver(collection: Collection) {
const options = {
collection,
depth: 0,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
res: context.res,
token,
}

View File

@@ -1,20 +1,24 @@
/* eslint-disable no-param-reassign */
import type { Collection } from '../../../collections/config/types'
import type { PayloadRequest } from '../../../express/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import resetPassword from '../../operations/resetPassword'
function resetPasswordResolver(collection: Collection) {
async function resolver(_, args, context) {
if (args.locale) context.req.locale = args.locale
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
let { req } = context
req = isolateObjectProperty(req, 'locale')
req = isolateObjectProperty(req, 'fallbackLocale')
if (args.locale) req.locale = args.locale
if (args.fallbackLocale) req.fallbackLocale = args.fallbackLocale
const options = {
api: 'GraphQL',
collection,
data: args,
depth: 0,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(req, 'transactionID'),
res: context.res,
}

View File

@@ -1,6 +1,7 @@
import type { Collection } from '../../../collections/config/types'
import type { PayloadRequest } from '../../../express/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import unlock from '../../operations/unlock'
function unlockResolver(collection: Collection) {
@@ -8,7 +9,7 @@ function unlockResolver(collection: Collection) {
const options = {
collection,
data: { email: args.email },
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
}
const result = await unlock(options)

View File

@@ -1,18 +1,22 @@
/* eslint-disable no-param-reassign */
import type { Collection } from '../../../collections/config/types'
import type { PayloadRequest } from '../../../express/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import verifyEmail from '../../operations/verifyEmail'
function verifyEmailResolver(collection: Collection) {
async function resolver(_, args, context) {
if (args.locale) context.req.locale = args.locale
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
let { req } = context
req = isolateObjectProperty(req, 'locale')
req = isolateObjectProperty(req, 'fallbackLocale')
if (args.locale) req.locale = args.locale
if (args.fallbackLocale) req.fallbackLocale = args.fallbackLocale
const options = {
api: 'GraphQL',
collection,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(req, 'transactionID'),
res: context.res,
token: args.token,
}

View File

@@ -36,8 +36,8 @@ async function localLogin<TSlug extends keyof GeneratedTypes['collections']>(
context,
data,
depth,
fallbackLocale,
locale,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
locale: localeArg = null,
overrideAccess = true,
req = {} as PayloadRequest,
res,
@@ -46,6 +46,12 @@ async function localLogin<TSlug extends keyof GeneratedTypes['collections']>(
setRequestContext(req, context)
const collection = payload.collections[collectionSlug]
const localizationConfig = payload?.config?.localization
const defaultLocale = localizationConfig ? localizationConfig.defaultLocale : null
const locale = localeArg || req?.locale || defaultLocale
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!collection) {
throw new APIError(
@@ -56,8 +62,6 @@ async function localLogin<TSlug extends keyof GeneratedTypes['collections']>(
req.payloadAPI = req.payloadAPI || 'local'
req.payload = payload
req.i18n = i18nInit(payload.config.i18n)
req.locale = undefined
req.fallbackLocale = undefined
if (!req.t) req.t = req.i18n.t
if (!req.payloadDataLoader) req.payloadDataLoader = getDataLoader(req)
@@ -73,7 +77,10 @@ async function localLogin<TSlug extends keyof GeneratedTypes['collections']>(
}
if (locale) args.req.locale = locale
if (fallbackLocale) args.req.fallbackLocale = fallbackLocale
if (fallbackLocale) {
args.req.fallbackLocale =
typeof fallbackLocaleArg !== 'undefined' ? fallbackLocaleArg : fallbackLocale || defaultLocale
}
return login<TSlug>(args)
}

View File

@@ -6,7 +6,7 @@ import type { GeneratedTypes } from '../../../'
import type { PayloadRequest } from '../../../express/types'
import type { Collection } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import create from '../../operations/create'
export type Resolver<TSlug extends keyof GeneratedTypes['collections']> = (
@@ -29,16 +29,17 @@ export default function createResolver<TSlug extends keyof GeneratedTypes['colle
collection: Collection,
): Resolver<TSlug> {
return async function resolver(_, args, context) {
if (args.locale) {
context.req.locale = args.locale
}
let { req } = context
const locale = req.locale
req = isolateObjectProperty(req, 'locale')
req.locale = args.locale || locale
const options = {
collection,
data: args.data,
depth: 0,
draft: args.draft,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(req, 'transactionID'),
}
const result = await create(options)

View File

@@ -5,7 +5,7 @@ import type { GeneratedTypes } from '../../../'
import type { PayloadRequest } from '../../../express/types'
import type { Collection } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import deleteByID from '../../operations/deleteByID'
export type Resolver<TSlug extends keyof GeneratedTypes['collections']> = (
@@ -24,14 +24,19 @@ export default function getDeleteResolver<TSlug extends keyof GeneratedTypes['co
collection: Collection,
): Resolver<TSlug> {
async function resolver(_, args, context) {
if (args.locale) context.req.locale = args.locale
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
let { req } = context
const locale = req.locale
const fallbackLocale = req.fallbackLocale
req = isolateObjectProperty(req, 'locale')
req = isolateObjectProperty(req, 'fallbackLocale')
req.locale = args.locale || locale
req.fallbackLocale = args.fallbackLocale || fallbackLocale
const options = {
id: args.id,
collection,
depth: 0,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(req, 'transactionID'),
}
const result = await deleteByID(options)

View File

@@ -1,7 +1,7 @@
import type { CollectionPermission, GlobalPermission } from '../../../auth'
import type { PayloadRequest } from '../../../express/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import { docAccess } from '../../operations/docAccess'
export type Resolver = (
@@ -19,7 +19,7 @@ export function docAccessResolver(): Resolver {
async function resolver(_, args, context) {
return docAccess({
id: args.id,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
})
}

View File

@@ -4,7 +4,7 @@ import type { PayloadRequest } from '../../../express/types'
import type { Where } from '../../../types'
import type { Collection } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import find from '../../operations/find'
export type Resolver = (
@@ -28,8 +28,13 @@ export type Resolver = (
export default function findResolver(collection: Collection): Resolver {
return async function resolver(_, args, context) {
if (args.locale) context.req.locale = args.locale
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
let { req } = context
const locale = req.locale
const fallbackLocale = req.fallbackLocale
req = isolateObjectProperty(req, 'locale')
req = isolateObjectProperty(req, 'fallbackLocale')
req.locale = args.locale || locale
req.fallbackLocale = args.fallbackLocale || fallbackLocale
const options = {
collection,
@@ -37,7 +42,7 @@ export default function findResolver(collection: Collection): Resolver {
draft: args.draft,
limit: args.limit,
page: args.page,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(req, 'transactionID'),
sort: args.sort,
where: args.where,
}

View File

@@ -2,7 +2,7 @@ import type { GeneratedTypes } from '../../../'
import type { PayloadRequest } from '../../../express/types'
import type { Collection } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import findByID from '../../operations/findByID'
export type Resolver<T> = (
@@ -23,16 +23,20 @@ export default function findByIDResolver<T extends keyof GeneratedTypes['collect
collection: Collection,
): Resolver<GeneratedTypes['collections'][T]> {
return async function resolver(_, args, context) {
const { req } = context
if (args.locale) req.locale = args.locale
if (args.fallbackLocale) req.fallbackLocale = args.fallbackLocale
let { req } = context
const locale = req.locale
const fallbackLocale = req.fallbackLocale
req = isolateObjectProperty(req, 'locale')
req = isolateObjectProperty(req, 'fallbackLocale')
req.locale = args.locale || locale
req.fallbackLocale = args.fallbackLocale || fallbackLocale
const options = {
id: args.id,
collection,
depth: 0,
draft: args.draft,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(req, 'transactionID'),
}
const result = await findByID(options)

View File

@@ -5,7 +5,7 @@ import type { PayloadRequest } from '../../../express/types'
import type { TypeWithVersion } from '../../../versions/types'
import type { Collection, TypeWithID } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import findVersionByID from '../../operations/findVersionByID'
export type Resolver<T extends TypeWithID = any> = (
@@ -24,15 +24,20 @@ export type Resolver<T extends TypeWithID = any> = (
export default function findVersionByIDResolver(collection: Collection): Resolver {
return async function resolver(_, args, context) {
if (args.locale) context.req.locale = args.locale
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
let { req } = context
const locale = req.locale
const fallbackLocale = req.fallbackLocale
req = isolateObjectProperty(req, 'locale')
req = isolateObjectProperty(req, 'fallbackLocale')
req.locale = args.locale || locale
req.fallbackLocale = args.fallbackLocale || fallbackLocale
const options = {
id: args.id,
collection,
depth: 0,
draft: args.draft,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(req, 'transactionID'),
}
const result = await findVersionByID(options)

View File

@@ -7,7 +7,7 @@ import type { PayloadRequest } from '../../../express/types'
import type { Where } from '../../../types'
import type { Collection } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import findVersions from '../../operations/findVersions'
export type Resolver = (
@@ -28,15 +28,20 @@ export type Resolver = (
export default function findVersionsResolver(collection: Collection): Resolver {
async function resolver(_, args, context) {
if (args.locale) context.req.locale = args.locale
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
let { req } = context
const locale = req.locale
const fallbackLocale = req.fallbackLocale
req = isolateObjectProperty(req, 'locale')
req = isolateObjectProperty(req, 'fallbackLocale')
req.locale = args.locale || locale
req.fallbackLocale = args.fallbackLocale || fallbackLocale
const options = {
collection,
depth: 0,
limit: args.limit,
page: args.page,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(req, 'transactionID'),
sort: args.sort,
where: args.where,
}

View File

@@ -4,7 +4,7 @@ import type { Response } from 'express'
import type { PayloadRequest } from '../../../express/types'
import type { Collection } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import restoreVersion from '../../operations/restoreVersion'
export type Resolver = (
@@ -24,7 +24,7 @@ export default function restoreVersionResolver(collection: Collection): Resolver
id: args.id,
collection,
depth: 0,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
}
const result = await restoreVersion(options)

View File

@@ -5,7 +5,7 @@ import type { GeneratedTypes } from '../../../'
import type { PayloadRequest } from '../../../express/types'
import type { Collection } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import updateByID from '../../operations/updateByID'
export type Resolver<TSlug extends keyof GeneratedTypes['collections']> = (
@@ -27,8 +27,13 @@ export default function updateResolver<TSlug extends keyof GeneratedTypes['colle
collection: Collection,
): Resolver<TSlug> {
async function resolver(_, args, context) {
if (args.locale) context.req.locale = args.locale
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
let { req } = context
const locale = req.locale
const fallbackLocale = req.fallbackLocale
req = isolateObjectProperty(req, 'locale')
req = isolateObjectProperty(req, 'fallbackLocale')
req.locale = args.locale || locale
req.fallbackLocale = args.fallbackLocale || fallbackLocale
const options = {
id: args.id,
@@ -37,7 +42,7 @@ export default function updateResolver<TSlug extends keyof GeneratedTypes['colle
data: args.data,
depth: 0,
draft: args.draft,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(req, 'transactionID'),
}
const result = await updateByID<TSlug>(options)

View File

@@ -49,10 +49,10 @@ export default async function createLocal<TSlug extends keyof GeneratedTypes['co
depth,
disableVerificationEmail,
draft,
fallbackLocale,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
file,
filePath,
locale = null,
locale: localeArg = null,
overrideAccess = true,
overwriteExistingFiles = false,
req = {} as PayloadRequest,
@@ -62,8 +62,11 @@ export default async function createLocal<TSlug extends keyof GeneratedTypes['co
setRequestContext(req, context)
const collection = payload.collections[collectionSlug]
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
const localizationConfig = payload?.config?.localization
const defaultLocale = localizationConfig ? localizationConfig.defaultLocale : null
const locale = localeArg || req.locale || defaultLocale
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!collection) {
@@ -73,8 +76,9 @@ export default async function createLocal<TSlug extends keyof GeneratedTypes['co
}
req.payloadAPI = req.payloadAPI || 'local'
req.locale = locale ?? req?.locale ?? defaultLocale
req.fallbackLocale = fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale
req.locale = locale
req.fallbackLocale =
typeof fallbackLocaleArg !== 'undefined' ? fallbackLocaleArg : fallbackLocale || defaultLocale
req.payload = payload
req.i18n = i18nInit(payload.config.i18n)
req.files = {

View File

@@ -61,18 +61,21 @@ async function deleteLocal<TSlug extends keyof GeneratedTypes['collections']>(
collection: collectionSlug,
context,
depth,
fallbackLocale,
locale = null,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
locale: localeArg = null,
overrideAccess = true,
req: incomingReq,
req: incomingReq = {} as PayloadRequest,
showHiddenFields,
user,
where,
} = options
const collection = payload.collections[collectionSlug]
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
const localizationConfig = payload?.config?.localization
const defaultLocale = localizationConfig ? localizationConfig.defaultLocale : null
const locale = localeArg || incomingReq?.locale || defaultLocale
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!collection) {
@@ -82,9 +85,12 @@ async function deleteLocal<TSlug extends keyof GeneratedTypes['collections']>(
}
const req = {
fallbackLocale: typeof fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale,
fallbackLocale:
typeof fallbackLocaleArg !== 'undefined'
? fallbackLocaleArg
: fallbackLocale || defaultLocale,
i18n: i18nInit(payload.config.i18n),
locale: locale ?? defaultLocale,
locale: locale,
payload,
payloadAPI: 'local',
transactionID: incomingReq?.transactionID,

View File

@@ -44,9 +44,9 @@ export default async function findLocal<T extends keyof GeneratedTypes['collecti
depth,
disableErrors,
draft = false,
fallbackLocale,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
limit,
locale = null,
locale: localeArg = null,
overrideAccess = true,
page,
pagination = true,
@@ -59,8 +59,11 @@ export default async function findLocal<T extends keyof GeneratedTypes['collecti
setRequestContext(req, context)
const collection = payload.collections[collectionSlug]
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
const localizationConfig = payload?.config?.localization
const defaultLocale = localizationConfig ? localizationConfig.defaultLocale : null
const locale = localeArg || req.locale || defaultLocale
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!collection) {
@@ -69,19 +72,10 @@ export default async function findLocal<T extends keyof GeneratedTypes['collecti
)
}
let fallbackLocaleToUse = defaultLocale
if (typeof req.fallbackLocale !== 'undefined') {
fallbackLocaleToUse = req.fallbackLocale
}
if (typeof fallbackLocale !== 'undefined') {
fallbackLocaleToUse = fallbackLocale
}
req.payloadAPI = req.payloadAPI || 'local'
req.locale = locale ?? req?.locale ?? defaultLocale
req.fallbackLocale = fallbackLocaleToUse
req.locale = locale
req.fallbackLocale =
typeof fallbackLocaleArg !== 'undefined' ? fallbackLocaleArg : fallbackLocale || defaultLocale
req.i18n = i18nInit(payload.config.i18n)
req.payload = payload

View File

@@ -40,8 +40,8 @@ export default async function findByIDLocal<T extends keyof GeneratedTypes['coll
depth,
disableErrors = false,
draft = false,
fallbackLocale,
locale = null,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
locale: localeArg = null,
overrideAccess = true,
req = {} as PayloadRequest,
showHiddenFields,
@@ -50,8 +50,11 @@ export default async function findByIDLocal<T extends keyof GeneratedTypes['coll
setRequestContext(req, context)
const collection = payload.collections[collectionSlug]
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
const localizationConfig = payload?.config?.localization
const defaultLocale = localizationConfig ? localizationConfig.defaultLocale : null
const locale = localeArg || req.locale || defaultLocale
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!collection) {
@@ -60,19 +63,10 @@ export default async function findByIDLocal<T extends keyof GeneratedTypes['coll
)
}
let fallbackLocaleToUse = defaultLocale
if (typeof req.fallbackLocale !== 'undefined') {
fallbackLocaleToUse = req.fallbackLocale
}
if (typeof fallbackLocale !== 'undefined') {
fallbackLocaleToUse = fallbackLocale
}
req.payloadAPI = req.payloadAPI || 'local'
req.locale = locale ?? req?.locale ?? defaultLocale
req.fallbackLocale = fallbackLocaleToUse
req.locale = locale
req.fallbackLocale =
typeof fallbackLocaleArg !== 'undefined' ? fallbackLocaleArg : fallbackLocale || defaultLocale
req.i18n = i18nInit(payload.config.i18n)
req.payload = payload

View File

@@ -38,8 +38,8 @@ export default async function findVersionByIDLocal<T extends keyof GeneratedType
context,
depth,
disableErrors = false,
fallbackLocale,
locale = null,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
locale: localeArg = null,
overrideAccess = true,
req = {} as PayloadRequest,
showHiddenFields,
@@ -47,8 +47,11 @@ export default async function findVersionByIDLocal<T extends keyof GeneratedType
setRequestContext(req, context)
const collection = payload.collections[collectionSlug]
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
const localizationConfig = payload?.config?.localization
const defaultLocale = localizationConfig ? localizationConfig.defaultLocale : null
const locale = localeArg || req.locale || defaultLocale
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!collection) {
@@ -59,19 +62,10 @@ export default async function findVersionByIDLocal<T extends keyof GeneratedType
)
}
let fallbackLocaleToUse = defaultLocale
if (typeof req.fallbackLocale !== 'undefined') {
fallbackLocaleToUse = req.fallbackLocale
}
if (typeof fallbackLocale !== 'undefined') {
fallbackLocaleToUse = fallbackLocale
}
req.payloadAPI = req.payloadAPI || 'local'
req.locale = locale ?? req?.locale ?? defaultLocale
req.fallbackLocale = fallbackLocaleToUse
req.locale = locale
req.fallbackLocale =
typeof fallbackLocaleArg !== 'undefined' ? fallbackLocaleArg : fallbackLocale || defaultLocale
req.i18n = i18nInit(payload.config.i18n)
req.payload = payload

View File

@@ -39,9 +39,9 @@ export default async function findVersionsLocal<T extends keyof GeneratedTypes['
collection: collectionSlug,
context,
depth,
fallbackLocale,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
limit,
locale = null,
locale: localeArg = null,
overrideAccess = true,
page,
req: incomingReq,
@@ -52,8 +52,11 @@ export default async function findVersionsLocal<T extends keyof GeneratedTypes['
} = options
const collection = payload.collections[collectionSlug]
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
const localizationConfig = payload?.config?.localization
const defaultLocale = localizationConfig ? localizationConfig.defaultLocale : null
const locale = localeArg || incomingReq?.locale || defaultLocale
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!collection) {
@@ -64,9 +67,12 @@ export default async function findVersionsLocal<T extends keyof GeneratedTypes['
const i18n = i18nInit(payload.config.i18n)
const req = {
fallbackLocale: typeof fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale,
fallbackLocale:
typeof fallbackLocaleArg !== 'undefined'
? fallbackLocaleArg
: fallbackLocale || defaultLocale,
i18n,
locale: locale ?? defaultLocale,
locale,
payload,
payloadAPI: 'local',
transactionID: incomingReq?.transactionID,

View File

@@ -35,8 +35,8 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
collection: collectionSlug,
context,
depth,
fallbackLocale = null,
locale = payload.config.localization ? payload.config.localization?.defaultLocale : null,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
locale: localeArg = null,
overrideAccess = true,
req: incomingReq,
showHiddenFields,
@@ -44,6 +44,12 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
} = options
const collection = payload.collections[collectionSlug]
const localizationConfig = payload?.config?.localization
const defaultLocale = localizationConfig ? localizationConfig.defaultLocale : null
const locale = localeArg || incomingReq?.locale || defaultLocale
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!collection) {
throw new APIError(
@@ -55,7 +61,10 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
const i18n = i18nInit(payload.config.i18n)
const req = {
fallbackLocale,
fallbackLocale:
typeof fallbackLocaleArg !== 'undefined'
? fallbackLocaleArg
: fallbackLocale || defaultLocale,
i18n,
locale,
payload,

View File

@@ -74,10 +74,10 @@ async function updateLocal<TSlug extends keyof GeneratedTypes['collections']>(
data,
depth,
draft,
fallbackLocale,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
file,
filePath,
locale = null,
locale: localeArg = null,
overrideAccess = true,
overwriteExistingFiles = false,
req: incomingReq,
@@ -88,8 +88,11 @@ async function updateLocal<TSlug extends keyof GeneratedTypes['collections']>(
const collection = payload.collections[collectionSlug]
const i18n = i18nInit(payload.config.i18n)
const defaultLocale = payload.config.localization
? payload.config.localization?.defaultLocale
const localizationConfig = payload?.config?.localization
const defaultLocale = localizationConfig ? localizationConfig.defaultLocale : null
const locale = localeArg || incomingReq?.locale || defaultLocale
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!collection) {
@@ -99,7 +102,10 @@ async function updateLocal<TSlug extends keyof GeneratedTypes['collections']>(
}
const req = {
fallbackLocale: typeof fallbackLocale !== 'undefined' ? fallbackLocale : defaultLocale,
fallbackLocale:
typeof fallbackLocaleArg !== 'undefined'
? fallbackLocaleArg
: fallbackLocale || defaultLocale,
files: {
file: file ?? (await getFileByPath(filePath)),
},

View File

@@ -138,6 +138,7 @@ export default joi.object({
joi.array().items(
joi.object().keys({
code: joi.string(),
fallbackLocale: joi.string(),
label: joi
.alternatives()
.try(

View File

@@ -11,11 +11,7 @@ import type { DeepRequired } from 'ts-essentials'
import type { InlineConfig } from 'vite'
import type { Configuration } from 'webpack'
import type {
DocumentTab,
DocumentTabComponent,
DocumentTabConfig,
} from '../admin/components/elements/DocumentHeader/Tabs/types'
import type { DocumentTab } from '../admin/components/elements/DocumentHeader/Tabs/types'
import type { RichTextAdapter } from '../admin/components/forms/field-types/RichText/types'
import type { ContextType } from '../admin/components/utilities/DocumentInfo/types'
import type { User } from '../auth/types'
@@ -291,6 +287,10 @@ export type Locale = {
* @example "en"
*/
code: string
/**
* Code of another locale to use when reading documents with fallback, if not specified defaultLocale is used
*/
fallbackLocale?: string
/**
* label of supported locale
* @example "English"

View File

@@ -116,8 +116,8 @@ export interface BaseDatabaseAdapter {
sessions?: {
[id: string]: {
db: unknown
reject: () => void
resolve: () => void
reject: () => Promise<void>
resolve: () => Promise<void>
}
}

View File

@@ -48,15 +48,15 @@ const middleware = (payload: Payload): any => {
qsMiddleware({ arrayLimit: 1000, depth: 10 }),
bodyParser.urlencoded({ extended: true }),
compression(payload.config.express.compression),
localizationMiddleware(payload.config.localization),
localizationMiddleware,
express.json(payload.config.express.json),
fileUpload({
parseNested: true,
...payload.config.upload,
}),
convertPayload,
corsHeaders(payload.config),
authenticate(payload.config),
corsHeaders(payload.config),
...(payload.config.express.middleware || []),
...(payload.config.express.postMiddleware || []),
]

View File

@@ -174,6 +174,7 @@ export const json = baseField.keys({
Error: componentSchema,
Label: componentSchema,
}),
editorOptions: joi.object().unknown(), // Editor['options'] @monaco-editor/react
}),
defaultValue: joi.alternatives().try(joi.array(), joi.object()),
type: joi.string().valid('json').required(),

View File

@@ -2,7 +2,7 @@ import type { CollectionPermission, GlobalPermission } from '../../../auth'
import type { PayloadRequest } from '../../../express/types'
import type { SanitizedGlobalConfig } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import { docAccess } from '../../operations/docAccess'
export type Resolver = (
@@ -17,7 +17,7 @@ export function docAccessResolver(global: SanitizedGlobalConfig): Resolver {
async function resolver(_, context) {
return docAccess({
globalConfig: global,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
})
}

View File

@@ -3,7 +3,7 @@
import type { Document } from '../../../types'
import type { SanitizedGlobalConfig } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import findOne from '../../operations/findOne'
export default function findOneResolver(globalConfig: SanitizedGlobalConfig): Document {
@@ -17,7 +17,7 @@ export default function findOneResolver(globalConfig: SanitizedGlobalConfig): Do
depth: 0,
draft: args.draft,
globalConfig,
req: isolateTransactionID(context.req),
req: isolateObjectProperty(context.req, 'transactionID'),
slug,
}

View File

@@ -5,7 +5,7 @@ import type { PayloadRequest } from '../../../express/types'
import type { Document } from '../../../types'
import type { SanitizedGlobalConfig } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import findVersionByID from '../../operations/findVersionByID'
export type Resolver = (
@@ -32,7 +32,7 @@ export default function findVersionByIDResolver(globalConfig: SanitizedGlobalCon
depth: 0,
draft: args.draft,
globalConfig,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
}
const result = await findVersionByID(options)

View File

@@ -4,7 +4,7 @@ import type { PayloadRequest } from '../../../express/types'
import type { Document, Where } from '../../../types'
import type { SanitizedGlobalConfig } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import findVersions from '../../operations/findVersions'
export type Resolver = (
@@ -30,7 +30,7 @@ export default function findVersionsResolver(globalConfig: SanitizedGlobalConfig
globalConfig,
limit: args.limit,
page: args.page,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
sort: args.sort,
where: args.where,
}

View File

@@ -4,7 +4,7 @@ import type { PayloadRequest } from '../../../express/types'
import type { Document } from '../../../types'
import type { SanitizedGlobalConfig } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import restoreVersion from '../../operations/restoreVersion'
type Resolver = (
@@ -23,7 +23,7 @@ export default function restoreVersionResolver(globalConfig: SanitizedGlobalConf
id: args.id,
depth: 0,
globalConfig,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
}
const result = await restoreVersion(options)

View File

@@ -5,7 +5,7 @@ import type { GeneratedTypes } from '../../../'
import type { PayloadRequest } from '../../../express/types'
import type { SanitizedGlobalConfig } from '../../config/types'
import isolateTransactionID from '../../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../../utilities/isolateObjectProperty'
import update from '../../operations/update'
type Resolver<TSlug extends keyof GeneratedTypes['globals']> = (
@@ -36,7 +36,7 @@ export default function updateResolver<TSlug extends keyof GeneratedTypes['globa
depth: 0,
draft: args.draft,
globalConfig,
req: isolateTransactionID(context.req),
req: isolateObjectProperty<PayloadRequest>(context.req, 'transactionID'),
slug,
}

View File

@@ -30,7 +30,7 @@ export default async function findOneLocal<T extends keyof GeneratedTypes['globa
context,
depth,
draft = false,
fallbackLocale = null,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
locale = payload.config.localization ? payload.config.localization?.defaultLocale : null,
overrideAccess = true,
showHiddenFields,
@@ -39,9 +39,13 @@ export default async function findOneLocal<T extends keyof GeneratedTypes['globa
} = options
const globalConfig = payload.globals.config.find((config) => config.slug === globalSlug)
const localizationConfig = payload?.config?.localization
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
: null
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
if (!globalConfig) {
throw new APIError(`The global with slug ${String(globalSlug)} can't be found.`)
@@ -50,7 +54,10 @@ export default async function findOneLocal<T extends keyof GeneratedTypes['globa
const i18n = i18nInit(payload.config.i18n)
const req = {
fallbackLocale: fallbackLocale ?? options.req?.fallbackLocale ?? defaultLocale,
fallbackLocale:
typeof fallbackLocaleArg !== 'undefined'
? fallbackLocaleArg
: fallbackLocale || defaultLocale,
i18n,
locale: locale ?? options.req?.locale ?? defaultLocale,
payload,

View File

@@ -33,7 +33,7 @@ export default async function findVersionByIDLocal<T extends keyof GeneratedType
context,
depth,
disableErrors = false,
fallbackLocale = null,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
locale = payload.config.localization ? payload.config.localization?.defaultLocale : null,
overrideAccess = true,
req: incomingReq,
@@ -43,6 +43,13 @@ export default async function findVersionByIDLocal<T extends keyof GeneratedType
} = options
const globalConfig = payload.globals.config.find((config) => config.slug === globalSlug)
const localizationConfig = payload?.config?.localization
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
: null
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
const i18n = i18nInit(payload.config.i18n)
if (!globalConfig) {
@@ -50,7 +57,10 @@ export default async function findVersionByIDLocal<T extends keyof GeneratedType
}
const req = {
fallbackLocale,
fallbackLocale:
typeof fallbackLocaleArg !== 'undefined'
? fallbackLocaleArg
: fallbackLocale || defaultLocale,
i18n,
locale,
payload,

View File

@@ -34,7 +34,7 @@ export default async function findVersionsLocal<T extends keyof GeneratedTypes['
const {
context,
depth,
fallbackLocale = null,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
limit,
locale = payload.config.localization ? payload.config.localization?.defaultLocale : null,
overrideAccess = true,
@@ -48,6 +48,13 @@ export default async function findVersionsLocal<T extends keyof GeneratedTypes['
} = options
const globalConfig = payload.globals.config.find((config) => config.slug === globalSlug)
const localizationConfig = payload?.config?.localization
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
: null
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
const i18n = i18nInit(payload.config.i18n)
if (!globalConfig) {
@@ -55,7 +62,10 @@ export default async function findVersionsLocal<T extends keyof GeneratedTypes['
}
const req = {
fallbackLocale,
fallbackLocale:
typeof fallbackLocaleArg !== 'undefined'
? fallbackLocaleArg
: fallbackLocale || defaultLocale,
i18n,
locale,
payload,

View File

@@ -30,7 +30,7 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
id,
context,
depth,
fallbackLocale = null,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
locale = payload.config.localization ? payload.config.localization?.defaultLocale : null,
overrideAccess = true,
req: incomingReq,
@@ -40,6 +40,13 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
} = options
const globalConfig = payload.globals.config.find((config) => config.slug === globalSlug)
const localizationConfig = payload?.config?.localization
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
: null
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
const i18n = i18nInit(payload.config.i18n)
if (!globalConfig) {
@@ -47,7 +54,10 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
}
const req = {
fallbackLocale,
fallbackLocale:
typeof fallbackLocaleArg !== 'undefined'
? fallbackLocaleArg
: fallbackLocale || defaultLocale,
i18n,
locale,
payload,

View File

@@ -34,7 +34,7 @@ export default async function updateLocal<TSlug extends keyof GeneratedTypes['gl
data,
depth,
draft,
fallbackLocale = null,
fallbackLocale: fallbackLocaleArg = options?.req?.fallbackLocale,
locale = payload.config.localization ? payload.config.localization?.defaultLocale : null,
overrideAccess = true,
req: incomingReq,
@@ -44,6 +44,13 @@ export default async function updateLocal<TSlug extends keyof GeneratedTypes['gl
} = options
const globalConfig = payload.globals.config.find((config) => config.slug === globalSlug)
const localizationConfig = payload?.config?.localization
const defaultLocale = payload?.config?.localization
? payload?.config?.localization?.defaultLocale
: null
const fallbackLocale = localizationConfig
? localizationConfig.locales.find(({ code }) => locale === code)?.fallbackLocale
: null
const i18n = i18nInit(payload.config.i18n)
if (!globalConfig) {
@@ -51,7 +58,10 @@ export default async function updateLocal<TSlug extends keyof GeneratedTypes['gl
}
const req = {
fallbackLocale,
fallbackLocale:
typeof fallbackLocaleArg !== 'undefined'
? fallbackLocaleArg
: fallbackLocale || defaultLocale,
i18n,
locale,
payload,

View File

@@ -22,7 +22,6 @@ export default function registerGraphQLSchema(payload: Payload): void {
blockInputTypes: {},
blockTypes: {},
groupTypes: {},
tabTypes: {},
}
if (payload.config.localization) {

View File

@@ -508,7 +508,7 @@ function buildObjectType({
const interfaceName =
tab?.interfaceName || combineParentName(parentName, toWords(tab.name, true))
if (!payload.types.tabTypes[interfaceName]) {
if (!payload.types.groupTypes[interfaceName]) {
const objectType = buildObjectType({
name: interfaceName,
fields: tab.fields,
@@ -518,16 +518,20 @@ function buildObjectType({
})
if (Object.keys(objectType.getFields()).length) {
return {
...tabSchema,
[tab.name]: { type: objectType },
}
payload.types.groupTypes[interfaceName] = objectType
}
}
if (!payload.types.groupTypes[interfaceName]) {
return tabSchema
}
return {
...tabSchema,
[tab.name]: { type: payload.types.groupTypes[interfaceName] },
}
}
return {
...tabSchema,
...tab.fields.reduce((subFieldSchema, subField) => {

View File

@@ -1,10 +1,9 @@
import type { ObjMap } from 'graphql/jsutils/ObjMap'
import type { GraphQLFieldResolver } from 'graphql/type/definition'
import type { GraphQLFieldConfig } from 'graphql/type/definition'
import type { GraphQLFieldConfig, GraphQLFieldResolver } from 'graphql/type/definition'
import type { PayloadRequest } from '../../express/types'
import isolateTransactionID from '../../utilities/isolateTransactionID'
import isolateObjectProperty from '../../utilities/isolateObjectProperty'
type PayloadContext = { req: PayloadRequest }
@@ -12,7 +11,12 @@ function wrapCustomResolver<TSource, TArgs, TResult>(
resolver: GraphQLFieldResolver<TSource, PayloadContext, TArgs, TResult>,
): GraphQLFieldResolver<TSource, PayloadContext, TArgs, TResult> {
return (source, args, context, info) => {
return resolver(source, args, { ...context, req: isolateTransactionID(context.req) }, info)
return resolver(
source,
args,
{ ...context, req: isolateObjectProperty(context.req, 'transactionID') },
info,
)
}
}

View File

@@ -1,19 +1,18 @@
import type { SanitizedLocalizationConfig } from '../config/types'
/**
* sets request locale
*
* @param localization
* @returns {Function}
*/
export default function localizationMiddleware(localization: SanitizedLocalizationConfig | false) {
const middleware = (req, res, next) => {
if (localization) {
export default function localizationMiddleware(req, res, next) {
const localization = req.payload.config.localization
if (!localization) {
next()
return
}
const validLocales = [...localization.localeCodes, 'all']
const validFallbackLocales = [...localization.localeCodes, 'null']
let requestedLocale = req.query.locale || localization.defaultLocale
let requestedFallbackLocale = req.query['fallback-locale'] || localization.defaultLocale
let requestedFallbackLocale = req.query['fallback-locale']
if (req.body) {
if (req.body.locale) requestedLocale = req.body.locale
@@ -26,18 +25,14 @@ export default function localizationMiddleware(localization: SanitizedLocalizati
if (requestedLocale === '*' || requestedLocale === 'all') {
requestedLocale = 'all'
}
req.fallbackLocale = validFallbackLocales.find((locale) => locale === requestedFallbackLocale)
if (validLocales.find((locale) => locale === requestedLocale)) {
req.locale = requestedLocale
}
req.locale = validLocales.find((locale) => locale === requestedLocale)
if (validFallbackLocales.find((locale) => locale === requestedFallbackLocale)) {
req.fallbackLocale = requestedFallbackLocale
if (!req.fallbackLocale) {
req.fallbackLocale =
localization.locales.find(({ code }) => req.locale === code)?.fallbackLocale ||
localization.defaultLocale
}
}
return next()
}
return middleware
next()
}

View File

@@ -256,7 +256,6 @@ export class BasePayload<TGeneratedTypes extends GeneratedTypes> {
fallbackLocaleInputType?: any
groupTypes: any
localeInputType?: any
tabTypes: any
}
unlock = async <T extends keyof TGeneratedTypes['collections']>(

View File

@@ -5,10 +5,10 @@ import translations from './index'
export const defaultOptions: InitOptions = {
debug: false,
detection: {
caches: ['cookie', 'localStorage'],
caches: ['header', 'cookie', 'localStorage'],
lookupCookie: 'lng',
lookupLocalStorage: 'lng',
order: ['cookie', 'localStorage'],
order: ['header', 'cookie', 'localStorage'],
},
fallbackLng: 'en',
interpolation: {

View File

@@ -0,0 +1,27 @@
/**
* Creates a proxy for the given object that has its own property
*/
export default function isolateObjectProperty<T>(object: T, key): T {
const delegate = {}
const handler = {
deleteProperty(target, p): boolean {
return Reflect.deleteProperty(p === key ? delegate : target, p)
},
get(target, p, receiver) {
return Reflect.get(p === key ? delegate : target, p, receiver)
},
has(target, p) {
return Reflect.has(p === key ? delegate : target, p)
},
set(target, p, newValue, receiver) {
if (p === key) {
// in case of transactionID we must ignore any receiver, because
// "If provided and target does not have a setter for propertyKey, the property will be set on receiver instead."
return Reflect.set(delegate, p, newValue)
} else {
return Reflect.set(target, p, newValue, receiver)
}
},
}
return new Proxy(object, handler)
}

View File

@@ -1,29 +0,0 @@
import type { PayloadRequest } from '../express/types'
/**
* Creates a proxy for the given request that has its own TransactionID
*/
export default function isolateTransactionID(req: PayloadRequest): PayloadRequest {
const delegate = {}
const handler: ProxyHandler<PayloadRequest> = {
deleteProperty(target, p): boolean {
return Reflect.deleteProperty(p === 'transactionID' ? delegate : target, p)
},
get(target, p, receiver) {
return Reflect.get(p === 'transactionID' ? delegate : target, p, receiver)
},
has(target, p) {
return Reflect.has(p === 'transactionID' ? delegate : target, p)
},
set(target, p, newValue, receiver) {
if (p === 'transactionID') {
// in case of transactionID we must ignore any receiver, because
// "If provided and target does not have a setter for propertyKey, the property will be set on receiver instead."
return Reflect.set(delegate, p, newValue)
} else {
return Reflect.set(target, p, newValue, receiver)
}
},
}
return new Proxy(req, handler)
}

View File

@@ -22,7 +22,7 @@
"@aws-sdk/credential-providers": "^3.289.0",
"@aws-sdk/lib-storage": "^3.267.0",
"amazon-cognito-identity-js": "^6.1.2",
"nodemailer": "^6.9.1",
"nodemailer": "6.9.8",
"resend": "^0.17.2"
},
"devDependencies": {

View File

@@ -1,7 +1,7 @@
{
"name": "@payloadcms/plugin-form-builder",
"description": "Form builder plugin for Payload CMS",
"version": "1.0.15",
"version": "1.1.0",
"homepage:": "https://payloadcms.com",
"repository": "git@github.com:payloadcms/plugin-form-builder.git",
"main": "dist/index.js",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-nested-docs",
"version": "1.0.9",
"version": "1.0.10",
"description": "The official Nested Docs plugin for Payload",
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",

View File

@@ -19,7 +19,7 @@ const Search =
// write any config defaults here
}
// add a beforeChange hook to every search-enabled collection
// add afterChange and afterDelete hooks to every search-enabled collection
const collectionsWithSearchHooks = config?.collections
?.map((collection) => {
const { hooks: existingHooks } = collection

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/richtext-lexical",
"version": "0.4.1",
"version": "0.5.0",
"description": "The officially supported Lexical richtext adapter for Payload",
"repository": "https://github.com/payloadcms/payload",
"license": "MIT",

View File

@@ -3,7 +3,6 @@
.rich-text-lexical {
.editor {
position: relative;
z-index: 1;
}
.editor-shell {

View File

@@ -6,7 +6,6 @@
tab-size: 1;
outline: 0;
padding-top: 8px;
isolation: isolate;
&:focus-visible {
outline: none !important;

281
pnpm-lock.yaml generated
View File

@@ -435,9 +435,12 @@ importers:
get-port:
specifier: 5.1.1
version: 5.1.1
http-status:
specifier: 1.6.2
version: 1.6.2
mongoose:
specifier: 6.12.0
version: 6.12.0
specifier: 6.12.3
version: 6.12.3
mongoose-aggregate-paginate-v2:
specifier: 1.0.6
version: 1.0.6
@@ -457,6 +460,9 @@ importers:
'@types/mongoose-aggregate-paginate-v2':
specifier: 1.0.9
version: 1.0.9
mongodb:
specifier: 4.17.1
version: 4.17.1
mongodb-memory-server:
specifier: 8.13.0
version: 8.13.0
@@ -742,8 +748,8 @@ importers:
specifier: 0.38.0
version: 0.38.0
nodemailer:
specifier: 6.9.4
version: 6.9.4
specifier: 6.9.8
version: 6.9.8
object-to-formdata:
specifier: 4.5.1
version: 4.5.1
@@ -1061,8 +1067,8 @@ importers:
specifier: ^6.1.2
version: 6.3.6
nodemailer:
specifier: ^6.9.1
version: 6.9.4
specifier: 6.9.8
version: 6.9.8
resend:
specifier: ^0.17.2
version: 0.17.2
@@ -1520,7 +1526,7 @@ packages:
'@aws-crypto/sha256-js': 3.0.0
'@aws-crypto/supports-web-crypto': 3.0.0
'@aws-crypto/util': 3.0.0
'@aws-sdk/types': 3.413.0
'@aws-sdk/types': 3.425.0
'@aws-sdk/util-locate-window': 3.310.0
'@aws-sdk/util-utf8-browser': 3.259.0
tslib: 1.14.1
@@ -1529,7 +1535,7 @@ packages:
resolution: {integrity: sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==}
dependencies:
'@aws-crypto/util': 1.2.2
'@aws-sdk/types': 3.413.0
'@aws-sdk/types': 3.425.0
tslib: 1.14.1
dev: false
@@ -1550,7 +1556,7 @@ packages:
/@aws-crypto/util@1.2.2:
resolution: {integrity: sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==}
dependencies:
'@aws-sdk/types': 3.413.0
'@aws-sdk/types': 3.425.0
'@aws-sdk/util-utf8-browser': 3.259.0
tslib: 1.14.1
dev: false
@@ -1559,7 +1565,7 @@ packages:
resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==}
requiresBuild: true
dependencies:
'@aws-sdk/types': 3.413.0
'@aws-sdk/types': 3.425.0
'@aws-sdk/util-utf8-browser': 3.259.0
tslib: 1.14.1
@@ -1686,27 +1692,27 @@ packages:
'@aws-sdk/util-endpoints': 3.413.0
'@aws-sdk/util-user-agent-browser': 3.413.0
'@aws-sdk/util-user-agent-node': 3.413.0
'@smithy/config-resolver': 2.0.9
'@smithy/fetch-http-handler': 2.1.4
'@smithy/hash-node': 2.0.8
'@smithy/invalid-dependency': 2.0.8
'@smithy/middleware-content-length': 2.0.10
'@smithy/middleware-endpoint': 2.0.8
'@smithy/middleware-retry': 2.0.11
'@smithy/middleware-serde': 2.0.8
'@smithy/middleware-stack': 2.0.1
'@smithy/node-config-provider': 2.0.11
'@smithy/node-http-handler': 2.1.4
'@smithy/protocol-http': 3.0.4
'@smithy/smithy-client': 2.1.5
'@smithy/types': 2.3.2
'@smithy/url-parser': 2.0.8
'@smithy/config-resolver': 2.0.14
'@smithy/fetch-http-handler': 2.2.3
'@smithy/hash-node': 2.0.11
'@smithy/invalid-dependency': 2.0.11
'@smithy/middleware-content-length': 2.0.13
'@smithy/middleware-endpoint': 2.1.0
'@smithy/middleware-retry': 2.0.16
'@smithy/middleware-serde': 2.0.11
'@smithy/middleware-stack': 2.0.5
'@smithy/node-config-provider': 2.1.1
'@smithy/node-http-handler': 2.1.7
'@smithy/protocol-http': 3.0.7
'@smithy/smithy-client': 2.1.11
'@smithy/types': 2.3.5
'@smithy/url-parser': 2.0.11
'@smithy/util-base64': 2.0.0
'@smithy/util-body-length-browser': 2.0.0
'@smithy/util-body-length-node': 2.1.0
'@smithy/util-defaults-mode-browser': 2.0.9
'@smithy/util-defaults-mode-node': 2.0.11
'@smithy/util-retry': 2.0.1
'@smithy/util-defaults-mode-browser': 2.0.15
'@smithy/util-defaults-mode-node': 2.0.19
'@smithy/util-retry': 2.0.4
'@smithy/util-utf8': 2.0.0
tslib: 2.6.2
transitivePeerDependencies:
@@ -1785,7 +1791,7 @@ packages:
'@smithy/node-http-handler': 2.1.4
'@smithy/protocol-http': 3.0.4
'@smithy/smithy-client': 2.1.5
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/url-parser': 2.0.8
'@smithy/util-base64': 2.0.0
'@smithy/util-body-length-browser': 2.0.0
@@ -1851,8 +1857,8 @@ packages:
dependencies:
'@aws-sdk/client-cognito-identity': 3.414.0
'@aws-sdk/types': 3.413.0
'@smithy/property-provider': 2.0.9
'@smithy/types': 2.3.2
'@smithy/property-provider': 2.0.12
'@smithy/types': 2.3.5
tslib: 2.6.2
transitivePeerDependencies:
- aws-crt
@@ -1863,8 +1869,8 @@ packages:
requiresBuild: true
dependencies:
'@aws-sdk/types': 3.413.0
'@smithy/property-provider': 2.0.9
'@smithy/types': 2.3.2
'@smithy/property-provider': 2.0.12
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/credential-provider-env@3.425.0:
@@ -1872,7 +1878,7 @@ packages:
engines: {node: '>=14.0.0'}
dependencies:
'@aws-sdk/types': 3.425.0
'@smithy/property-provider': 2.0.9
'@smithy/property-provider': 2.0.12
'@smithy/types': 2.3.5
tslib: 2.6.2
@@ -1886,10 +1892,10 @@ packages:
'@aws-sdk/credential-provider-sso': 3.414.0
'@aws-sdk/credential-provider-web-identity': 3.413.0
'@aws-sdk/types': 3.413.0
'@smithy/credential-provider-imds': 2.0.11
'@smithy/property-provider': 2.0.9
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/types': 2.3.2
'@smithy/credential-provider-imds': 2.0.16
'@smithy/property-provider': 2.0.12
'@smithy/shared-ini-file-loader': 2.2.0
'@smithy/types': 2.3.5
tslib: 2.6.2
transitivePeerDependencies:
- aws-crt
@@ -1903,9 +1909,9 @@ packages:
'@aws-sdk/credential-provider-sso': 3.427.0
'@aws-sdk/credential-provider-web-identity': 3.425.0
'@aws-sdk/types': 3.425.0
'@smithy/credential-provider-imds': 2.0.11
'@smithy/property-provider': 2.0.9
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/credential-provider-imds': 2.0.16
'@smithy/property-provider': 2.0.12
'@smithy/shared-ini-file-loader': 2.2.0
'@smithy/types': 2.3.5
tslib: 2.6.2
transitivePeerDependencies:
@@ -1922,10 +1928,10 @@ packages:
'@aws-sdk/credential-provider-sso': 3.414.0
'@aws-sdk/credential-provider-web-identity': 3.413.0
'@aws-sdk/types': 3.413.0
'@smithy/credential-provider-imds': 2.0.11
'@smithy/property-provider': 2.0.9
'@smithy/credential-provider-imds': 2.0.16
'@smithy/property-provider': 2.0.12
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
transitivePeerDependencies:
- aws-crt
@@ -1940,8 +1946,8 @@ packages:
'@aws-sdk/credential-provider-sso': 3.427.0
'@aws-sdk/credential-provider-web-identity': 3.425.0
'@aws-sdk/types': 3.425.0
'@smithy/credential-provider-imds': 2.0.11
'@smithy/property-provider': 2.0.9
'@smithy/credential-provider-imds': 2.0.16
'@smithy/property-provider': 2.0.12
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/types': 2.3.5
tslib: 2.6.2
@@ -1954,9 +1960,9 @@ packages:
requiresBuild: true
dependencies:
'@aws-sdk/types': 3.413.0
'@smithy/property-provider': 2.0.9
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/types': 2.3.2
'@smithy/property-provider': 2.0.12
'@smithy/shared-ini-file-loader': 2.2.0
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/credential-provider-process@3.425.0:
@@ -1964,8 +1970,8 @@ packages:
engines: {node: '>=14.0.0'}
dependencies:
'@aws-sdk/types': 3.425.0
'@smithy/property-provider': 2.0.9
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/property-provider': 2.0.12
'@smithy/shared-ini-file-loader': 2.2.0
'@smithy/types': 2.3.5
tslib: 2.6.2
@@ -1977,9 +1983,9 @@ packages:
'@aws-sdk/client-sso': 3.414.0
'@aws-sdk/token-providers': 3.413.0
'@aws-sdk/types': 3.413.0
'@smithy/property-provider': 2.0.9
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/types': 2.3.2
'@smithy/property-provider': 2.0.12
'@smithy/shared-ini-file-loader': 2.2.0
'@smithy/types': 2.3.5
tslib: 2.6.2
transitivePeerDependencies:
- aws-crt
@@ -1991,8 +1997,8 @@ packages:
'@aws-sdk/client-sso': 3.427.0
'@aws-sdk/token-providers': 3.427.0
'@aws-sdk/types': 3.425.0
'@smithy/property-provider': 2.0.9
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/property-provider': 2.0.12
'@smithy/shared-ini-file-loader': 2.2.0
'@smithy/types': 2.3.5
tslib: 2.6.2
transitivePeerDependencies:
@@ -2004,8 +2010,8 @@ packages:
requiresBuild: true
dependencies:
'@aws-sdk/types': 3.413.0
'@smithy/property-provider': 2.0.9
'@smithy/types': 2.3.2
'@smithy/property-provider': 2.0.12
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/credential-provider-web-identity@3.425.0:
@@ -2013,7 +2019,7 @@ packages:
engines: {node: '>=14.0.0'}
dependencies:
'@aws-sdk/types': 3.425.0
'@smithy/property-provider': 2.0.9
'@smithy/property-provider': 2.0.12
'@smithy/types': 2.3.5
tslib: 2.6.2
@@ -2096,7 +2102,7 @@ packages:
dependencies:
'@aws-sdk/types': 3.413.0
'@smithy/protocol-http': 3.0.4
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/middleware-host-header@3.425.0:
@@ -2122,7 +2128,7 @@ packages:
requiresBuild: true
dependencies:
'@aws-sdk/types': 3.413.0
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/middleware-logger@3.425.0:
@@ -2140,7 +2146,7 @@ packages:
dependencies:
'@aws-sdk/types': 3.413.0
'@smithy/protocol-http': 3.0.4
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/middleware-recursion-detection@3.425.0:
@@ -2170,7 +2176,7 @@ packages:
dependencies:
'@aws-sdk/middleware-signing': 3.413.0
'@aws-sdk/types': 3.413.0
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/middleware-sdk-sts@3.425.0:
@@ -2188,10 +2194,10 @@ packages:
requiresBuild: true
dependencies:
'@aws-sdk/types': 3.413.0
'@smithy/property-provider': 2.0.9
'@smithy/property-provider': 2.0.12
'@smithy/protocol-http': 3.0.4
'@smithy/signature-v4': 2.0.8
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/util-middleware': 2.0.1
tslib: 2.6.2
@@ -2200,7 +2206,7 @@ packages:
engines: {node: '>=14.0.0'}
dependencies:
'@aws-sdk/types': 3.425.0
'@smithy/property-provider': 2.0.9
'@smithy/property-provider': 2.0.12
'@smithy/protocol-http': 3.0.7
'@smithy/signature-v4': 2.0.8
'@smithy/types': 2.3.5
@@ -2223,7 +2229,7 @@ packages:
'@aws-sdk/types': 3.413.0
'@aws-sdk/util-endpoints': 3.413.0
'@smithy/protocol-http': 3.0.4
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/middleware-user-agent@3.427.0:
@@ -2242,7 +2248,7 @@ packages:
requiresBuild: true
dependencies:
'@smithy/node-config-provider': 2.0.11
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/util-config-provider': 2.0.0
'@smithy/util-middleware': 2.0.1
tslib: 2.6.2
@@ -2282,29 +2288,29 @@ packages:
'@aws-sdk/util-endpoints': 3.413.0
'@aws-sdk/util-user-agent-browser': 3.413.0
'@aws-sdk/util-user-agent-node': 3.413.0
'@smithy/config-resolver': 2.0.9
'@smithy/fetch-http-handler': 2.1.4
'@smithy/hash-node': 2.0.8
'@smithy/invalid-dependency': 2.0.8
'@smithy/middleware-content-length': 2.0.10
'@smithy/middleware-endpoint': 2.0.8
'@smithy/middleware-retry': 2.0.11
'@smithy/middleware-serde': 2.0.8
'@smithy/middleware-stack': 2.0.1
'@smithy/node-config-provider': 2.0.11
'@smithy/node-http-handler': 2.1.4
'@smithy/property-provider': 2.0.9
'@smithy/protocol-http': 3.0.4
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/smithy-client': 2.1.5
'@smithy/types': 2.3.2
'@smithy/url-parser': 2.0.8
'@smithy/config-resolver': 2.0.14
'@smithy/fetch-http-handler': 2.2.3
'@smithy/hash-node': 2.0.11
'@smithy/invalid-dependency': 2.0.11
'@smithy/middleware-content-length': 2.0.13
'@smithy/middleware-endpoint': 2.1.0
'@smithy/middleware-retry': 2.0.16
'@smithy/middleware-serde': 2.0.11
'@smithy/middleware-stack': 2.0.5
'@smithy/node-config-provider': 2.1.1
'@smithy/node-http-handler': 2.1.7
'@smithy/property-provider': 2.0.12
'@smithy/protocol-http': 3.0.7
'@smithy/shared-ini-file-loader': 2.2.0
'@smithy/smithy-client': 2.1.11
'@smithy/types': 2.3.5
'@smithy/url-parser': 2.0.11
'@smithy/util-base64': 2.0.0
'@smithy/util-body-length-browser': 2.0.0
'@smithy/util-body-length-node': 2.1.0
'@smithy/util-defaults-mode-browser': 2.0.9
'@smithy/util-defaults-mode-node': 2.0.11
'@smithy/util-retry': 2.0.1
'@smithy/util-defaults-mode-browser': 2.0.15
'@smithy/util-defaults-mode-node': 2.0.19
'@smithy/util-retry': 2.0.4
'@smithy/util-utf8': 2.0.0
tslib: 2.6.2
transitivePeerDependencies:
@@ -2335,9 +2341,9 @@ packages:
'@smithy/middleware-stack': 2.0.5
'@smithy/node-config-provider': 2.1.1
'@smithy/node-http-handler': 2.1.7
'@smithy/property-provider': 2.0.9
'@smithy/property-provider': 2.0.12
'@smithy/protocol-http': 3.0.7
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/shared-ini-file-loader': 2.2.0
'@smithy/smithy-client': 2.1.11
'@smithy/types': 2.3.5
'@smithy/url-parser': 2.0.11
@@ -2357,7 +2363,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/types@3.425.0:
@@ -2401,7 +2407,7 @@ packages:
requiresBuild: true
dependencies:
'@aws-sdk/types': 3.413.0
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
bowser: 2.11.0
tslib: 2.6.2
@@ -2425,7 +2431,7 @@ packages:
dependencies:
'@aws-sdk/types': 3.413.0
'@smithy/node-config-provider': 2.0.11
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@aws-sdk/util-user-agent-node@3.425.0:
@@ -4730,7 +4736,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/chunked-blob-reader-native@2.0.0:
@@ -4760,7 +4766,7 @@ packages:
requiresBuild: true
dependencies:
'@smithy/node-config-provider': 2.0.11
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/util-config-provider': 2.0.0
'@smithy/util-middleware': 2.0.1
tslib: 2.6.2
@@ -4771,8 +4777,8 @@ packages:
requiresBuild: true
dependencies:
'@smithy/node-config-provider': 2.0.11
'@smithy/property-provider': 2.0.9
'@smithy/types': 2.3.2
'@smithy/property-provider': 2.0.12
'@smithy/types': 2.3.5
'@smithy/url-parser': 2.0.8
tslib: 2.6.2
@@ -4794,15 +4800,6 @@ packages:
'@smithy/util-hex-encoding': 2.0.0
tslib: 2.6.2
/@smithy/eventstream-codec@2.0.8:
resolution: {integrity: sha512-onO4to8ujCKn4m5XagReT9Nc6FlNG5vveuvjp1H7AtaG7njdet1LOl6/jmUOkskF2C/w+9jNw3r9Ak+ghOvN0A==}
requiresBuild: true
dependencies:
'@aws-crypto/crc32': 3.0.0
'@smithy/types': 2.3.2
'@smithy/util-hex-encoding': 2.0.0
tslib: 2.6.2
/@smithy/eventstream-serde-browser@2.0.11:
resolution: {integrity: sha512-p9IK4uvwT6B3pT1VGlODvcVBfPVikjBFHAcKpvvNF+7lAEI+YiC6d0SROPkpjnvCgVBYyGXa3ciqrWnFze6mwQ==}
engines: {node: '>=14.0.0'}
@@ -4840,7 +4837,7 @@ packages:
dependencies:
'@smithy/protocol-http': 3.0.4
'@smithy/querystring-builder': 2.0.8
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/util-base64': 2.0.0
tslib: 2.6.2
@@ -4875,7 +4872,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/util-buffer-from': 2.0.0
'@smithy/util-utf8': 2.0.0
tslib: 2.6.2
@@ -4898,7 +4895,7 @@ packages:
resolution: {integrity: sha512-88VOS7W3KzUz/bNRc+Sl/F/CDIasFspEE4G39YZRHIh9YmsXF7GUyVaAKURfMNulTie62ayk6BHC9O0nOBAVgQ==}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/is-array-buffer@2.0.0:
@@ -4921,7 +4918,7 @@ packages:
requiresBuild: true
dependencies:
'@smithy/protocol-http': 3.0.4
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/middleware-content-length@2.0.13:
@@ -4938,7 +4935,7 @@ packages:
requiresBuild: true
dependencies:
'@smithy/middleware-serde': 2.0.8
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/url-parser': 2.0.8
'@smithy/util-middleware': 2.0.1
tslib: 2.6.2
@@ -4962,7 +4959,7 @@ packages:
'@smithy/node-config-provider': 2.0.11
'@smithy/protocol-http': 3.0.4
'@smithy/service-error-classification': 2.0.1
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/util-middleware': 2.0.1
'@smithy/util-retry': 2.0.1
tslib: 2.6.2
@@ -4993,7 +4990,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/middleware-stack@2.0.1:
@@ -5001,7 +4998,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/middleware-stack@2.0.5:
@@ -5016,9 +5013,9 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/property-provider': 2.0.9
'@smithy/property-provider': 2.0.12
'@smithy/shared-ini-file-loader': 2.0.10
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/node-config-provider@2.1.1:
@@ -5038,7 +5035,7 @@ packages:
'@smithy/abort-controller': 2.0.8
'@smithy/protocol-http': 3.0.4
'@smithy/querystring-builder': 2.0.8
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/node-http-handler@2.1.7:
@@ -5063,7 +5060,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/protocol-http@3.0.4:
@@ -5071,7 +5068,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/protocol-http@3.0.7:
@@ -5094,7 +5091,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/util-uri-escape': 2.0.0
tslib: 2.6.2
@@ -5110,7 +5107,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/service-error-classification@2.0.1:
@@ -5131,7 +5128,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/shared-ini-file-loader@2.2.0:
@@ -5146,11 +5143,11 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/eventstream-codec': 2.0.8
'@smithy/eventstream-codec': 2.0.11
'@smithy/is-array-buffer': 2.0.0
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/util-hex-encoding': 2.0.0
'@smithy/util-middleware': 2.0.1
'@smithy/util-middleware': 2.0.4
'@smithy/util-uri-escape': 2.0.0
'@smithy/util-utf8': 2.0.0
tslib: 2.6.2
@@ -5170,7 +5167,7 @@ packages:
requiresBuild: true
dependencies:
'@smithy/middleware-stack': 2.0.1
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
'@smithy/util-stream': 2.0.11
tslib: 2.6.2
@@ -5199,7 +5196,7 @@ packages:
requiresBuild: true
dependencies:
'@smithy/querystring-parser': 2.0.8
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/util-base64@2.0.0:
@@ -5253,9 +5250,9 @@ packages:
engines: {node: '>= 10.0.0'}
requiresBuild: true
dependencies:
'@smithy/property-provider': 2.0.9
'@smithy/property-provider': 2.0.12
'@smithy/smithy-client': 2.1.5
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
bowser: 2.11.0
tslib: 2.6.2
@@ -5265,11 +5262,11 @@ packages:
requiresBuild: true
dependencies:
'@smithy/config-resolver': 2.0.9
'@smithy/credential-provider-imds': 2.0.11
'@smithy/credential-provider-imds': 2.0.16
'@smithy/node-config-provider': 2.0.11
'@smithy/property-provider': 2.0.9
'@smithy/property-provider': 2.0.12
'@smithy/smithy-client': 2.1.5
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/util-defaults-mode-node@2.0.19:
@@ -5296,7 +5293,7 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/util-middleware@2.0.4:
@@ -5312,7 +5309,7 @@ packages:
requiresBuild: true
dependencies:
'@smithy/service-error-classification': 2.0.1
'@smithy/types': 2.3.2
'@smithy/types': 2.3.5
tslib: 2.6.2
/@smithy/util-retry@2.0.4:
@@ -5328,9 +5325,9 @@ packages:
engines: {node: '>=14.0.0'}
requiresBuild: true
dependencies:
'@smithy/fetch-http-handler': 2.1.4
'@smithy/node-http-handler': 2.1.4
'@smithy/types': 2.3.2
'@smithy/fetch-http-handler': 2.2.3
'@smithy/node-http-handler': 2.1.7
'@smithy/types': 2.3.5
'@smithy/util-base64': 2.0.0
'@smithy/util-buffer-from': 2.0.0
'@smithy/util-hex-encoding': 2.0.0
@@ -6017,7 +6014,7 @@ packages:
/@types/mongoose-aggregate-paginate-v2@1.0.9:
resolution: {integrity: sha512-YKDKtSuE1vzMY/SAtlDTWJr52UhTYdrOypCqyx7T2xFYEWfybLnV98m4ZoVgYJH0XowVl7Y2Gnn6p1sF+3NbLA==}
dependencies:
mongoose: 6.12.0
mongoose: 6.12.3
transitivePeerDependencies:
- aws-crt
- supports-color
@@ -13424,8 +13421,8 @@ packages:
engines: {node: '>=4.0.0'}
dev: false
/mongoose@6.12.0:
resolution: {integrity: sha512-sd/q83C6TBRPBrrD2A/POSbA/exbCFM2WOuY7Lf2JuIJFlHFG39zYSDTTAEiYlzIfahNOLmXPxBGFxdAch41Mw==}
/mongoose@6.12.3:
resolution: {integrity: sha512-MNJymaaXali7w7rHBxVUoQ3HzHHMk/7I/+yeeoSa4rUzdjZwIWQznBNvVgc0A8ghuJwsuIkb5LyLV6gSjGjWyQ==}
engines: {node: '>=12.0.0'}
dependencies:
bson: 4.7.2
@@ -13596,8 +13593,8 @@ packages:
/node-releases@2.0.13:
resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
/nodemailer@6.9.4:
resolution: {integrity: sha512-CXjQvrQZV4+6X5wP6ZIgdehJamI63MFoYFGGPtHudWym9qaEHDNdPzaj5bfMCvxG1vhAileSWW90q7nL0N36mA==}
/nodemailer@6.9.8:
resolution: {integrity: sha512-cfrYUk16e67Ks051i4CntM9kshRYei1/o/Gi8K1d+R34OIs21xdFnW7Pt7EucmVKA0LKtqUGNcjMZ7ehjl49mQ==}
engines: {node: '>=6.0.0'}
dev: false

View File

@@ -80,6 +80,7 @@ export const Card: React.FC<{
{showCategories && hasCategories && (
<div>
{categories?.map((category, index) => {
if (typeof category === 'object' && category !== null) {
const { title: titleFromCategory } = category
const categoryTitle = titleFromCategory || 'Untitled category'
@@ -92,6 +93,9 @@ export const Card: React.FC<{
{!isLast && <Fragment>, &nbsp;</Fragment>}
</Fragment>
)
}
return null
})}
</div>
)}

View File

@@ -13,7 +13,7 @@ import { Pagination } from '../Pagination'
import classes from './index.module.scss'
type Result = {
docs: Product[]
docs: (Product | string)[]
hasNextPage: boolean
hasPrevPage: boolean
nextPage: number
@@ -75,7 +75,9 @@ export const CollectionArchive: React.FC<Props> = props => {
const isRequesting = useRef(false)
const [page, setPage] = useState(1)
const categories = (catsFromProps || []).map(cat => cat.id).join(',')
const categories = (catsFromProps || [])
.map(cat => (typeof cat === 'object' ? cat?.id : cat))
.join(',')
const scrollToRef = useCallback(() => {
const { current } = scrollRef
@@ -182,11 +184,15 @@ export const CollectionArchive: React.FC<Props> = props => {
<Gutter>
<div className={classes.grid}>
{results.docs?.map((result, index) => {
if (typeof result === 'object' && result !== null) {
return (
<div className={classes.column} key={index}>
<Card doc={result} relationTo={relationTo} showCategories />
</div>
)
}
return null
})}
</div>
{results.totalPages > 1 && populateBy !== 'selection' && (

View File

@@ -46,6 +46,7 @@ export const ProductHero: React.FC<{
<div className={classes.content}>
<div className={classes.categories}>
{categories?.map((category, index) => {
if (typeof category === 'object' && category !== null) {
const { title: categoryTitle } = category
const titleToUse = categoryTitle || 'Untitled category'
@@ -58,6 +59,9 @@ export const ProductHero: React.FC<{
{!isLast && <Fragment>, &nbsp;</Fragment>}
</Fragment>
)
}
return null
})}
</div>
<h1 className={classes.title}>{title}</h1>

View File

@@ -6,11 +6,13 @@
* and re-run `payload generate:types` to regenerate this file.
*/
export type CartItems = {
product?: string | Product
quantity?: number
id?: string
}[]
export type CartItems =
| {
product?: (string | null) | Product
quantity?: number | null
id?: string | null
}[]
| null
export interface Config {
collections: {
@@ -33,403 +35,407 @@ export interface Config {
export interface Page {
id: string
title: string
publishedOn?: string
publishedOn?: string | null
hero: {
type: 'none' | 'highImpact' | 'mediumImpact' | 'lowImpact'
richText: {
[k: string]: unknown
}[]
links?: {
links?:
| {
link: {
type?: 'reference' | 'custom'
newTab?: boolean
reference: {
type?: ('reference' | 'custom') | null
newTab?: boolean | null
reference?: {
relationTo: 'pages'
value: string | Page
}
url: string
} | null
url?: string | null
label: string
appearance?: 'default' | 'primary' | 'secondary'
appearance?: ('default' | 'primary' | 'secondary') | null
}
id?: string
id?: string | null
}[]
media: string | Media
| null
media?: string | Media | null
}
layout: (
| {
invertBackground?: boolean
invertBackground?: boolean | null
richText: {
[k: string]: unknown
}[]
links?: {
links?:
| {
link: {
type?: 'reference' | 'custom'
newTab?: boolean
reference: {
type?: ('reference' | 'custom') | null
newTab?: boolean | null
reference?: {
relationTo: 'pages'
value: string | Page
}
url: string
} | null
url?: string | null
label: string
appearance?: 'primary' | 'secondary'
appearance?: ('primary' | 'secondary') | null
}
id?: string
id?: string | null
}[]
id?: string
blockName?: string
| null
id?: string | null
blockName?: string | null
blockType: 'cta'
}
| {
invertBackground?: boolean
columns?: {
size?: 'oneThird' | 'half' | 'twoThirds' | 'full'
invertBackground?: boolean | null
columns?:
| {
size?: ('oneThird' | 'half' | 'twoThirds' | 'full') | null
richText: {
[k: string]: unknown
}[]
enableLink?: boolean
enableLink?: boolean | null
link?: {
type?: 'reference' | 'custom'
newTab?: boolean
reference: {
type?: ('reference' | 'custom') | null
newTab?: boolean | null
reference?: {
relationTo: 'pages'
value: string | Page
}
url: string
} | null
url?: string | null
label: string
appearance?: 'default' | 'primary' | 'secondary'
appearance?: ('default' | 'primary' | 'secondary') | null
}
id?: string
id?: string | null
}[]
id?: string
blockName?: string
| null
id?: string | null
blockName?: string | null
blockType: 'content'
}
| {
invertBackground?: boolean
position?: 'default' | 'fullscreen'
invertBackground?: boolean | null
position?: ('default' | 'fullscreen') | null
media: string | Media
id?: string
blockName?: string
id?: string | null
blockName?: string | null
blockType: 'mediaBlock'
}
| {
introContent: {
[k: string]: unknown
}[]
populateBy?: 'collection' | 'selection'
relationTo?: 'products'
categories?: string[] | Category[]
limit?: number
populateBy?: ('collection' | 'selection') | null
relationTo?: 'products' | null
categories?: (string | Category)[] | null
limit?: number | null
selectedDocs?:
| {
relationTo: 'products'
value: string
}[]
| {
relationTo: 'products'
value: Product
value: string | Product
}[]
| null
populatedDocs?:
| {
relationTo: 'products'
value: string
value: string | Product
}[]
| {
relationTo: 'products'
value: Product
}[]
populatedDocsTotal?: number
id?: string
blockName?: string
| null
populatedDocsTotal?: number | null
id?: string | null
blockName?: string | null
blockType: 'archive'
}
)[]
slug?: string
slug?: string | null
meta?: {
title?: string
description?: string
image?: string | Media
title?: string | null
description?: string | null
image?: string | Media | null
}
updatedAt: string
createdAt: string
_status?: 'draft' | 'published'
_status?: ('draft' | 'published') | null
}
export interface Media {
id: string
alt: string
caption?: {
caption?:
| {
[k: string]: unknown
}[]
| null
updatedAt: string
createdAt: string
url?: string
filename?: string
mimeType?: string
filesize?: number
width?: number
height?: number
url?: string | null
filename?: string | null
mimeType?: string | null
filesize?: number | null
width?: number | null
height?: number | null
}
export interface Category {
id: string
title?: string
parent?: string | Category
breadcrumbs?: {
doc?: string | Category
url?: string
label?: string
id?: string
title?: string | null
parent?: (string | null) | Category
breadcrumbs?:
| {
doc?: (string | null) | Category
url?: string | null
label?: string | null
id?: string | null
}[]
| null
updatedAt: string
createdAt: string
}
export interface Product {
id: string
title: string
publishedOn?: string
publishedOn?: string | null
layout: (
| {
invertBackground?: boolean
invertBackground?: boolean | null
richText: {
[k: string]: unknown
}[]
links?: {
links?:
| {
link: {
type?: 'reference' | 'custom'
newTab?: boolean
reference: {
type?: ('reference' | 'custom') | null
newTab?: boolean | null
reference?: {
relationTo: 'pages'
value: string | Page
}
url: string
} | null
url?: string | null
label: string
appearance?: 'primary' | 'secondary'
appearance?: ('primary' | 'secondary') | null
}
id?: string
id?: string | null
}[]
id?: string
blockName?: string
| null
id?: string | null
blockName?: string | null
blockType: 'cta'
}
| {
invertBackground?: boolean
columns?: {
size?: 'oneThird' | 'half' | 'twoThirds' | 'full'
invertBackground?: boolean | null
columns?:
| {
size?: ('oneThird' | 'half' | 'twoThirds' | 'full') | null
richText: {
[k: string]: unknown
}[]
enableLink?: boolean
enableLink?: boolean | null
link?: {
type?: 'reference' | 'custom'
newTab?: boolean
reference: {
type?: ('reference' | 'custom') | null
newTab?: boolean | null
reference?: {
relationTo: 'pages'
value: string | Page
}
url: string
} | null
url?: string | null
label: string
appearance?: 'default' | 'primary' | 'secondary'
appearance?: ('default' | 'primary' | 'secondary') | null
}
id?: string
id?: string | null
}[]
id?: string
blockName?: string
| null
id?: string | null
blockName?: string | null
blockType: 'content'
}
| {
invertBackground?: boolean
position?: 'default' | 'fullscreen'
invertBackground?: boolean | null
position?: ('default' | 'fullscreen') | null
media: string | Media
id?: string
blockName?: string
id?: string | null
blockName?: string | null
blockType: 'mediaBlock'
}
| {
introContent: {
[k: string]: unknown
}[]
populateBy?: 'collection' | 'selection'
relationTo?: 'products'
categories?: string[] | Category[]
limit?: number
populateBy?: ('collection' | 'selection') | null
relationTo?: 'products' | null
categories?: (string | Category)[] | null
limit?: number | null
selectedDocs?:
| {
relationTo: 'products'
value: string
}[]
| {
relationTo: 'products'
value: Product
value: string | Product
}[]
| null
populatedDocs?:
| {
relationTo: 'products'
value: string
value: string | Product
}[]
| {
relationTo: 'products'
value: Product
}[]
populatedDocsTotal?: number
id?: string
blockName?: string
| null
populatedDocsTotal?: number | null
id?: string | null
blockName?: string | null
blockType: 'archive'
}
)[]
stripeProductID?: string
priceJSON?: string
enablePaywall?: boolean
paywall?: (
stripeProductID?: string | null
priceJSON?: string | null
enablePaywall?: boolean | null
paywall?:
| (
| {
invertBackground?: boolean
invertBackground?: boolean | null
richText: {
[k: string]: unknown
}[]
links?: {
links?:
| {
link: {
type?: 'reference' | 'custom'
newTab?: boolean
reference: {
type?: ('reference' | 'custom') | null
newTab?: boolean | null
reference?: {
relationTo: 'pages'
value: string | Page
}
url: string
} | null
url?: string | null
label: string
appearance?: 'primary' | 'secondary'
appearance?: ('primary' | 'secondary') | null
}
id?: string
id?: string | null
}[]
id?: string
blockName?: string
| null
id?: string | null
blockName?: string | null
blockType: 'cta'
}
| {
invertBackground?: boolean
columns?: {
size?: 'oneThird' | 'half' | 'twoThirds' | 'full'
invertBackground?: boolean | null
columns?:
| {
size?: ('oneThird' | 'half' | 'twoThirds' | 'full') | null
richText: {
[k: string]: unknown
}[]
enableLink?: boolean
enableLink?: boolean | null
link?: {
type?: 'reference' | 'custom'
newTab?: boolean
reference: {
type?: ('reference' | 'custom') | null
newTab?: boolean | null
reference?: {
relationTo: 'pages'
value: string | Page
}
url: string
} | null
url?: string | null
label: string
appearance?: 'default' | 'primary' | 'secondary'
appearance?: ('default' | 'primary' | 'secondary') | null
}
id?: string
id?: string | null
}[]
id?: string
blockName?: string
| null
id?: string | null
blockName?: string | null
blockType: 'content'
}
| {
invertBackground?: boolean
position?: 'default' | 'fullscreen'
invertBackground?: boolean | null
position?: ('default' | 'fullscreen') | null
media: string | Media
id?: string
blockName?: string
id?: string | null
blockName?: string | null
blockType: 'mediaBlock'
}
| {
introContent: {
[k: string]: unknown
}[]
populateBy?: 'collection' | 'selection'
relationTo?: 'products'
categories?: string[] | Category[]
limit?: number
populateBy?: ('collection' | 'selection') | null
relationTo?: 'products' | null
categories?: (string | Category)[] | null
limit?: number | null
selectedDocs?:
| {
relationTo: 'products'
value: string
}[]
| {
relationTo: 'products'
value: Product
value: string | Product
}[]
| null
populatedDocs?:
| {
relationTo: 'products'
value: string
value: string | Product
}[]
| {
relationTo: 'products'
value: Product
}[]
populatedDocsTotal?: number
id?: string
blockName?: string
| null
populatedDocsTotal?: number | null
id?: string | null
blockName?: string | null
blockType: 'archive'
}
)[]
categories?: string[] | Category[]
relatedProducts?: string[] | Product[]
slug?: string
skipSync?: boolean
| null
categories?: (string | Category)[] | null
relatedProducts?: (string | Product)[] | null
slug?: string | null
skipSync?: boolean | null
meta?: {
title?: string
description?: string
image?: string | Media
title?: string | null
description?: string | null
image?: string | Media | null
}
updatedAt: string
createdAt: string
_status?: 'draft' | 'published'
_status?: ('draft' | 'published') | null
}
export interface Order {
id: string
orderedBy?: string | User
stripePaymentIntentID?: string
orderedBy?: (string | null) | User
stripePaymentIntentID?: string | null
total: number
items?: {
items?:
| {
product: string | Product
price?: number
quantity?: number
id?: string
price?: number | null
quantity?: number | null
id?: string | null
}[]
| null
updatedAt: string
createdAt: string
}
export interface User {
id: string
name?: string
roles?: ('admin' | 'customer')[]
purchases?: string[] | Product[]
stripeCustomerID?: string
name?: string | null
roles?: ('admin' | 'customer')[] | null
purchases?: (string | Product)[] | null
stripeCustomerID?: string | null
cart?: {
items?: CartItems
}
skipSync?: boolean
skipSync?: boolean | null
updatedAt: string
createdAt: string
email: string
resetPasswordToken?: string
resetPasswordExpiration?: string
salt?: string
hash?: string
loginAttempts?: number
lockUntil?: string
password?: string
resetPasswordToken?: string | null
resetPasswordExpiration?: string | null
salt?: string | null
hash?: string | null
loginAttempts?: number | null
lockUntil?: string | null
password: string | null
}
export interface Redirect {
id: string
from: string
to: {
type?: 'reference' | 'custom'
reference:
| {
to?: {
type?: ('reference' | 'custom') | null
reference?:
| ({
relationTo: 'pages'
value: string | Page
}
| {
} | null)
| ({
relationTo: 'products'
value: string | Product
}
url: string
} | null)
url?: string | null
}
updatedAt: string
createdAt: string
@@ -440,7 +446,7 @@ export interface PayloadPreference {
relationTo: 'users'
value: string | User
}
key?: string
key?: string | null
value?:
| {
[k: string]: unknown
@@ -455,71 +461,58 @@ export interface PayloadPreference {
}
export interface PayloadMigration {
id: string
name?: string
batch?: number
name?: string | null
batch?: number | null
updatedAt: string
createdAt: string
}
export interface Settings {
id: string
productsPage?: string | Page
updatedAt?: string
createdAt?: string
productsPage?: (string | null) | Page
updatedAt?: string | null
createdAt?: string | null
}
export interface Header {
id: string
navItems?: {
navItems?:
| {
link: {
type?: 'reference' | 'custom'
newTab?: boolean
reference: {
type?: ('reference' | 'custom') | null
newTab?: boolean | null
reference?: {
relationTo: 'pages'
value: string | Page
}
url: string
} | null
url?: string | null
label: string
}
id?: string
id?: string | null
}[]
updatedAt?: string
createdAt?: string
| null
updatedAt?: string | null
createdAt?: string | null
}
export interface Footer {
id: string
navItems?: {
navItems?:
| {
link: {
type?: 'reference' | 'custom'
newTab?: boolean
reference: {
type?: ('reference' | 'custom') | null
newTab?: boolean | null
reference?: {
relationTo: 'pages'
value: string | Page
}
url: string
} | null
url?: string | null
label: string
}
id?: string
id?: string | null
}[]
updatedAt?: string
createdAt?: string
| null
updatedAt?: string | null
createdAt?: string | null
}
declare module 'payload' {
export interface GeneratedTypes {
collections: {
pages: Page
products: Product
orders: Order
media: Media
categories: Category
users: User
redirects: Redirect
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
globals: {
settings: Settings
header: Header
footer: Footer
}
}
export interface GeneratedTypes extends Config {}
}

View File

@@ -51,6 +51,7 @@ export const Card: React.FC<{
{showCategories && hasCategories && (
<div>
{categories?.map((category, index) => {
if (typeof category === 'object') {
const { title: titleFromCategory } = category
const categoryTitle = titleFromCategory || 'Untitled category'
@@ -63,6 +64,9 @@ export const Card: React.FC<{
{!isLast && <Fragment>, &nbsp;</Fragment>}
</Fragment>
)
}
return null
})}
</div>
)}

View File

@@ -13,7 +13,7 @@ import { Pagination } from '../Pagination'
import classes from './index.module.scss'
type Result = {
docs: (Post | Project)[]
docs: (Post | Project | string)[]
hasNextPage: boolean
hasPrevPage: boolean
nextPage: number
@@ -75,7 +75,9 @@ export const CollectionArchive: React.FC<Props> = props => {
const isRequesting = useRef(false)
const [page, setPage] = useState(1)
const categories = (catsFromProps || []).map(cat => cat.id).join(',')
const categories = (catsFromProps || [])
.map(cat => (typeof cat === 'object' ? cat.id : cat))
.join(',')
const scrollToRef = useCallback(() => {
const { current } = scrollRef
@@ -182,11 +184,15 @@ export const CollectionArchive: React.FC<Props> = props => {
<Gutter>
<div className={classes.grid}>
{results.docs?.map((result, index) => {
if (typeof result === 'object' && result !== null) {
return (
<div className={classes.column} key={index}>
<Card doc={result} relationTo={relationTo} showCategories />
</div>
)
}
return null
})}
</div>
{results.totalPages > 1 && populateBy !== 'selection' && (

View File

@@ -28,6 +28,7 @@ export const PostHero: React.FC<{
<div className={classes.leader}>
<div className={classes.categories}>
{categories?.map((category, index) => {
if (typeof category === 'object' && category !== null) {
const { title: categoryTitle } = category
const titleToUse = categoryTitle || 'Untitled category'
@@ -40,6 +41,8 @@ export const PostHero: React.FC<{
{!isLast && <Fragment>, &nbsp;</Fragment>}
</Fragment>
)
}
return null
})}
</div>
</div>

View File

@@ -23,6 +23,7 @@ export const ProjectHero: React.FC<{
{createdAt && formatDateTime(createdAt)}
&nbsp; &mdash; &nbsp;
{categories?.map((category, index) => {
if (typeof category === 'object' && category !== null) {
const { title: categoryTitle } = category
const titleToUse = categoryTitle || 'Untitled category'
@@ -35,6 +36,9 @@ export const ProjectHero: React.FC<{
{!isLast && <Fragment>, &nbsp;</Fragment>}
</Fragment>
)
}
return null
})}
</div>
</div>

File diff suppressed because it is too large Load Diff

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