Compare commits
2169 Commits
db-postgre
...
example/ss
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c58a0cd1e9 | ||
|
|
d679d1f400 | ||
|
|
3de264b750 | ||
|
|
2d4651d474 | ||
|
|
0f306da63b | ||
|
|
ba9ea5c752 | ||
|
|
53b7d6f89f | ||
|
|
f5fb095df4 | ||
|
|
721919fae9 | ||
|
|
d3e27e87fe | ||
|
|
e1ff92e8c6 | ||
|
|
ac5d744914 | ||
|
|
b94a265fad | ||
|
|
1ba3a92745 | ||
|
|
9814fd705e | ||
|
|
20455f4fc2 | ||
|
|
9f37bf7397 | ||
|
|
892b884745 | ||
|
|
e8dd0a7daf | ||
|
|
26151e39c9 | ||
|
|
453e331014 | ||
|
|
7f72006020 | ||
|
|
3c13df3c2d | ||
|
|
d31af813e2 | ||
|
|
a85dc66a39 | ||
|
|
9492f0ae29 | ||
|
|
51149c75ff | ||
|
|
56bedb821f | ||
|
|
d3bca574aa | ||
|
|
c462bf229f | ||
|
|
8a452c42af | ||
|
|
07f2d74dc3 | ||
|
|
2ce65dc1e0 | ||
|
|
37be06448c | ||
|
|
9c13089a2f | ||
|
|
b642cb2d93 | ||
|
|
9e5d521567 | ||
|
|
6eabc99e01 | ||
|
|
ea917dd811 | ||
|
|
070d8e1731 | ||
|
|
664c60d2bc | ||
|
|
e25814e1ee | ||
|
|
27ea117731 | ||
|
|
7ab156e117 | ||
|
|
f2d415663f | ||
|
|
bdf08a19d1 | ||
|
|
cb90e9f622 | ||
|
|
b05a5e1fb6 | ||
|
|
92a5da1006 | ||
|
|
75a95469b2 | ||
|
|
c0ae287d46 | ||
|
|
a2b92aa3ff | ||
|
|
544a2285d3 | ||
|
|
8c39950ea3 | ||
|
|
6d642fe9b9 | ||
|
|
f175a741bc | ||
|
|
3290376f80 | ||
|
|
2b5c1ba99a | ||
|
|
bcb3f08386 | ||
|
|
b729b9bebd | ||
|
|
26ee91eb48 | ||
|
|
43a17f67a0 | ||
|
|
c71d2db949 | ||
|
|
04f1df8af1 | ||
|
|
1c490aee42 | ||
|
|
c6132df866 | ||
|
|
d8f91cc94c | ||
|
|
568b074809 | ||
|
|
401c16e485 | ||
|
|
17bee6a145 | ||
|
|
8829fba6cf | ||
|
|
e8983abe65 | ||
|
|
01f38c4e33 | ||
|
|
10b99ceb6f | ||
|
|
1140426b73 | ||
|
|
5a82f34801 | ||
|
|
5420d889fe | ||
|
|
d9bb51fdc7 | ||
|
|
9a636a3cfb | ||
|
|
181f82f33e | ||
|
|
6a9cde24b0 | ||
|
|
dc31d9c715 | ||
|
|
45b3f06e1b | ||
|
|
d5f7944ac4 | ||
|
|
3d50caf985 | ||
|
|
4d7ef58e7e | ||
|
|
3e117f4e99 | ||
|
|
888d6f8856 | ||
|
|
9ebf8693d4 | ||
|
|
d8c3127b09 | ||
|
|
b6631f4778 | ||
|
|
2e77bdf11e | ||
|
|
cce75f11ca | ||
|
|
d8b6b39dbb | ||
|
|
fa89057aac | ||
|
|
15db0a8018 | ||
|
|
b7a4d9cea4 | ||
|
|
5b676c36e5 | ||
|
|
32231762ff | ||
|
|
a7096c1599 | ||
|
|
bed428c27e | ||
|
|
873e698352 | ||
|
|
ad13577399 | ||
|
|
31a9c77055 | ||
|
|
bae0c2df5f | ||
|
|
0ed31def68 | ||
|
|
0e7a6ad5ab | ||
|
|
180797540c | ||
|
|
c00babf9b3 | ||
|
|
943681ae3c | ||
|
|
f14ce367d2 | ||
|
|
3eb5766323 | ||
|
|
cd5e8d7b52 | ||
|
|
361d12e97c | ||
|
|
fb4a5a3715 | ||
|
|
9c2585ba86 | ||
|
|
feb6296bb4 | ||
|
|
74eb71c304 | ||
|
|
fa2083f764 | ||
|
|
7111834a99 | ||
|
|
a943c7eddb | ||
|
|
2d089a7bae | ||
|
|
5bba969f0d | ||
|
|
3a43fd34c0 | ||
|
|
d9005b3f53 | ||
|
|
fab9e32175 | ||
|
|
e71c1c2ec4 | ||
|
|
81fb0515fb | ||
|
|
739dfc1434 | ||
|
|
a4e8795666 | ||
|
|
14134d637d | ||
|
|
2b698a9018 | ||
|
|
91684c8a7d | ||
|
|
fbdfe1d9dd | ||
|
|
7221725121 | ||
|
|
640348df3a | ||
|
|
4ed99e017a | ||
|
|
df6b9dd30b | ||
|
|
faf142baff | ||
|
|
f80cb9f553 | ||
|
|
d3eaa1fceb | ||
|
|
df77152851 | ||
|
|
937202b27c | ||
|
|
3581f39c31 | ||
|
|
c1d9c81b68 | ||
|
|
20355a4dd4 | ||
|
|
cf66d7f09b | ||
|
|
30afe81462 | ||
|
|
18ee6e8867 | ||
|
|
9f78a93403 | ||
|
|
bd046e2437 | ||
|
|
e9004a93a4 | ||
|
|
4816a1638a | ||
|
|
22c53392a3 | ||
|
|
bdaa9e831d | ||
|
|
036bcd6b8f | ||
|
|
4d2bc861cf | ||
|
|
98722dc0fd | ||
|
|
629d7c3263 | ||
|
|
5f7af5317a | ||
|
|
8bb1b60964 | ||
|
|
7ef5493414 | ||
|
|
a3ac838221 | ||
|
|
14400d1cb9 | ||
|
|
7d531646fd | ||
|
|
6f6c1435c7 | ||
|
|
332b8b6f34 | ||
|
|
d40a734080 | ||
|
|
94f1dfef52 | ||
|
|
0857dbe465 | ||
|
|
71f19fba58 | ||
|
|
24b18fb0fd | ||
|
|
5731241a5c | ||
|
|
47e70abb4e | ||
|
|
0ede95f375 | ||
|
|
b723efdd3b | ||
|
|
14c513690d | ||
|
|
88f239e784 | ||
|
|
a1f6bf8a67 | ||
|
|
912dcd38df | ||
|
|
da5028cdee | ||
|
|
899faa62f1 | ||
|
|
9df6a644c9 | ||
|
|
1a6d9eaa11 | ||
|
|
7d447af277 | ||
|
|
d8baaab849 | ||
|
|
3e1523f007 | ||
|
|
fa38af025f | ||
|
|
6ca9ff847f | ||
|
|
a8824b2b51 | ||
|
|
6aa3752b16 | ||
|
|
c483a439bf | ||
|
|
74bdf1c681 | ||
|
|
7437d9fe58 | ||
|
|
51f7351962 | ||
|
|
d01fcb921b | ||
|
|
6179c938bf | ||
|
|
dbbcb658a9 | ||
|
|
16f97ad7c3 | ||
|
|
bc7445ed99 | ||
|
|
e4d024cd0d | ||
|
|
1005de8295 | ||
|
|
c79289cedf | ||
|
|
6a745be036 | ||
|
|
cee9cc33ed | ||
|
|
9a5e9313cd | ||
|
|
5401af5812 | ||
|
|
6305a1d1c2 | ||
|
|
95b96e3e9e | ||
|
|
95b3f6d40d | ||
|
|
c258a4bef1 | ||
|
|
647544a0c6 | ||
|
|
7e0a2a879c | ||
|
|
471e1388ae | ||
|
|
1da430b042 | ||
|
|
56ac06c563 | ||
|
|
4dec4bb61c | ||
|
|
99a09c49a3 | ||
|
|
88fd46bfea | ||
|
|
8a6603b3d8 | ||
|
|
f6c9f454a5 | ||
|
|
d8a5426c37 | ||
|
|
c9011dcbfd | ||
|
|
43089fd13c | ||
|
|
bb3bd9c395 | ||
|
|
ba423ab424 | ||
|
|
c23984cac3 | ||
|
|
6685a0fa7e | ||
|
|
ac4750d016 | ||
|
|
951e9fd7f2 | ||
|
|
cbd1554589 | ||
|
|
80c545933f | ||
|
|
594f319fc6 | ||
|
|
102feb9576 | ||
|
|
68274d2862 | ||
|
|
8945b7a4fa | ||
|
|
d5ef93b2ba | ||
|
|
cb0f0dba3a | ||
|
|
7b263be01b | ||
|
|
56df60f520 | ||
|
|
d5cbbc472d | ||
|
|
d987e5628a | ||
|
|
1383191f15 | ||
|
|
27297284cf | ||
|
|
3af3a91c87 | ||
|
|
23c5b71f95 | ||
|
|
2ee6a8ec3a | ||
|
|
10819b8693 | ||
|
|
83c617b452 | ||
|
|
4acb133655 | ||
|
|
6e4135e790 | ||
|
|
f0198b62f3 | ||
|
|
3ff8063ab8 | ||
|
|
8d52f1b279 | ||
|
|
24072d222c | ||
|
|
55c59e71da | ||
|
|
62233788e0 | ||
|
|
b297c5499d | ||
|
|
fb7925f272 | ||
|
|
221e873862 | ||
|
|
e7143e02e2 | ||
|
|
a1d68bd951 | ||
|
|
93ee452a2d | ||
|
|
1abaa5fc17 | ||
|
|
999059bc61 | ||
|
|
39ba39c237 | ||
|
|
009e6c2066 | ||
|
|
8bf03ae706 | ||
|
|
a2fe3f66e3 | ||
|
|
6cd5b253f1 | ||
|
|
abf0461d80 | ||
|
|
abca45e152 | ||
|
|
58ea94f6ac | ||
|
|
49cba92fa1 | ||
|
|
42329fc736 | ||
|
|
68dee49501 | ||
|
|
234837ee1d | ||
|
|
0d3554d70a | ||
|
|
7f6c6c4787 | ||
|
|
b6c975bfdc | ||
|
|
eaf5a86121 | ||
|
|
b9a9dad60a | ||
|
|
a2afc38894 | ||
|
|
b80c92ba93 | ||
|
|
6669a2cedb | ||
|
|
7369da3d8d | ||
|
|
697a0f1ecf | ||
|
|
3db0557b07 | ||
|
|
8178d57ab9 | ||
|
|
f1b2f767bb | ||
|
|
f21b394d21 | ||
|
|
4e4ccca02a | ||
|
|
b6578d6447 | ||
|
|
abeb94a53d | ||
|
|
974a74500b | ||
|
|
61dd17ae5e | ||
|
|
2628249a51 | ||
|
|
5f57782199 | ||
|
|
bceb49ee6c | ||
|
|
beeb59f263 | ||
|
|
4150c87be0 | ||
|
|
a394d8211e | ||
|
|
6a162776f2 | ||
|
|
d41bd7b133 | ||
|
|
f3409fab29 | ||
|
|
dd75fbfee2 | ||
|
|
ae2c85f947 | ||
|
|
c0b454a5de | ||
|
|
27754dd0d7 | ||
|
|
18ec830882 | ||
|
|
1ffc0f552e | ||
|
|
07b676ac81 | ||
|
|
da79f09544 | ||
|
|
993b035285 | ||
|
|
3f2df643e7 | ||
|
|
42c7649176 | ||
|
|
2722d2f5ce | ||
|
|
f71e61d7d9 | ||
|
|
73c76cab77 | ||
|
|
43e8a533b7 | ||
|
|
ea4203bb32 | ||
|
|
568b5073c8 | ||
|
|
471e1f4827 | ||
|
|
b9185a6fcd | ||
|
|
80496aa94c | ||
|
|
5fd6e3c1a8 | ||
|
|
54590c1700 | ||
|
|
b1259be8f2 | ||
|
|
cd161e4b16 | ||
|
|
cb4214fe6e | ||
|
|
9d42751a42 | ||
|
|
c2c637b359 | ||
|
|
2f446e11d6 | ||
|
|
4f566b088c | ||
|
|
0d40d87b31 | ||
|
|
70fcd6bf40 | ||
|
|
94c0095b3b | ||
|
|
4328060637 | ||
|
|
d98d0fd5bd | ||
|
|
5db2863d08 | ||
|
|
ff5e438d6d | ||
|
|
bfd5f13ee9 | ||
|
|
8043188f36 | ||
|
|
e3e0998772 | ||
|
|
86adc6f282 | ||
|
|
b51b519d30 | ||
|
|
c70dcb6a59 | ||
|
|
2486c7dba0 | ||
|
|
1456fcdcad | ||
|
|
a216800c72 | ||
|
|
c3d8597c13 | ||
|
|
844663ce1a | ||
|
|
055e6af7b7 | ||
|
|
479e6ecddc | ||
|
|
b9456e8244 | ||
|
|
432dfef435 | ||
|
|
429c6f7a48 | ||
|
|
6d41f6c56d | ||
|
|
20ac2b86cf | ||
|
|
b88455166a | ||
|
|
9b86de1f9d | ||
|
|
1393c72281 | ||
|
|
bcb538aee2 | ||
|
|
01e8f8c649 | ||
|
|
1119cf3af9 | ||
|
|
216934145c | ||
|
|
40f952cac3 | ||
|
|
330e4a7724 | ||
|
|
e676503e02 | ||
|
|
06233fbb2f | ||
|
|
17298695b1 | ||
|
|
c1081ccfe2 | ||
|
|
30da5a8643 | ||
|
|
55bf5436e4 | ||
|
|
a4956dc649 | ||
|
|
512b7bd429 | ||
|
|
5119c51439 | ||
|
|
f3e25f3277 | ||
|
|
1275c70187 | ||
|
|
be69fc448d | ||
|
|
bcccefe98e | ||
|
|
2061f38d9e | ||
|
|
d0869d9087 | ||
|
|
1eabf316d6 | ||
|
|
a0dd750a52 | ||
|
|
2fc9885abc | ||
|
|
14d683fb9a | ||
|
|
e286519cb1 | ||
|
|
b1e78a3562 | ||
|
|
0bc103658a | ||
|
|
9037b9b4fa | ||
|
|
d194493e9a | ||
|
|
aa22344cdb | ||
|
|
736e7b822e | ||
|
|
2ebda95036 | ||
|
|
d8783eaad4 | ||
|
|
cddb08de1a | ||
|
|
d4e5d3df54 | ||
|
|
414b03ce74 | ||
|
|
96dbab8834 | ||
|
|
03a110a750 | ||
|
|
6accc705be | ||
|
|
312dca003b | ||
|
|
4f9fdb6c14 | ||
|
|
94af06466b | ||
|
|
7cf2686097 | ||
|
|
f14883aa11 | ||
|
|
9df8de2386 | ||
|
|
8b2cf4705e | ||
|
|
364e9832ac | ||
|
|
2deeb61f17 | ||
|
|
14498e8a9c | ||
|
|
eb78022387 | ||
|
|
3677a59a78 | ||
|
|
7c1c840a59 | ||
|
|
a73eaf5d37 | ||
|
|
68989a58a8 | ||
|
|
9841731ae7 | ||
|
|
ba7ac5d439 | ||
|
|
7c60772b26 | ||
|
|
1141a5d3af | ||
|
|
6f74fd1f98 | ||
|
|
75873bfcfa | ||
|
|
1faf621f17 | ||
|
|
1d1c73dfcc | ||
|
|
d057ce0a85 | ||
|
|
0ce26d2c08 | ||
|
|
abf285d713 | ||
|
|
c2ee8e3999 | ||
|
|
167ba0c68f | ||
|
|
9ad1cbe920 | ||
|
|
313ea52e3d | ||
|
|
3acfb7a83f | ||
|
|
783dae2bbb | ||
|
|
59681b211b | ||
|
|
98438175cf | ||
|
|
af40302e5f | ||
|
|
ec0e0ae449 | ||
|
|
607ff17033 | ||
|
|
e73e610669 | ||
|
|
30fddde066 | ||
|
|
a56d2842fb | ||
|
|
35f59a47cc | ||
|
|
817d57bd12 | ||
|
|
5826048e7b | ||
|
|
1a975b31cf | ||
|
|
73298a80f0 | ||
|
|
a5d14ef4c1 | ||
|
|
d0c79b65f8 | ||
|
|
2fc50b1a1f | ||
|
|
0ddeedb0b3 | ||
|
|
09c2fb10f3 | ||
|
|
5bfff5b7ba | ||
|
|
702088375c | ||
|
|
ea507fbcc4 | ||
|
|
0ff1e6632b | ||
|
|
996ee47f96 | ||
|
|
3e9bd5bb62 | ||
|
|
ee7221c986 | ||
|
|
318c126ae3 | ||
|
|
2154aea89f | ||
|
|
4d3ad1af35 | ||
|
|
75cab7688f | ||
|
|
5084d6dd97 | ||
|
|
518f80cbb6 | ||
|
|
c9399efa65 | ||
|
|
dd9133659c | ||
|
|
d3016b7eb5 | ||
|
|
69e884f5b7 | ||
|
|
6d122905f4 | ||
|
|
e6e016ac2d | ||
|
|
3e7925e33f | ||
|
|
7a2ccba63c | ||
|
|
be2134eb69 | ||
|
|
95e422b0e1 | ||
|
|
53d9c4ca95 | ||
|
|
30948ab545 | ||
|
|
906df6b401 | ||
|
|
b9c585bab5 | ||
|
|
12203140ad | ||
|
|
0704152e38 | ||
|
|
f582efe98d | ||
|
|
540579f520 | ||
|
|
24c348dc49 | ||
|
|
4b4c245507 | ||
|
|
400f68d1aa | ||
|
|
5bb27ed9cd | ||
|
|
833498c269 | ||
|
|
80507d487b | ||
|
|
08f4ebaaf8 | ||
|
|
4c418525eb | ||
|
|
4962f6c926 | ||
|
|
50f0e9298c | ||
|
|
89efcc5db1 | ||
|
|
c3119a5632 | ||
|
|
069bbd92b0 | ||
|
|
c4422a2593 | ||
|
|
3aab9d368e | ||
|
|
b6afab63b2 | ||
|
|
b93f5e9c44 | ||
|
|
630082035f | ||
|
|
c74e41fc76 | ||
|
|
08ce7c58b5 | ||
|
|
1853fde379 | ||
|
|
f29d22ca95 | ||
|
|
5ea5f928ab | ||
|
|
efd6d35eb3 | ||
|
|
2b2538f13a | ||
|
|
9375dae179 | ||
|
|
674bb3758d | ||
|
|
cedf9a2eb8 | ||
|
|
7d2dc5b6c6 | ||
|
|
9d2aad7bf9 | ||
|
|
f085d7609b | ||
|
|
a49243a42a | ||
|
|
e79f431f14 | ||
|
|
38e5b6e8e3 | ||
|
|
35bdb785c4 | ||
|
|
25cb146fde | ||
|
|
c10f0f4a9e | ||
|
|
3a3a7f6e16 | ||
|
|
1d3b500962 | ||
|
|
f39f95af6d | ||
|
|
6fec2bbe1c | ||
|
|
2412134073 | ||
|
|
136545d1fd | ||
|
|
684c4d2113 | ||
|
|
6624fd0401 | ||
|
|
31502d2da3 | ||
|
|
3ee39ecca3 | ||
|
|
89e7c305e7 | ||
|
|
60dd71c59e | ||
|
|
0936f77930 | ||
|
|
3c09b95a8c | ||
|
|
780f26f135 | ||
|
|
77618674a0 | ||
|
|
c9c89a6005 | ||
|
|
d1276c4299 | ||
|
|
69730b6c95 | ||
|
|
9147d30152 | ||
|
|
6217c70fb5 | ||
|
|
17352c9a56 | ||
|
|
1b6026304f | ||
|
|
91f9973c6c | ||
|
|
ca2acee38a | ||
|
|
3bd455ced2 | ||
|
|
2c25abd143 | ||
|
|
08a9fb8cd7 | ||
|
|
d8a38b4e35 | ||
|
|
e64660f2d8 | ||
|
|
1a11466e69 | ||
|
|
78ab2fbe09 | ||
|
|
0c45d5773a | ||
|
|
f48335444b | ||
|
|
81b33cee5c | ||
|
|
020dcaad75 | ||
|
|
9bc56bcfc7 | ||
|
|
8325fadeb3 | ||
|
|
d54275b3bd | ||
|
|
29d20423a3 | ||
|
|
e539816253 | ||
|
|
922ce9ef5f | ||
|
|
b73ec6ae94 | ||
|
|
4a11bf956d | ||
|
|
3b3bb6c80a | ||
|
|
0f323ff2e3 | ||
|
|
3305c65ae6 | ||
|
|
5c5acdcb03 | ||
|
|
0e6991f486 | ||
|
|
014786cc5f | ||
|
|
223c6b50fc | ||
|
|
b18946352e | ||
|
|
96012b26b7 | ||
|
|
31cd663ad5 | ||
|
|
0e9c9d7ccf | ||
|
|
2a6eb6ec86 | ||
|
|
0a74423c07 | ||
|
|
6f1302ae67 | ||
|
|
f275570f12 | ||
|
|
90b47f6c44 | ||
|
|
e73d008695 | ||
|
|
3c5d1b402c | ||
|
|
3e22bccce4 | ||
|
|
354e140305 | ||
|
|
54859f3582 | ||
|
|
da12efd675 | ||
|
|
32f848e90d | ||
|
|
32440d23f7 | ||
|
|
62b7acc93a | ||
|
|
7b8e2c75c2 | ||
|
|
03abc641c5 | ||
|
|
fa5b98c9b5 | ||
|
|
c681be7ba8 | ||
|
|
3d3305a312 | ||
|
|
bb305af7b4 | ||
|
|
fd284973b6 | ||
|
|
5d57572694 | ||
|
|
36a22f2b3c | ||
|
|
dea9b590d1 | ||
|
|
bf843fe598 | ||
|
|
a23bc6caa8 | ||
|
|
1904fd5b02 | ||
|
|
03c9a883e1 | ||
|
|
c06df267a3 | ||
|
|
0bccdfeda7 | ||
|
|
07d118ae7d | ||
|
|
e912dde08d | ||
|
|
3544375fdd | ||
|
|
ab6ca7910e | ||
|
|
6a329f7a8e | ||
|
|
5d4bb10106 | ||
|
|
cbc079bfff | ||
|
|
09358d5853 | ||
|
|
81c345f33e | ||
|
|
3aa200eacc | ||
|
|
6ce0b60cf2 | ||
|
|
faef0784ee | ||
|
|
fb70fe5760 | ||
|
|
5b75b8a89e | ||
|
|
fa0296b796 | ||
|
|
4e2d1f568f | ||
|
|
b8d1aec1e5 | ||
|
|
38cfd6985e | ||
|
|
d7c20c6941 | ||
|
|
7894a54a0e | ||
|
|
a46e64eec3 | ||
|
|
cae0399584 | ||
|
|
bfbf4ef0b5 | ||
|
|
ca4004605e | ||
|
|
ec565a1bd3 | ||
|
|
94c4b180c1 | ||
|
|
66de0b9019 | ||
|
|
f752b38228 | ||
|
|
d79748a967 | ||
|
|
c1b6c2c5a5 | ||
|
|
806b04e0ca | ||
|
|
736b562f3a | ||
|
|
db440236fc | ||
|
|
00ea8b900a | ||
|
|
e092e9ba67 | ||
|
|
8313cf34a6 | ||
|
|
8f4b8f5826 | ||
|
|
c607b01f33 | ||
|
|
cc5d01d0e2 | ||
|
|
a4cc41b679 | ||
|
|
67361e9ed5 | ||
|
|
8662572690 | ||
|
|
99ea1788e7 | ||
|
|
7bec3c90cd | ||
|
|
ca4e6c46bc | ||
|
|
678da159a9 | ||
|
|
cc3b51fb3b | ||
|
|
060344bb5a | ||
|
|
b42c67040d | ||
|
|
f3b18fcf0e | ||
|
|
a86c69edc9 | ||
|
|
55c60a05dc | ||
|
|
ecf40cc747 | ||
|
|
197458e60b | ||
|
|
0c3ffb0743 | ||
|
|
56dffd3c58 | ||
|
|
57a3a37fdd | ||
|
|
a8a273f0d8 | ||
|
|
9f4ab26696 | ||
|
|
4ddef9d648 | ||
|
|
7cccca8194 | ||
|
|
2a8b678a4b | ||
|
|
b9767b865a | ||
|
|
f6bc3eb014 | ||
|
|
007917df19 | ||
|
|
22a2e850bf | ||
|
|
1cfdf3613c | ||
|
|
fe280e6bb1 | ||
|
|
a330fe6017 | ||
|
|
4ee4ad25b0 | ||
|
|
777a661389 | ||
|
|
8174230afe | ||
|
|
e1777dc533 | ||
|
|
390731c07b | ||
|
|
25d475e165 | ||
|
|
1e60250670 | ||
|
|
f6d2dd520c | ||
|
|
4600588e72 | ||
|
|
825ca94080 | ||
|
|
7f674f9861 | ||
|
|
27dba7e4e1 | ||
|
|
44295ff248 | ||
|
|
dc33d96a54 | ||
|
|
4ff7619356 | ||
|
|
cc5c2bd7cd | ||
|
|
2884712685 | ||
|
|
027264588b | ||
|
|
ddd75ce730 | ||
|
|
4bc13c28dd | ||
|
|
7a1db89a6e | ||
|
|
c08489509a | ||
|
|
7054ae8a88 | ||
|
|
d7e913be95 | ||
|
|
f283a2ced5 | ||
|
|
c7274ba16f | ||
|
|
6f323e379c | ||
|
|
42212b409a | ||
|
|
e8506cc5f1 | ||
|
|
d387f9f1fa | ||
|
|
73a555788d | ||
|
|
be58f67115 | ||
|
|
b26117a65d | ||
|
|
34fe6182c8 | ||
|
|
ee3ae6025f | ||
|
|
df9812b2a3 | ||
|
|
113eea04cc | ||
|
|
57f9ebdb68 | ||
|
|
94d0e28ad7 | ||
|
|
cd553d45cc | ||
|
|
d993f9ac64 | ||
|
|
833bdc13bd | ||
|
|
33657b4b49 | ||
|
|
ec6bc8e36b | ||
|
|
799370f753 | ||
|
|
abd404c57c | ||
|
|
037ed3cd54 | ||
|
|
c461a7fa15 | ||
|
|
8fc8aaa6dd | ||
|
|
2bc45e2b2e | ||
|
|
cdfc58d115 | ||
|
|
bb8a57d2e9 | ||
|
|
5e52339135 | ||
|
|
df75914e30 | ||
|
|
572e6ccb37 | ||
|
|
8e1ebe28c0 | ||
|
|
adec044e02 | ||
|
|
b9868cc709 | ||
|
|
fce8b125f8 | ||
|
|
4befd2e4ff | ||
|
|
38cdc1b7ba | ||
|
|
a0f6018469 | ||
|
|
f230d55031 | ||
|
|
2f6a15a9ae | ||
|
|
04d751208f | ||
|
|
7cfc40f328 | ||
|
|
3c54d32b6d | ||
|
|
ece7d92e57 | ||
|
|
8e736b28af | ||
|
|
92ec0a5b1d | ||
|
|
398834f690 | ||
|
|
28e6dd8759 | ||
|
|
dedc937915 | ||
|
|
732f4241fe | ||
|
|
873585e1ae | ||
|
|
71a5a02e8c | ||
|
|
51fbd02b40 | ||
|
|
763eda5038 | ||
|
|
6cdb76503b | ||
|
|
aa8edd7a47 | ||
|
|
535aa56627 | ||
|
|
db0fb30f7b | ||
|
|
7619fb4753 | ||
|
|
0aeba954d4 | ||
|
|
2bc1468fa2 | ||
|
|
4b29b6efc5 | ||
|
|
26b1003cfd | ||
|
|
b696dce6e4 | ||
|
|
403a86feca | ||
|
|
56d6a9767e | ||
|
|
d2cc229622 | ||
|
|
e6b166da7d | ||
|
|
77f401d977 | ||
|
|
7d7b232fdb | ||
|
|
959f1e33cd | ||
|
|
7f5ab96f81 | ||
|
|
443089a66f | ||
|
|
f5d9b47177 | ||
|
|
a0cddbe9b3 | ||
|
|
5f7fcfd3df | ||
|
|
a39080340a | ||
|
|
a3d6879c55 | ||
|
|
b09be86a3c | ||
|
|
02ef033d23 | ||
|
|
f10861e1de | ||
|
|
ecf53d9961 | ||
|
|
5339c09b72 | ||
|
|
b6ad218126 | ||
|
|
b7b74a429e | ||
|
|
52acd3123f | ||
|
|
c9c3a689d8 | ||
|
|
da4a2a2494 | ||
|
|
35a1fb26f9 | ||
|
|
cb3723242c | ||
|
|
6a0c6284d0 | ||
|
|
114ade7456 | ||
|
|
a01e0e37f4 | ||
|
|
18884025de | ||
|
|
cfdc941207 | ||
|
|
5eaf00ba0e | ||
|
|
8948555ac1 | ||
|
|
e28418d6d6 | ||
|
|
fe83c53206 | ||
|
|
942aa08285 | ||
|
|
93dd6b5a98 | ||
|
|
08dd9ca91c | ||
|
|
77efdc3ccf | ||
|
|
ef1bcd5afa | ||
|
|
8636685252 | ||
|
|
5873dfb731 | ||
|
|
934abec88c | ||
|
|
c1d654c4ce | ||
|
|
d64b12b14c | ||
|
|
3f4ab5f95e | ||
|
|
ee1e94be96 | ||
|
|
1e9999a8d3 | ||
|
|
460ca99fe1 | ||
|
|
7fdf9b7012 | ||
|
|
c16b869fea | ||
|
|
8deb19e3ac | ||
|
|
e6d4445a8a | ||
|
|
0f0da809da | ||
|
|
db8e805a96 | ||
|
|
a882cc7e8e | ||
|
|
acede26aa6 | ||
|
|
9330919be8 | ||
|
|
91b4e91e9c | ||
|
|
2fb265ae2d | ||
|
|
3b5e7f1dc4 | ||
|
|
08ff286f9a | ||
|
|
bc9fe2f4f9 | ||
|
|
e99b168bd6 | ||
|
|
a7afb1f680 | ||
|
|
6f3934f2e5 | ||
|
|
79da297add | ||
|
|
6664535ab9 | ||
|
|
80d290e178 | ||
|
|
d144af6d8e | ||
|
|
aba7c13a1d | ||
|
|
f59d3f36d1 | ||
|
|
3f0d0ecd5f | ||
|
|
0c51502cc5 | ||
|
|
e829650cd9 | ||
|
|
a8082c551b | ||
|
|
ff55cfa001 | ||
|
|
623a3d3b7b | ||
|
|
fb32e2a561 | ||
|
|
8aa8a380e1 | ||
|
|
f35b8b05e8 | ||
|
|
05bb73bb7c | ||
|
|
18299dc65e | ||
|
|
818ab2c10f | ||
|
|
df0bf28d57 | ||
|
|
ff65f10c2f | ||
|
|
5cf49aa166 | ||
|
|
0651daa1d4 | ||
|
|
921c53f75c | ||
|
|
dd37519185 | ||
|
|
a1e8c4eb2b | ||
|
|
1f8c191cb3 | ||
|
|
f4acc74eee | ||
|
|
3d1378ab77 | ||
|
|
58e4174edb | ||
|
|
20b4585666 | ||
|
|
9c7e7ed8d4 | ||
|
|
436c4f2736 | ||
|
|
0ce752af79 | ||
|
|
92ff896bdb | ||
|
|
77a3cbaba5 | ||
|
|
56f9c88251 | ||
|
|
8a5a08cbe1 | ||
|
|
5241c38ba0 | ||
|
|
072a903351 | ||
|
|
328bd453bb | ||
|
|
690a3cfa68 | ||
|
|
1c1847f63c | ||
|
|
c3d9d8ee2f | ||
|
|
65932b65d2 | ||
|
|
682e961416 | ||
|
|
9fcccc8197 | ||
|
|
72f3ced219 | ||
|
|
74de066529 | ||
|
|
3d1589404c | ||
|
|
30d9d46dd8 | ||
|
|
740373897a | ||
|
|
f7ca01bafd | ||
|
|
7654ff686a | ||
|
|
5266612bb3 | ||
|
|
a9b46a4d63 | ||
|
|
76e9bd8ad6 | ||
|
|
317a443644 | ||
|
|
43f91ca42c | ||
|
|
8d78d07415 | ||
|
|
99a00a1ae2 | ||
|
|
2cd8d891a1 | ||
|
|
7fc33af1e5 | ||
|
|
67c57a1137 | ||
|
|
9f8ac06659 | ||
|
|
aea28b28d0 | ||
|
|
ee4cd61696 | ||
|
|
e9f15c377f | ||
|
|
d5935ea81b | ||
|
|
934ad96a98 | ||
|
|
2c68f8fba1 | ||
|
|
c90de87f37 | ||
|
|
ab84566d86 | ||
|
|
4c109a467f | ||
|
|
bc4f6aaf9c | ||
|
|
cf8ac7e8b3 | ||
|
|
3a9b230aef | ||
|
|
016b644d86 | ||
|
|
7082b47856 | ||
|
|
57ec382102 | ||
|
|
9748ed2259 | ||
|
|
6ec5981f1d | ||
|
|
e20ea342c2 | ||
|
|
2ff3603245 | ||
|
|
da6e8f14d6 | ||
|
|
2dd04739b5 | ||
|
|
8e758ea979 | ||
|
|
a81f7e2a24 | ||
|
|
c98ec3658c | ||
|
|
249463f7df | ||
|
|
700e77ad43 | ||
|
|
1a272879f1 | ||
|
|
aa6cb4f25b | ||
|
|
59eec36746 | ||
|
|
45baff403a | ||
|
|
5de1883390 | ||
|
|
35b0d213a6 | ||
|
|
774a4b7533 | ||
|
|
11cbb774bc | ||
|
|
0f7d0a03d9 | ||
|
|
cb568a1af4 | ||
|
|
f4da03d840 | ||
|
|
e5cc8123b9 | ||
|
|
cc13e1210d | ||
|
|
1e838f2e55 | ||
|
|
154d4170cc | ||
|
|
64d6163f13 | ||
|
|
85ffc5d8bf | ||
|
|
38f36d465c | ||
|
|
d956055795 | ||
|
|
c1e1cd0596 | ||
|
|
a3df2ca0ef | ||
|
|
6b3325d0ba | ||
|
|
9e4dd44a2e | ||
|
|
e880588aac | ||
|
|
c2af3df331 | ||
|
|
46be6e37dc | ||
|
|
5165077bc9 | ||
|
|
5ae537f23c | ||
|
|
5f572dbd04 | ||
|
|
d511e80b01 | ||
|
|
27dfa41b67 | ||
|
|
f55c28352e | ||
|
|
a7b884d170 | ||
|
|
fd4f996c30 | ||
|
|
c897037b7a | ||
|
|
11fe64eee3 | ||
|
|
6cbc0f0304 | ||
|
|
b3d28bac6a | ||
|
|
96833bdf89 | ||
|
|
6cf5730bcb | ||
|
|
e5403f8dfd | ||
|
|
8278992feb | ||
|
|
9f690c1f5d | ||
|
|
b946f7e697 | ||
|
|
c9dea854f6 | ||
|
|
e72dfe5af2 | ||
|
|
d5912a53f4 | ||
|
|
cb5d005e68 | ||
|
|
0dd0f39250 | ||
|
|
9c7e250109 | ||
|
|
ca103b6af3 | ||
|
|
2f75ee9472 | ||
|
|
7eab38afa7 | ||
|
|
68d0a442e4 | ||
|
|
ee2b6d3b85 | ||
|
|
e73220e069 | ||
|
|
d2a1404f04 | ||
|
|
c8a7eb4988 | ||
|
|
7ec37e058e | ||
|
|
64f2d2a502 | ||
|
|
6afb4ccf26 | ||
|
|
a4676d1fea | ||
|
|
97173de555 | ||
|
|
9e6d01b2a1 | ||
|
|
d3a5437079 | ||
|
|
b22a03a317 | ||
|
|
06cd13aef2 | ||
|
|
25a3feb2ca | ||
|
|
c8c3332366 | ||
|
|
006b315120 | ||
|
|
f74d6efcae | ||
|
|
b2d802aa85 | ||
|
|
964a51e21d | ||
|
|
4a43db06dd | ||
|
|
3ce7fe638f | ||
|
|
c2a4d44bf4 | ||
|
|
867817f568 | ||
|
|
46a56a236f | ||
|
|
6357009055 | ||
|
|
42f7091038 | ||
|
|
a3c63fcdf0 | ||
|
|
6b358c626f | ||
|
|
3bbfa822d7 | ||
|
|
a13fc138f2 | ||
|
|
721a082758 | ||
|
|
07288de5a1 | ||
|
|
ac0bb78412 | ||
|
|
c24464179b | ||
|
|
d473600a15 | ||
|
|
accd9eaa27 | ||
|
|
cb180cbbf8 | ||
|
|
a3dbe482e2 | ||
|
|
959302a868 | ||
|
|
95be2b55f7 | ||
|
|
3bce86a1e8 | ||
|
|
dd10931316 | ||
|
|
f5b8f5a6f8 | ||
|
|
65fddc5d28 | ||
|
|
d3ac843249 | ||
|
|
1b5f4f5c3c | ||
|
|
1af558af44 | ||
|
|
b3b36f3340 | ||
|
|
4624659af6 | ||
|
|
ab649af8be | ||
|
|
c5491e6f27 | ||
|
|
b47b5ddb05 | ||
|
|
095799a816 | ||
|
|
1104b6daa4 | ||
|
|
4ecd811302 | ||
|
|
b112ccd6d8 | ||
|
|
bee32f9898 | ||
|
|
69fce590e3 | ||
|
|
c51ed43a10 | ||
|
|
fd51511380 | ||
|
|
8a054d8cc9 | ||
|
|
91731896c4 | ||
|
|
e897d04218 | ||
|
|
69e4de6ba9 | ||
|
|
6b176066ec | ||
|
|
4c372962fc | ||
|
|
001f386244 | ||
|
|
5eb73e0c05 | ||
|
|
3347f92414 | ||
|
|
72c6200f17 | ||
|
|
ed01ee1e2d | ||
|
|
b259bc60a2 | ||
|
|
772d5e10b8 | ||
|
|
7e96560fbb | ||
|
|
6ae5e11c6f | ||
|
|
9877fe2eed | ||
|
|
fe086e90a1 | ||
|
|
c9958e1634 | ||
|
|
67f7c002c9 | ||
|
|
bf7c38d8e8 | ||
|
|
f361d153d1 | ||
|
|
0e571c3e35 | ||
|
|
7857c80c79 | ||
|
|
99adfd2bba | ||
|
|
9a493491f1 | ||
|
|
1ac76d7758 | ||
|
|
c5ecf48d94 | ||
|
|
1e10f021b5 | ||
|
|
7d0bd49ae3 | ||
|
|
d4e7cabee5 | ||
|
|
92471b0beb | ||
|
|
ea713758a1 | ||
|
|
9182d8d594 | ||
|
|
7df3434c6a | ||
|
|
5e9014b2c3 | ||
|
|
4d95c824f3 | ||
|
|
28d7d2544e | ||
|
|
decc56e54d | ||
|
|
976d86ae1a | ||
|
|
4e650e17aa | ||
|
|
d08d04debd | ||
|
|
602108b150 | ||
|
|
a9b1a2e7b7 | ||
|
|
99f31bbc23 | ||
|
|
6c2faf68c4 | ||
|
|
ee8c29c5ef | ||
|
|
26df916421 | ||
|
|
0a8f400a59 | ||
|
|
cc1cbd1ed7 | ||
|
|
034e85aa87 | ||
|
|
12e54e189a | ||
|
|
5eaea1c7f1 | ||
|
|
10786c6ca8 | ||
|
|
55d9377403 | ||
|
|
70f29785ca | ||
|
|
e197c5120d | ||
|
|
2cf72aea81 | ||
|
|
30111bb125 | ||
|
|
7d38f6b074 | ||
|
|
7e625b8e9e | ||
|
|
152eea3cb8 | ||
|
|
ee72b1be5d | ||
|
|
605d96b71b | ||
|
|
8e1c7d955f | ||
|
|
8046b5675f | ||
|
|
0ac8a39c5e | ||
|
|
81522b33e6 | ||
|
|
4df49689a9 | ||
|
|
0f7106bf4a | ||
|
|
900c5b7661 | ||
|
|
5cac4c953d | ||
|
|
65f2cb9a22 | ||
|
|
7ddb68b70d | ||
|
|
14eb66c87d | ||
|
|
ef141d499b | ||
|
|
1ab27e8fe3 | ||
|
|
145a3b7ee4 | ||
|
|
a042327741 | ||
|
|
4eba651c3d | ||
|
|
ba3b2ea66f | ||
|
|
c48719dfdb | ||
|
|
1680f0ef52 | ||
|
|
ae6c4b2ddf | ||
|
|
8e9192181d | ||
|
|
a2f2a59c21 | ||
|
|
e739c26f2e | ||
|
|
b215eae914 | ||
|
|
1123e4e751 | ||
|
|
203bc26c0e | ||
|
|
fb4651bdad | ||
|
|
09f2926bbb | ||
|
|
eef06425a3 | ||
|
|
b329e3c43c | ||
|
|
04a3223ff5 | ||
|
|
9226be058c | ||
|
|
2dc425b083 | ||
|
|
c5f915651c | ||
|
|
e2d7fec793 | ||
|
|
d3b4f46b25 | ||
|
|
6311156169 | ||
|
|
695a814eb3 | ||
|
|
5ef2e35685 | ||
|
|
8818ed9d7b | ||
|
|
d785af1826 | ||
|
|
398811a14e | ||
|
|
c5f9533d2b | ||
|
|
aaf17aa2b2 | ||
|
|
3e11379e6c | ||
|
|
f78d0b7c7a | ||
|
|
978e19c817 | ||
|
|
1550e32282 | ||
|
|
7fb2dc6500 | ||
|
|
92654af609 | ||
|
|
c10787dbb3 | ||
|
|
4fecb7fad9 | ||
|
|
01a121868b | ||
|
|
a023009dee | ||
|
|
e301393f33 | ||
|
|
39600fb0f5 | ||
|
|
663cde7676 | ||
|
|
dac771c096 | ||
|
|
b8b1d572b4 | ||
|
|
6789e61488 | ||
|
|
051fdfb081 | ||
|
|
1f07a827ec | ||
|
|
81618d2efc | ||
|
|
6f44a88ffd | ||
|
|
4300c3d550 | ||
|
|
5fbf7b3d24 | ||
|
|
eb5899c94b | ||
|
|
5e68fa1255 | ||
|
|
f1c322fe69 | ||
|
|
580520f100 | ||
|
|
40343df255 | ||
|
|
57f8b427db | ||
|
|
f85e96acac | ||
|
|
bff83f1785 | ||
|
|
ca27748799 | ||
|
|
2dc98f682f | ||
|
|
d4f3309ffd | ||
|
|
821777bd64 | ||
|
|
84c2fa9491 | ||
|
|
d193c677c7 | ||
|
|
cbfc7c8b43 | ||
|
|
6a43065316 | ||
|
|
9dd390f7a7 | ||
|
|
6c631cb11e | ||
|
|
817b790757 | ||
|
|
98aa8cc22a | ||
|
|
e9e228abaf | ||
|
|
909bb6f6cf | ||
|
|
e8b47eef2f | ||
|
|
415ba26efe | ||
|
|
777e2744c4 | ||
|
|
53a09f4989 | ||
|
|
e3e0f056a9 | ||
|
|
b6ce1fbd51 | ||
|
|
7267cfdbfc | ||
|
|
fa259aa194 | ||
|
|
da1d2873d5 | ||
|
|
be88d278c6 | ||
|
|
81cb8c83bf | ||
|
|
eee44a9919 | ||
|
|
4f730410bc | ||
|
|
171144be80 | ||
|
|
5c2bcba000 | ||
|
|
5b5c6e975d | ||
|
|
45110f60c3 | ||
|
|
26c434c4ee | ||
|
|
2e872d4818 | ||
|
|
30a1219f9d | ||
|
|
cf1632f80b | ||
|
|
885b003730 | ||
|
|
a9a61b2617 | ||
|
|
b968d8594c | ||
|
|
d7ebb871bb | ||
|
|
6f67b2381a | ||
|
|
2237d7e860 | ||
|
|
6ea456d6da | ||
|
|
f0a2edf7cf | ||
|
|
881fcd4e9b | ||
|
|
8954af5c53 | ||
|
|
e3c6d5859b | ||
|
|
16441b5b6a | ||
|
|
195b1ccfcc | ||
|
|
b3f5670cc0 | ||
|
|
e43c80b4f5 | ||
|
|
931e2f6134 | ||
|
|
e091a37241 | ||
|
|
5f093846a7 | ||
|
|
dcbae0618c | ||
|
|
4d70d6319b | ||
|
|
09484667f0 | ||
|
|
04fcf57d0a | ||
|
|
8436dd5851 | ||
|
|
bbae8cccfb | ||
|
|
044fa2d10f | ||
|
|
2dd50cccd3 | ||
|
|
c05ffb0c6b | ||
|
|
935044d2da | ||
|
|
6ec6505a5d | ||
|
|
96e0f55c61 | ||
|
|
b765f06dfd | ||
|
|
8da6318cc6 | ||
|
|
0fcdec604c | ||
|
|
3edda36a91 | ||
|
|
97d65bfca0 | ||
|
|
66771c6f62 | ||
|
|
e6b23aee18 | ||
|
|
5e9ee50f99 | ||
|
|
93584bc766 | ||
|
|
a89180ea06 | ||
|
|
4983da7efa | ||
|
|
8fd6bd4c71 | ||
|
|
c7ea62a394 | ||
|
|
fc8e2d3e05 | ||
|
|
6cf3c91293 | ||
|
|
e122278ec4 | ||
|
|
7c9b5cba1c | ||
|
|
a86c1b7cd3 | ||
|
|
dd6d08d61d | ||
|
|
0fc120d7d5 | ||
|
|
6e03558dcb | ||
|
|
b327dd31b7 | ||
|
|
da1326a336 | ||
|
|
d22cb1dfa7 | ||
|
|
5556915564 | ||
|
|
4c6fc53ba5 | ||
|
|
626b6500de | ||
|
|
dbbbb6b921 | ||
|
|
d9e3d4dbae | ||
|
|
92648de3b4 | ||
|
|
4f9e5b9336 | ||
|
|
d55d0ad621 | ||
|
|
4edbe2aace | ||
|
|
ba2702cfca | ||
|
|
eba1f6327d | ||
|
|
1ba0b4037c | ||
|
|
49daa75bc4 | ||
|
|
cd21138b3d | ||
|
|
fea1eb1149 | ||
|
|
9a58f6c454 | ||
|
|
66cefe6bb5 | ||
|
|
23510acf40 | ||
|
|
faa49f36e7 | ||
|
|
a5fb8b20a1 | ||
|
|
e14b303609 | ||
|
|
2ec3df6680 | ||
|
|
1f4b6001ef | ||
|
|
6e7c9cc6a3 | ||
|
|
2db385c6a5 | ||
|
|
bd27f48eae | ||
|
|
98a33250f6 | ||
|
|
8f9729a928 | ||
|
|
1a8564bc35 | ||
|
|
76c9632417 | ||
|
|
2370361b43 | ||
|
|
cb63095d3f | ||
|
|
601f2fb450 | ||
|
|
e746f17167 | ||
|
|
5f76097562 | ||
|
|
03756c4210 | ||
|
|
5e1e158414 | ||
|
|
76d2525fd2 | ||
|
|
ec8c7e5c2c | ||
|
|
0a4cbe1a08 | ||
|
|
c228421a38 | ||
|
|
a742f82370 | ||
|
|
213678ca3e | ||
|
|
e1b7ad6a71 | ||
|
|
8b9985a92c | ||
|
|
f276826b09 | ||
|
|
8c1df551ef | ||
|
|
b62cb157e1 | ||
|
|
045c74ce67 | ||
|
|
911e902da4 | ||
|
|
4e0d90d720 | ||
|
|
7b62705cc0 | ||
|
|
bdf02bebaa | ||
|
|
94aa309910 | ||
|
|
499a0a782a | ||
|
|
1e5a531a83 | ||
|
|
3e6a4073c4 | ||
|
|
e7cb6abd1f | ||
|
|
abfd8841a5 | ||
|
|
5e385fa33b | ||
|
|
95688c7e30 | ||
|
|
b041d3e70e | ||
|
|
0e91cddab9 | ||
|
|
d3856693ce | ||
|
|
40f36104f3 | ||
|
|
7215edb784 | ||
|
|
189be7ce69 | ||
|
|
28f10ffc25 | ||
|
|
be015320de | ||
|
|
a37d53b2e7 | ||
|
|
f43de11121 | ||
|
|
4c1129188b | ||
|
|
34e04f5251 | ||
|
|
b613d65b36 | ||
|
|
66aec63f6b | ||
|
|
5b0d18bb3b | ||
|
|
1c5b43c218 | ||
|
|
c78cfb9fcf | ||
|
|
927d4dd06f | ||
|
|
afb75ef75a | ||
|
|
92181866a4 | ||
|
|
c97805c7f1 | ||
|
|
c20a139e58 | ||
|
|
4287d1032f | ||
|
|
8b784d7c10 | ||
|
|
8895f6420f | ||
|
|
bb10ed5b7d | ||
|
|
9dc315dbf3 | ||
|
|
677531531f | ||
|
|
70c89b14a9 | ||
|
|
7f7c94e0d5 | ||
|
|
e6f09e42a1 | ||
|
|
f0419b7502 | ||
|
|
f01072eb11 | ||
|
|
c88102d6cc | ||
|
|
847a2994f9 | ||
|
|
ab186c0608 | ||
|
|
349ae8ed27 | ||
|
|
0066b858d6 | ||
|
|
e12e720a99 | ||
|
|
c17f2e2560 | ||
|
|
d75bf235bb | ||
|
|
881d1e9594 | ||
|
|
45a443989a | ||
|
|
7880fb402a | ||
|
|
ac2f8c9141 | ||
|
|
e36e774382 | ||
|
|
b1be2dfbf4 | ||
|
|
32f3a11bf7 | ||
|
|
7d0c72f92e | ||
|
|
27e0e12595 | ||
|
|
f6ae6b3658 | ||
|
|
9e1d633244 | ||
|
|
6b28e72686 | ||
|
|
dfd3a06600 | ||
|
|
2c35a6f0e1 | ||
|
|
f956558656 | ||
|
|
32fa7006ff | ||
|
|
95acf71dbf | ||
|
|
5640c27cec | ||
|
|
a7c5e4f317 | ||
|
|
274682e736 | ||
|
|
b4b6ab2667 | ||
|
|
bbe9dd6760 | ||
|
|
2aa7adb3bd | ||
|
|
fb7e671c26 | ||
|
|
7420dba0c9 | ||
|
|
9a059bdce4 | ||
|
|
50c7269315 | ||
|
|
b4434a369b | ||
|
|
1c945ebfbf | ||
|
|
20d0915a03 | ||
|
|
21ee94739b | ||
|
|
9ebb894694 | ||
|
|
483db08057 | ||
|
|
3a557998d0 | ||
|
|
c8322349a0 | ||
|
|
75b993bc6b | ||
|
|
b9db83a741 | ||
|
|
5bbb65b569 | ||
|
|
974eedc4dd | ||
|
|
c38c95dab5 | ||
|
|
c3a3446baa | ||
|
|
443413c03e | ||
|
|
0c56f420d5 | ||
|
|
f66bcb22c4 | ||
|
|
b44d59a303 | ||
|
|
dbe382f91e | ||
|
|
1d4ec9cd71 | ||
|
|
36f88b198c | ||
|
|
e2ca80a33f | ||
|
|
c08f981224 | ||
|
|
846f59974c | ||
|
|
5e368f486a | ||
|
|
42eed07dfd | ||
|
|
fcd647832c | ||
|
|
06d30f0182 | ||
|
|
c6c5b2e682 | ||
|
|
5431a84f37 | ||
|
|
764c6f0086 | ||
|
|
7f48c5c0e5 | ||
|
|
bd66cda0ee | ||
|
|
030ddbe12f | ||
|
|
60e3b21596 | ||
|
|
647e0236bb | ||
|
|
83c0b8b96e | ||
|
|
4d2f1ca10e | ||
|
|
678a617b0b | ||
|
|
b88d78a7e5 | ||
|
|
3d4092ee3e | ||
|
|
0306a79a37 | ||
|
|
539503f766 | ||
|
|
e06022e4d4 | ||
|
|
afb93eda2c | ||
|
|
6d2f5fcb60 | ||
|
|
1fb37aec25 | ||
|
|
5174662fe8 | ||
|
|
e47bafce29 | ||
|
|
7cf68a4b68 | ||
|
|
694d5d92b7 | ||
|
|
83d9d98ba3 | ||
|
|
cf3d0fe78d | ||
|
|
56aaf52430 | ||
|
|
40696ddea7 | ||
|
|
38d2dc8c8e | ||
|
|
69346c5b3e | ||
|
|
a2aa527f50 | ||
|
|
b2ae40c8c8 | ||
|
|
11498dcc7f | ||
|
|
140d5242cf | ||
|
|
e3dff56479 | ||
|
|
0fb7666b97 | ||
|
|
5c06de6abc | ||
|
|
582a609d27 | ||
|
|
ec3d25e64e | ||
|
|
740c7510ea | ||
|
|
c9f6c707ac | ||
|
|
667eee07b1 | ||
|
|
deba38ab60 | ||
|
|
25e44e54fb | ||
|
|
62a2341ab4 | ||
|
|
53b465b7bb | ||
|
|
fc6a3282ad | ||
|
|
cecd1ccc96 | ||
|
|
439987c149 | ||
|
|
61279ac119 | ||
|
|
ca2fbf5cdf | ||
|
|
d3129224bd | ||
|
|
57625b26c9 | ||
|
|
e345009e0a | ||
|
|
41f5071d7f | ||
|
|
623969be82 | ||
|
|
d106037f42 | ||
|
|
a9f1b3eea9 | ||
|
|
a1f1067063 | ||
|
|
f57dda5d09 | ||
|
|
93acb8b163 | ||
|
|
4f32ab4421 | ||
|
|
c52736372a | ||
|
|
eca11bc064 | ||
|
|
093fd2d638 | ||
|
|
194fb44fb5 | ||
|
|
0c032d69ee | ||
|
|
b2219d879f | ||
|
|
304cf9d797 | ||
|
|
29963a04fc | ||
|
|
dff80d8276 | ||
|
|
f33bb0d73f | ||
|
|
be09dd41fa | ||
|
|
36b12b645b | ||
|
|
bea15771b9 | ||
|
|
8c2cbce4a4 | ||
|
|
9674f4e739 | ||
|
|
137952af73 | ||
|
|
66dcb1020a | ||
|
|
829d19dfc2 | ||
|
|
c73159d2d0 | ||
|
|
4159fae8c9 | ||
|
|
bff045fff2 | ||
|
|
3090e7c163 | ||
|
|
38798aec73 | ||
|
|
bc7a69044b | ||
|
|
ee6512567e | ||
|
|
1b7ded4560 | ||
|
|
e9abe63b47 | ||
|
|
b70bf81d6c | ||
|
|
410fddbf7f | ||
|
|
c0c9026da6 | ||
|
|
f76e534b64 | ||
|
|
468148ceb2 | ||
|
|
cc69cac29e | ||
|
|
19d2a4d1cd | ||
|
|
a7dcdc8df2 | ||
|
|
7815d5ac5d | ||
|
|
23051db54a | ||
|
|
f51434880f | ||
|
|
87d5b4d3af | ||
|
|
dd335ac75b | ||
|
|
16d5e5f906 | ||
|
|
42114a3680 | ||
|
|
e7adaecb0f | ||
|
|
9818f3df46 | ||
|
|
ca832a01cb | ||
|
|
aaa2b204ba | ||
|
|
78bf9e5993 | ||
|
|
8be0296fc1 | ||
|
|
26cd741c04 | ||
|
|
bf655b3327 | ||
|
|
1793b37adc | ||
|
|
d0ffe85abb | ||
|
|
f9f7dcfc58 | ||
|
|
f06257e7ff | ||
|
|
e490f0bce6 | ||
|
|
770c7173ec | ||
|
|
661ab4867b | ||
|
|
9ee3b5aae6 | ||
|
|
d202256c30 | ||
|
|
b8856d4ef7 | ||
|
|
e1294ac210 | ||
|
|
b0edd2d137 | ||
|
|
0d0e9bc953 | ||
|
|
2576291d9f | ||
|
|
d2aab87faa | ||
|
|
c2509b462c | ||
|
|
0e378be769 | ||
|
|
2785eaab21 | ||
|
|
8a10fd1547 | ||
|
|
8f8ed817fb | ||
|
|
7a150254fe | ||
|
|
9612a4a781 | ||
|
|
249b233dc2 | ||
|
|
c4d4a9b47b | ||
|
|
a55e991bfa | ||
|
|
610276f66b | ||
|
|
de99aabf7f | ||
|
|
40a0a0083f | ||
|
|
56ecd2ac14 | ||
|
|
4617d58b6a | ||
|
|
98aeff2f3e | ||
|
|
f2239decca | ||
|
|
36bd25a9cc | ||
|
|
933ae663f0 | ||
|
|
a08674f708 | ||
|
|
7fe0855932 | ||
|
|
d7594c4a1c | ||
|
|
d9c8fa6043 | ||
|
|
4140d3084e | ||
|
|
93d3c9c657 | ||
|
|
3433f1224a | ||
|
|
95ac686f04 | ||
|
|
ae8d11825a | ||
|
|
ece796432a | ||
|
|
995ae21075 | ||
|
|
4a2d52717c | ||
|
|
c0a07a6144 | ||
|
|
b14560c07d | ||
|
|
5de7d7f882 | ||
|
|
a4ae3b223c | ||
|
|
383571ef05 | ||
|
|
7e5459cc62 | ||
|
|
caa8d9c0ed | ||
|
|
df887dc0e9 | ||
|
|
262e3bbee2 | ||
|
|
87463c7e70 | ||
|
|
2dc3e9af5e | ||
|
|
d1de99d48d | ||
|
|
db87a06cfd | ||
|
|
fab38c1f4e | ||
|
|
298dbfb0e0 | ||
|
|
b978517945 | ||
|
|
5c55449a87 | ||
|
|
78425d1947 | ||
|
|
55529eb493 | ||
|
|
06b2d907b6 | ||
|
|
f54d96d916 | ||
|
|
2c3da88b44 | ||
|
|
a90b7a65de | ||
|
|
7ef0a5a550 | ||
|
|
5433ea0762 | ||
|
|
7162fd61fc | ||
|
|
d4271cf618 | ||
|
|
cc7dbb19a5 | ||
|
|
5381a23140 | ||
|
|
7bcffb9424 | ||
|
|
2fde4767a0 | ||
|
|
2f6b0861d9 | ||
|
|
c83eeefeb2 | ||
|
|
807227911a | ||
|
|
db71c89e35 | ||
|
|
8b29723317 | ||
|
|
bef3ebf9cc | ||
|
|
061e021cd4 | ||
|
|
55728fe332 | ||
|
|
b1b04c7e35 | ||
|
|
5b86a8d7c9 | ||
|
|
44a7a5e692 | ||
|
|
da33c80735 | ||
|
|
25935abf3a | ||
|
|
93e7914a86 | ||
|
|
36231b88db | ||
|
|
14c1ecd515 | ||
|
|
dd38e11a5d | ||
|
|
9572bdcbf9 | ||
|
|
9ad0efd85b | ||
|
|
399b799002 | ||
|
|
48fbedd8ee | ||
|
|
a85dba8b49 | ||
|
|
64240bf70a | ||
|
|
cd06011b5e | ||
|
|
4d29b74c29 | ||
|
|
e5a12ade90 | ||
|
|
981fb7f330 | ||
|
|
7851cb81bb | ||
|
|
4e586bf31f | ||
|
|
9860f1eb68 | ||
|
|
9397f38929 | ||
|
|
540943109b | ||
|
|
73dee79a4c | ||
|
|
894f8b8c77 | ||
|
|
056e24a653 | ||
|
|
4045bbb1bc | ||
|
|
2634557def | ||
|
|
2af3d5b8b1 | ||
|
|
a9ea1b84cc | ||
|
|
10fc2495cd | ||
|
|
e9f5e593ce | ||
|
|
eec98c9674 | ||
|
|
0fddeebbc6 | ||
|
|
125e9312c1 | ||
|
|
e6a305026d | ||
|
|
f5cf7c0ca7 | ||
|
|
4a903371ac | ||
|
|
13777c8773 | ||
|
|
b38b749438 | ||
|
|
ff68a9f508 | ||
|
|
4767ba6b9c | ||
|
|
d7467d9b8e | ||
|
|
ab11081276 | ||
|
|
1e280928d8 | ||
|
|
e245689b85 | ||
|
|
bd31694850 | ||
|
|
97437838f8 | ||
|
|
2c226a9c83 | ||
|
|
7a06721e16 | ||
|
|
ae0dd7b9c0 | ||
|
|
28d83c1e11 | ||
|
|
589d49af30 | ||
|
|
9283e367b1 | ||
|
|
37fa2f8431 | ||
|
|
a3ffb80344 | ||
|
|
5c0ffae67a | ||
|
|
a216af40dc | ||
|
|
51e2fffe7e | ||
|
|
b6af5dcb3a | ||
|
|
2aa943bef2 | ||
|
|
27ea4f76f0 | ||
|
|
1a4b6a66ae | ||
|
|
cf14b32355 | ||
|
|
707c5cba41 | ||
|
|
c803f92104 | ||
|
|
96d5d025dc | ||
|
|
91061235d8 | ||
|
|
105ce757d0 | ||
|
|
031b3a9f51 | ||
|
|
1fa9ea7a0e | ||
|
|
641ede20f3 | ||
|
|
b5051008e3 | ||
|
|
4eabb97821 | ||
|
|
76bf1bde87 | ||
|
|
dfe5591822 | ||
|
|
b27d86c1a5 | ||
|
|
c7b064c751 | ||
|
|
06a3d0e500 | ||
|
|
1ffe3c4813 | ||
|
|
a8c99d7594 | ||
|
|
144e13245a | ||
|
|
4ea0c7e875 | ||
|
|
d38bbd9603 | ||
|
|
881a502cbc | ||
|
|
cbecd918fc | ||
|
|
ff0044229a | ||
|
|
175924d705 | ||
|
|
26c138908a | ||
|
|
fd93a10376 | ||
|
|
486b3a1f44 | ||
|
|
cd63722e5e | ||
|
|
e75917a4d3 | ||
|
|
b288bcbc18 | ||
|
|
5b2b104e37 | ||
|
|
e9f2216f84 | ||
|
|
7d7d098efa | ||
|
|
59494833b7 | ||
|
|
ddc059713d | ||
|
|
009703fabe | ||
|
|
b3b5f1b584 | ||
|
|
7771f30270 | ||
|
|
8a26dddd08 | ||
|
|
98b4c1388e | ||
|
|
6d89f2160d | ||
|
|
3e8859b8dd | ||
|
|
27babe6677 | ||
|
|
2a6a3e624d | ||
|
|
6ff42d1627 | ||
|
|
7188cfe85a | ||
|
|
cccdba57fe | ||
|
|
b3bd502028 | ||
|
|
423b33e088 | ||
|
|
edb63380ed | ||
|
|
7175bb7b47 | ||
|
|
c817916e0f | ||
|
|
426b48bd13 | ||
|
|
88ba714b59 | ||
|
|
795fdd477c | ||
|
|
6f021049ab | ||
|
|
bbdc137f64 | ||
|
|
843974d810 | ||
|
|
b97f025ea7 | ||
|
|
670a32271a | ||
|
|
71a33f2f02 | ||
|
|
f477a215cf | ||
|
|
12b09cf963 | ||
|
|
bedd7b6f41 | ||
|
|
ee5ae22779 | ||
|
|
316f0722d8 | ||
|
|
34cb30bb39 | ||
|
|
84ec05a257 | ||
|
|
78bdfefc66 | ||
|
|
33899405ba | ||
|
|
b3fd720668 | ||
|
|
dc7a447baf | ||
|
|
138b56a429 | ||
|
|
4699a37b4b | ||
|
|
940e21e74f | ||
|
|
b6f330cc91 | ||
|
|
f388a46484 | ||
|
|
a66d023f84 | ||
|
|
188cad3a67 | ||
|
|
4d5bdf6b6f | ||
|
|
96810788fc | ||
|
|
2f356fe26d | ||
|
|
ab9e2729cd | ||
|
|
203f105974 | ||
|
|
972b8e110f | ||
|
|
31d0b8acbf | ||
|
|
0152560fd8 | ||
|
|
e78214c38d | ||
|
|
79ca759774 | ||
|
|
5d1e5ca2ff | ||
|
|
8d13ae9e1e | ||
|
|
b763df5730 | ||
|
|
a237388bd4 | ||
|
|
610f3525a2 | ||
|
|
fff692bd0c | ||
|
|
a2fff64bd8 | ||
|
|
c00074e40b | ||
|
|
93319402cb | ||
|
|
4d2d359b06 | ||
|
|
0cc4a7d238 | ||
|
|
026c6fac2e | ||
|
|
d56ac18585 | ||
|
|
e90d8dcdb5 | ||
|
|
1a1c207a97 | ||
|
|
9b1203185d | ||
|
|
3214af53b7 | ||
|
|
ec6b58d7d4 | ||
|
|
0d888c9eeb | ||
|
|
f957f1d2bb | ||
|
|
730344a201 | ||
|
|
c5e74ca5e0 | ||
|
|
3216c29766 | ||
|
|
db5babf012 | ||
|
|
da147aacd4 | ||
|
|
8c80c1d077 | ||
|
|
7ff646d044 | ||
|
|
cdc1e024f1 | ||
|
|
b9dec2f714 | ||
|
|
0b296cb271 | ||
|
|
e62cca40ac | ||
|
|
170ae3602b | ||
|
|
96349be350 | ||
|
|
62e4828b0d | ||
|
|
0d58a20d70 | ||
|
|
448288834a | ||
|
|
c0fc258848 | ||
|
|
6f1da7ad1f | ||
|
|
c0e2b6ac4d | ||
|
|
99ebce0462 | ||
|
|
9831629430 | ||
|
|
e0ce5b7d12 | ||
|
|
e757bbc1b2 | ||
|
|
f2d90fac26 | ||
|
|
a33e150312 | ||
|
|
e5e9a14de4 | ||
|
|
07311579af | ||
|
|
a517b7fb00 | ||
|
|
7474e7e7bb | ||
|
|
7a8ecf7377 | ||
|
|
def97afd9b | ||
|
|
6ba41af6dc | ||
|
|
a88b35f919 | ||
|
|
a0cf2ea56b | ||
|
|
75c4b4f234 | ||
|
|
37177f1226 | ||
|
|
18fb27d2f7 | ||
|
|
ee054c3181 | ||
|
|
594a3a1321 | ||
|
|
fca72c2b95 | ||
|
|
4048f466c2 | ||
|
|
5a28bbbc9b | ||
|
|
55294701f0 | ||
|
|
b36ddfb3c3 | ||
|
|
faef85b78f | ||
|
|
06c8f5de32 | ||
|
|
eb6af97b42 | ||
|
|
601e94d370 | ||
|
|
640ff152cc | ||
|
|
de19cc8afe | ||
|
|
214f852a98 | ||
|
|
c6b684df89 | ||
|
|
cb3efb157f | ||
|
|
17df48f9fa | ||
|
|
728d87028b | ||
|
|
131feabafe | ||
|
|
a6cf73b6d1 | ||
|
|
1d7fb0e43c | ||
|
|
bf11eacf5a | ||
|
|
513c29d349 | ||
|
|
b68f9f157c | ||
|
|
6b9b98ffdd | ||
|
|
5f7b4a9434 | ||
|
|
8e7d110a7a | ||
|
|
782053a6ec | ||
|
|
fdc72c27b6 | ||
|
|
8d502d2cb7 | ||
|
|
1df3065884 | ||
|
|
cc2ff8e3cb | ||
|
|
bce821dee9 | ||
|
|
9e67efbd1b | ||
|
|
5f081d038e | ||
|
|
d434925f0b | ||
|
|
1b62a57e7c | ||
|
|
13447f0b4f | ||
|
|
327810390e | ||
|
|
f8071ce942 | ||
|
|
2f858e29cb | ||
|
|
1eaecf7568 | ||
|
|
e83747e7ed | ||
|
|
3260d9376e | ||
|
|
827e825e53 | ||
|
|
0521ae4c75 | ||
|
|
3deb5dbb9b | ||
|
|
d58c3bd3d1 | ||
|
|
298bfa81b6 | ||
|
|
a9d1d1a63a | ||
|
|
e5c2a7f176 | ||
|
|
da05003a5c | ||
|
|
b9dfa1aafe | ||
|
|
a57410133a | ||
|
|
f26e646cfc | ||
|
|
2a755b0e65 | ||
|
|
5fdcb322c8 | ||
|
|
76afc2b3ff | ||
|
|
6eb4f7e4a1 | ||
|
|
80412a7c2b | ||
|
|
478b2cb7a2 | ||
|
|
bdc00a152c | ||
|
|
c7cec1b2f1 | ||
|
|
178f3cd4a3 | ||
|
|
3340d39f67 | ||
|
|
5e7c39e42c | ||
|
|
ab479ab885 | ||
|
|
65081d995e | ||
|
|
05b2692eb5 | ||
|
|
ca7b8e589e | ||
|
|
56c325b526 | ||
|
|
732402159c | ||
|
|
1ef3b9ed13 | ||
|
|
ef43a76b0b | ||
|
|
4003a8023c | ||
|
|
102205ff71 | ||
|
|
b736e5d971 | ||
|
|
5720009e29 | ||
|
|
04e2d1a89a | ||
|
|
bc0525589c | ||
|
|
122e8ac9d6 | ||
|
|
dc7b110da2 | ||
|
|
37259baf08 | ||
|
|
d87d095fe9 | ||
|
|
44a1baa41f | ||
|
|
a1bc60145c | ||
|
|
802919e6ea | ||
|
|
1f674b5b86 | ||
|
|
53b15f4507 | ||
|
|
a5e2fa80e8 | ||
|
|
f10f62cebd | ||
|
|
37ac4d30e5 | ||
|
|
0ac43cefa2 | ||
|
|
4c60173b02 | ||
|
|
dbcdc22b26 | ||
|
|
726596d568 | ||
|
|
3e3f223bb2 | ||
|
|
17eb760928 | ||
|
|
4cbfbdd621 | ||
|
|
aeb8e89b69 | ||
|
|
0759e1ece2 | ||
|
|
fd7b2b7c4b | ||
|
|
7ef8f9ac13 | ||
|
|
dbb6c2bd9f | ||
|
|
b18bd735c9 | ||
|
|
b7752cc8a2 | ||
|
|
e8bc88eace | ||
|
|
19a4a99e76 | ||
|
|
bc213888e8 | ||
|
|
c784b46a5e | ||
|
|
1c9ba5b512 | ||
|
|
3d99ea5cbf | ||
|
|
28dc5a5b8c | ||
|
|
dcf23d0952 | ||
|
|
e597ecfe78 | ||
|
|
1c75ac12e8 | ||
|
|
28c4046300 | ||
|
|
762b5444f5 | ||
|
|
a0e34c3a21 | ||
|
|
504892ddb9 | ||
|
|
5927bf8149 | ||
|
|
45069604e1 | ||
|
|
b7f42f47a1 | ||
|
|
2175562b9a | ||
|
|
311ae5c4c5 | ||
|
|
8f29df541f | ||
|
|
80e61206fd | ||
|
|
354d15cbf1 | ||
|
|
12c5100bc8 | ||
|
|
366db1623b | ||
|
|
88457d726b | ||
|
|
ac754f86f3 | ||
|
|
4bb1024041 | ||
|
|
a0d97ff7ed | ||
|
|
6a1a83cc2b | ||
|
|
abf0f7111d | ||
|
|
ef82489040 | ||
|
|
49474c6fc8 | ||
|
|
7ee0dc48a7 | ||
|
|
ca531f0c13 | ||
|
|
e1ef1efdb5 | ||
|
|
c8c393eff9 | ||
|
|
6fd80cd16f | ||
|
|
6f7a3ed031 | ||
|
|
be597ed467 | ||
|
|
a5267bcb5b | ||
|
|
c512693b9d | ||
|
|
95b19864d3 | ||
|
|
db6758f7f7 | ||
|
|
f11f3fdee1 | ||
|
|
497d055b63 | ||
|
|
8f9ecdcfb5 | ||
|
|
fb47b28318 | ||
|
|
6fa72cf912 | ||
|
|
df6fa0be24 | ||
|
|
edb7cfc08d | ||
|
|
559c132d17 | ||
|
|
4e006e9481 | ||
|
|
717a6b6d07 | ||
|
|
04c101018a | ||
|
|
d6a298cffd | ||
|
|
018755516b | ||
|
|
31e17daa34 | ||
|
|
0748743fe0 | ||
|
|
0a7ff53fc7 | ||
|
|
da9ca18fe3 | ||
|
|
d292ab72d2 | ||
|
|
9c77af0d67 | ||
|
|
03f3d295c9 | ||
|
|
9aa5ca022d | ||
|
|
35e2e1848a | ||
|
|
087ee35ece | ||
|
|
399809ee6b | ||
|
|
cf6b12842f | ||
|
|
702c138f44 | ||
|
|
b0f0066f28 | ||
|
|
47c9a1d80f | ||
|
|
239f65d04d | ||
|
|
2cd534526f | ||
|
|
604ecbbf95 | ||
|
|
5e6191f235 | ||
|
|
026f269bdf | ||
|
|
7970955c00 | ||
|
|
3a0ea03a9c | ||
|
|
4ea07940f8 | ||
|
|
a8ac42037b | ||
|
|
78a45fc92d | ||
|
|
a6a12335f1 | ||
|
|
d82c1427f7 | ||
|
|
f2c766ddaf | ||
|
|
33aefb69f4 | ||
|
|
2751624b2b | ||
|
|
fc55267dc3 | ||
|
|
9ea1bb492f | ||
|
|
42c4b95df1 | ||
|
|
55325a0812 | ||
|
|
86bfc0a7f9 | ||
|
|
166fce793f | ||
|
|
df53489498 | ||
|
|
d050f48d4f | ||
|
|
d204418530 | ||
|
|
a4d21586d0 | ||
|
|
bf5c7a41d6 | ||
|
|
73cae2e726 | ||
|
|
019a83bd83 | ||
|
|
826b14b54f | ||
|
|
8a81d59240 | ||
|
|
4581e1daf9 | ||
|
|
1d619b0954 | ||
|
|
6b666bf304 | ||
|
|
cbb784637a | ||
|
|
175dc33b01 | ||
|
|
aa1b98aef8 | ||
|
|
c842a1e8d4 | ||
|
|
7e8be87da2 | ||
|
|
97b9bd0593 | ||
|
|
389865ba13 | ||
|
|
bdaceedc91 | ||
|
|
2c910b0778 | ||
|
|
f01721ce64 | ||
|
|
35b16d421e | ||
|
|
147def5059 | ||
|
|
bf16dd2cf8 | ||
|
|
24feace60b | ||
|
|
3ab8a8e25f | ||
|
|
e96c7bf987 | ||
|
|
e7c39cb53f | ||
|
|
a8aca3ad0f | ||
|
|
b531f6ab8b | ||
|
|
bd83d995fa | ||
|
|
7962303c72 | ||
|
|
991056a861 | ||
|
|
369a1a8ad9 | ||
|
|
b8e7b9c8b3 | ||
|
|
df40bafcfe | ||
|
|
0cd8ac6754 | ||
|
|
ad416ca14f | ||
|
|
70784517e4 | ||
|
|
2c3dc6ceef | ||
|
|
db935b20a7 | ||
|
|
a1fd0318f1 | ||
|
|
c2151c1b59 | ||
|
|
8f729bba41 | ||
|
|
08bf0b6d4d | ||
|
|
1ff30c5e54 | ||
|
|
80e7fb9020 | ||
|
|
1bd0106c2b | ||
|
|
6c59192340 | ||
|
|
29c1498842 | ||
|
|
75c12e8966 | ||
|
|
23291d4627 | ||
|
|
8b89767907 | ||
|
|
7bc43b4fe8 | ||
|
|
0aaf4c1f32 | ||
|
|
16394e6dbd | ||
|
|
3b531f863d | ||
|
|
0bc1a6a22a | ||
|
|
6dac9f769a | ||
|
|
5871ae1a59 | ||
|
|
0a9329ec56 | ||
|
|
00e34bb6fe | ||
|
|
75777dafc6 | ||
|
|
85ca07c521 | ||
|
|
b781e5cc88 | ||
|
|
13313028b5 | ||
|
|
0bc7c452c3 | ||
|
|
b549003054 | ||
|
|
2ee425bdf1 | ||
|
|
fe6160663a | ||
|
|
6549e6136c | ||
|
|
9b1668cbcd | ||
|
|
1c615b7fbf | ||
|
|
7c54012caa | ||
|
|
abee872931 | ||
|
|
1cbcec87d8 | ||
|
|
0f1960f22a | ||
|
|
fb0c000b54 | ||
|
|
87bb6e9995 | ||
|
|
45ceabf49e | ||
|
|
8202629f62 | ||
|
|
d3d15301f7 | ||
|
|
8817ade510 | ||
|
|
4423bfdaa1 | ||
|
|
56c766c7b8 | ||
|
|
f8d2f44f82 | ||
|
|
d86e736b33 | ||
|
|
e2db15ed4d | ||
|
|
d5af131144 | ||
|
|
1401e0ab5a | ||
|
|
49817ee0fa | ||
|
|
e4e5cab60f | ||
|
|
bd6a3a633d | ||
|
|
3d5500e69b | ||
|
|
b5fc236d43 | ||
|
|
9915e560b2 | ||
|
|
4cf07f143c | ||
|
|
9c0994219e | ||
|
|
1287412383 | ||
|
|
0712207ff2 | ||
|
|
3e11a5200e | ||
|
|
723b470284 | ||
|
|
a267aad709 | ||
|
|
b1b318e282 | ||
|
|
31a8d35bb9 | ||
|
|
f5a63998ce | ||
|
|
921f568d2d | ||
|
|
f43ac8554c | ||
|
|
988a21e94d | ||
|
|
a7172d8782 | ||
|
|
cc8c23db85 | ||
|
|
a6d7852903 | ||
|
|
af88fb8af4 | ||
|
|
d16c710caa | ||
|
|
23d362757c | ||
|
|
ef7bea6d2d | ||
|
|
4d0fa60a7a | ||
|
|
e25fc2da88 | ||
|
|
5558e0c62f | ||
|
|
10315ed240 | ||
|
|
754fb2397e | ||
|
|
df2d144590 | ||
|
|
432e47032e | ||
|
|
507d40b6f5 | ||
|
|
97eb814f21 | ||
|
|
0ef80e6d3e | ||
|
|
b651b5cb48 | ||
|
|
02d95e90b4 | ||
|
|
99e160686a | ||
|
|
fc9ada5f18 | ||
|
|
ce3c084ea1 | ||
|
|
ab24796316 | ||
|
|
aa2ee060f1 | ||
|
|
66e47990ac | ||
|
|
bd9f7bda29 | ||
|
|
b002cf3031 | ||
|
|
77407f0879 | ||
|
|
ff4c76e3a2 | ||
|
|
533e0fb10d | ||
|
|
c5bc3e27a8 | ||
|
|
fad0398a48 | ||
|
|
5ce519aef9 | ||
|
|
a0719275e6 | ||
|
|
01a2fc6b75 | ||
|
|
c232983e63 | ||
|
|
fe956d4617 | ||
|
|
fee8838e7b | ||
|
|
0996f8cccb |
@@ -8,3 +8,6 @@
|
||||
**/dist/**
|
||||
**/node_modules
|
||||
**/temp
|
||||
playwright.config.ts
|
||||
jest.config.js
|
||||
test/live-preview/next-app
|
||||
|
||||
65
.eslintrc.cjs
Normal file
65
.eslintrc.cjs
Normal file
@@ -0,0 +1,65 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
extends: ['@payloadcms'],
|
||||
ignorePatterns: ['README.md', 'packages/**/*.spec.ts'],
|
||||
overrides: [
|
||||
{
|
||||
files: ['packages/**'],
|
||||
plugins: ['payload'],
|
||||
rules: {
|
||||
'payload/no-jsx-import-statements': 'warn',
|
||||
'payload/no-relative-monorepo-imports': 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['scripts/**'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'no-console': 'off',
|
||||
'perfectionist/sort-object-types': 'off',
|
||||
'perfectionist/sort-objects': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
extends: ['plugin:@typescript-eslint/disable-type-checked'],
|
||||
files: ['*.js', '*.cjs', '*.json', '*.md', '*.yml', '*.yaml'],
|
||||
},
|
||||
{
|
||||
files: ['packages/eslint-config-payload/**'],
|
||||
rules: {
|
||||
'perfectionist/sort-objects': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['package.json', 'tsconfig.json'],
|
||||
rules: {
|
||||
'perfectionist/sort-array-includes': 'off',
|
||||
'perfectionist/sort-astro-attributes': 'off',
|
||||
'perfectionist/sort-classes': 'off',
|
||||
'perfectionist/sort-enums': 'off',
|
||||
'perfectionist/sort-exports': 'off',
|
||||
'perfectionist/sort-imports': 'off',
|
||||
'perfectionist/sort-interfaces': 'off',
|
||||
'perfectionist/sort-jsx-props': 'off',
|
||||
'perfectionist/sort-keys': 'off',
|
||||
'perfectionist/sort-maps': 'off',
|
||||
'perfectionist/sort-named-exports': 'off',
|
||||
'perfectionist/sort-named-imports': 'off',
|
||||
'perfectionist/sort-object-types': 'off',
|
||||
'perfectionist/sort-objects': 'off',
|
||||
'perfectionist/sort-svelte-attributes': 'off',
|
||||
'perfectionist/sort-union-types': 'off',
|
||||
'perfectionist/sort-vue-attributes': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
parserOptions: {
|
||||
project: ['./tsconfig.json'],
|
||||
tsconfigRootDir: __dirname,
|
||||
EXPERIMENTAL_useSourceOfProjectReferenceRedirect: true,
|
||||
EXPERIMENTAL_useProjectService: true,
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 'latest',
|
||||
},
|
||||
root: true,
|
||||
}
|
||||
38
.eslintrc.js
38
.eslintrc.js
@@ -1,38 +0,0 @@
|
||||
module.exports = {
|
||||
extends: ['@payloadcms'],
|
||||
overrides: [
|
||||
{
|
||||
extends: ['plugin:@typescript-eslint/disable-type-checked'],
|
||||
files: ['*.js', '*.cjs', '*.json', '*.md', '*.yml', '*.yaml'],
|
||||
},
|
||||
{
|
||||
files: ['packages/eslint-config-payload/**'],
|
||||
rules: {
|
||||
'perfectionist/sort-objects': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['package.json', 'tsconfig.json'],
|
||||
rules: {
|
||||
'perfectionist/sort-array-includes': 'off',
|
||||
'perfectionist/sort-astro-attributes': 'off',
|
||||
'perfectionist/sort-classes': 'off',
|
||||
'perfectionist/sort-enums': 'off',
|
||||
'perfectionist/sort-exports': 'off',
|
||||
'perfectionist/sort-imports': 'off',
|
||||
'perfectionist/sort-interfaces': 'off',
|
||||
'perfectionist/sort-jsx-props': 'off',
|
||||
'perfectionist/sort-keys': 'off',
|
||||
'perfectionist/sort-maps': 'off',
|
||||
'perfectionist/sort-named-exports': 'off',
|
||||
'perfectionist/sort-named-imports': 'off',
|
||||
'perfectionist/sort-object-types': 'off',
|
||||
'perfectionist/sort-objects': 'off',
|
||||
'perfectionist/sort-svelte-attributes': 'off',
|
||||
'perfectionist/sort-union-types': 'off',
|
||||
'perfectionist/sort-vue-attributes': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
root: true,
|
||||
}
|
||||
@@ -16,3 +16,6 @@ fb7d1be2f3325d076b7c967b1730afcef37922c2
|
||||
|
||||
# lint and format create-payload-app
|
||||
5fd3d430001efe86515262ded5e26f00c1451181
|
||||
|
||||
# 3.0 prettier & lint everywhere
|
||||
6789e61488a1d3de56f472ac3214faf344030005
|
||||
|
||||
49
.github/CODEOWNERS
vendored
49
.github/CODEOWNERS
vendored
@@ -1,50 +1,33 @@
|
||||
# Order matters. The last matching pattern takes precedence.
|
||||
|
||||
### Catch-all ###
|
||||
* @denolfe @jmikrut @DanRibbens
|
||||
.* @denolfe @jmikrut @DanRibbens
|
||||
|
||||
### Core ###
|
||||
/packages/payload/ @denolfe @jmikrut @DanRibbens
|
||||
/packages/payload/src/uploads/ @denolfe
|
||||
/packages/payload/src/admin/ @jmikrut @jacobsfletch @JarrodMFlesch
|
||||
### Package Exports ###
|
||||
/**/exports/ @denolfe @jmikrut
|
||||
|
||||
### Adapters ###
|
||||
/packages/bundler-*/ @denolfe @jmikrut @DanRibbens @JarrodMFlesch
|
||||
/packages/db-*/ @denolfe @jmikrut @DanRibbens
|
||||
/packages/richtext-*/ @denolfe @jmikrut @DanRibbens @AlessioGr
|
||||
/packages/richtext-*/ @AlessioGr
|
||||
|
||||
### Plugins ###
|
||||
/packages/plugin-*/ @denolfe @jmikrut @DanRibbens @jacobsfletch @JarrodMFlesch @AlessioGr
|
||||
/packages/plugin-cloud*/ @denolfe
|
||||
/packages/plugin-form-builder/ @jacobsfletch
|
||||
/packages/plugin-live-preview*/ @jacobsfletch
|
||||
/packages/plugin-nested-docs/ @jacobsfletch
|
||||
/packages/plugin-password-protection/ @jmikrut
|
||||
/packages/plugin-redirects/ @jacobsfletch
|
||||
/packages/plugin-search/ @jacobsfletch
|
||||
/packages/plugin-sentry/ @JessChowdhury
|
||||
/packages/plugin-seo/ @jacobsfletch
|
||||
/packages/plugin-stripe/ @jacobsfletch
|
||||
/packages/plugin-zapier/ @JarrodMFlesch
|
||||
|
||||
### Examples ###
|
||||
/examples/ @jacobsfletch
|
||||
/examples/testing/ @JarrodMFlesch
|
||||
/examples/email/ @JessChowdhury
|
||||
/examples/whitelabel/ @JessChowdhury
|
||||
|
||||
### Templates ###
|
||||
/templates/ @jacobsfletch
|
||||
/templates/blank/ @denolfe
|
||||
/templates/ @jacobsfletch @denolfe
|
||||
|
||||
### Misc ###
|
||||
/packages/create-payload-app/ @denolfe
|
||||
/packages/eslint-config-payload/ @denolfe
|
||||
/packages/payload-admin-bar/ @jacobsfletch
|
||||
/packages/eslint-*/ @denolfe
|
||||
|
||||
### Build Files ###
|
||||
/**/package.json @denolfe
|
||||
|
||||
/tsconfig.json @denolfe
|
||||
/**/tsconfig*.json @denolfe
|
||||
|
||||
/jest.config.js @denolfe
|
||||
/**/jest.config.js @denolfe
|
||||
|
||||
### Root ###
|
||||
/package.json @denolfe
|
||||
/scripts/ @denolfe
|
||||
/.husky/ @denolfe
|
||||
/.vscode/ @denolfe
|
||||
/.github/ @denolfe
|
||||
/.github/CODEOWNERS @denolfe
|
||||
|
||||
486
.github/workflows/main.yml
vendored
486
.github/workflows/main.yml
vendored
@@ -4,7 +4,19 @@ on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
push:
|
||||
branches: ['main']
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
NODE_VERSION: 18.20.2
|
||||
PNPM_VERSION: 8.15.7
|
||||
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
|
||||
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
@@ -15,27 +27,74 @@ jobs:
|
||||
needs_build: ${{ steps.filter.outputs.needs_build }}
|
||||
templates: ${{ steps.filter.outputs.templates }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 25
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
needs_build:
|
||||
- '.github/workflows/**'
|
||||
- 'packages/**'
|
||||
- 'test/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'package.json'
|
||||
templates:
|
||||
- 'templates/**'
|
||||
- name: Log all filter results
|
||||
run: |
|
||||
echo "needs_build: ${{ steps.filter.outputs.needs_build }}"
|
||||
echo "templates: ${{ steps.filter.outputs.templates }}"
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
core-build:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 25
|
||||
- uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
needs_build:
|
||||
- '.github/workflows/**'
|
||||
- 'packages/**'
|
||||
- 'test/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'package.json'
|
||||
templates:
|
||||
- 'templates/**'
|
||||
- name: Log all filter results
|
||||
run: |
|
||||
echo "needs_build: ${{ steps.filter.outputs.needs_build }}"
|
||||
echo "templates: ${{ steps.filter.outputs.templates }}"
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 720
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-store-
|
||||
pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
- run: pnpm install
|
||||
- name: List changed files
|
||||
run: git diff --name-only --diff-filter=d origin/${GITHUB_BASE_REF}...origin/${GITHUB_HEAD_REF}
|
||||
- name: Lint staged
|
||||
run: npx lint-staged --diff="origin/${GITHUB_BASE_REF}...origin/${GITHUB_HEAD_REF}"
|
||||
|
||||
build:
|
||||
needs: changes
|
||||
if: ${{ needs.changes.outputs.needs_build == 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
@@ -45,15 +104,19 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 25
|
||||
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: 8
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
@@ -61,73 +124,148 @@ jobs:
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 720
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
pnpm-store-
|
||||
pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
- run: pnpm install
|
||||
- run: pnpm run build
|
||||
- run: pnpm run build:all
|
||||
env:
|
||||
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
|
||||
|
||||
- name: Cache build
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
tests:
|
||||
tests-unit:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Unit Tests
|
||||
run: pnpm test:unit
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8096
|
||||
|
||||
tests-int:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
database: [mongoose, postgres]
|
||||
database:
|
||||
- mongodb
|
||||
- postgres
|
||||
- postgres-custom-schema
|
||||
- postgres-uuid
|
||||
- supabase
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: payloadtests
|
||||
AWS_ENDPOINT_URL: http://127.0.0.1:4566
|
||||
AWS_ACCESS_KEY_ID: localstack
|
||||
AWS_SECRET_ACCESS_KEY: localstack
|
||||
AWS_REGION: us-east-1
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: 8
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Start LocalStack
|
||||
run: pnpm docker:start
|
||||
|
||||
- name: Start PostgreSQL
|
||||
uses: CasperWA/postgresql-action@v1.2
|
||||
with:
|
||||
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
|
||||
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
|
||||
postgresql db: ${{ env.POSTGRES_DB }}
|
||||
postgresql user: ${{ env.POSTGRES_USER }}
|
||||
postgresql password: ${{ env.POSTGRES_PASSWORD }}
|
||||
if: matrix.database == 'postgres'
|
||||
if: startsWith(matrix.database, 'postgres')
|
||||
|
||||
- name: Install Supabase CLI
|
||||
uses: supabase/setup-cli@v1
|
||||
with:
|
||||
version: latest
|
||||
if: matrix.database == 'supabase'
|
||||
|
||||
- name: Initialize Supabase
|
||||
run: |
|
||||
supabase init
|
||||
supabase start
|
||||
if: matrix.database == 'supabase'
|
||||
|
||||
- name: Wait for PostgreSQL
|
||||
run: sleep 30
|
||||
if: startsWith(matrix.database, 'postgres')
|
||||
|
||||
- run: sleep 30
|
||||
- name: Configure PostgreSQL
|
||||
run: |
|
||||
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "CREATE ROLE runner SUPERUSER LOGIN;"
|
||||
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "SELECT version();"
|
||||
echo "POSTGRES_URL=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" >> $GITHUB_ENV
|
||||
if: matrix.database == 'postgres'
|
||||
if: startsWith(matrix.database, 'postgres')
|
||||
|
||||
- name: Component Tests
|
||||
run: pnpm test:components
|
||||
- name: Configure PostgreSQL with custom schema
|
||||
run: |
|
||||
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "CREATE SCHEMA custom;"
|
||||
if: matrix.database == 'postgres-custom-schema'
|
||||
|
||||
- name: Configure Supabase
|
||||
run: |
|
||||
echo "POSTGRES_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres" >> $GITHUB_ENV
|
||||
if: matrix.database == 'supabase'
|
||||
|
||||
- name: Integration Tests
|
||||
run: pnpm test:int
|
||||
@@ -138,63 +276,172 @@ jobs:
|
||||
|
||||
tests-e2e:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
part: [1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 8/8]
|
||||
|
||||
# find test -type f -name 'e2e.spec.ts' | sort | xargs dirname | xargs -I {} basename {}
|
||||
suite:
|
||||
- _community
|
||||
- access-control
|
||||
- admin
|
||||
- auth
|
||||
- field-error-states
|
||||
- fields-relationship
|
||||
- fields
|
||||
- fields__collections__Blocks
|
||||
- fields__collections__Array
|
||||
- fields__collections__Relationship
|
||||
- fields__collections__RichText
|
||||
- fields__collections__Lexical
|
||||
- live-preview
|
||||
- localization
|
||||
- plugin-cloud-storage
|
||||
- plugin-form-builder
|
||||
- plugin-nested-docs
|
||||
- plugin-seo
|
||||
- versions
|
||||
- uploads
|
||||
env:
|
||||
SUITE_NAME: ${{ matrix.suite }}
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: 8
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: E2E Tests
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
retry_on: error
|
||||
max_attempts: 2
|
||||
timeout_minutes: 15
|
||||
command: pnpm test:e2e --part ${{ matrix.part }} --bail
|
||||
- name: Start LocalStack
|
||||
run: pnpm docker:start
|
||||
if: ${{ matrix.suite == 'plugin-cloud-storage' }}
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- name: Store Playwright's Version
|
||||
run: |
|
||||
# Extract the version number using a more targeted regex pattern with awk
|
||||
PLAYWRIGHT_VERSION=$(pnpm ls @playwright/test --depth=0 | awk '/@playwright\/test/ {print $2}')
|
||||
echo "Playwright's Version: $PLAYWRIGHT_VERSION"
|
||||
echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV
|
||||
|
||||
- name: Cache Playwright Browsers for Playwright's Version
|
||||
id: cache-playwright-browsers
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }}
|
||||
|
||||
- name: Setup Playwright - Browsers and Dependencies
|
||||
if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
|
||||
run: pnpm exec playwright install --with-deps chromium
|
||||
|
||||
- name: Setup Playwright - Dependencies-only
|
||||
if: steps.cache-playwright-browsers.outputs.cache-hit == 'true'
|
||||
run: pnpm exec playwright install-deps chromium
|
||||
|
||||
- name: E2E Tests
|
||||
run: PLAYWRIGHT_JSON_OUTPUT_NAME=results_${{ matrix.suite }}.json pnpm test:e2e ${{ matrix.suite }}
|
||||
env:
|
||||
PLAYWRIGHT_JSON_OUTPUT_NAME: results_${{ matrix.suite }}.json
|
||||
NEXT_TELEMETRY_DISABLED: 1
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: test-results
|
||||
path: test-results/
|
||||
name: test-results-${{ matrix.suite }}
|
||||
path: test/test-results/
|
||||
if-no-files-found: ignore
|
||||
retention-days: 1
|
||||
|
||||
tests-type-generation:
|
||||
# Disabled until this is fixed: https://github.com/daun/playwright-report-summary/issues/156
|
||||
# - uses: daun/playwright-report-summary@v3
|
||||
# with:
|
||||
# report-file: results_${{ matrix.suite }}.json
|
||||
# report-tag: ${{ matrix.suite }}
|
||||
# job-summary: true
|
||||
|
||||
app-build-with-packed:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: 8
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Start MongoDB
|
||||
uses: supercharge/mongodb-github-action@1.10.0
|
||||
with:
|
||||
mongodb-version: 6.0
|
||||
|
||||
- name: Pack and build app
|
||||
run: |
|
||||
set -ex
|
||||
pnpm run script:pack --dest templates/blank-3.0
|
||||
cd templates/blank-3.0
|
||||
cp .env.example .env
|
||||
ls -la
|
||||
pnpm add ./*.tgz
|
||||
pnpm install --ignore-workspace
|
||||
cat package.json
|
||||
pnpm run build
|
||||
|
||||
tests-type-generation:
|
||||
if: false # This should be replaced with gen on a real Payload project
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v3
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v4
|
||||
timeout-minutes: 10
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
@@ -205,87 +452,9 @@ jobs:
|
||||
- name: Generate GraphQL schema file
|
||||
run: pnpm dev:generate-graphql-schema graphql-schema-gen
|
||||
|
||||
build-packages:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pkg:
|
||||
- db-mongodb
|
||||
- db-postgres
|
||||
- bundler-webpack
|
||||
- bundler-vite
|
||||
- richtext-slate
|
||||
- richtext-lexical
|
||||
- live-preview
|
||||
- live-preview-react
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Build ${{ matrix.pkg }}
|
||||
run: pnpm turbo run build --filter=${{ matrix.pkg }}
|
||||
|
||||
plugins:
|
||||
runs-on: ubuntu-latest
|
||||
needs: core-build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pkg:
|
||||
- create-payload-app
|
||||
- plugin-cloud
|
||||
- plugin-cloud-storage
|
||||
- plugin-form-builder
|
||||
- plugin-nested-docs
|
||||
- plugin-search
|
||||
- plugin-sentry
|
||||
- plugin-seo
|
||||
|
||||
steps:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 8
|
||||
run_install: false
|
||||
|
||||
- name: Restore build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}-${{ github.run_number }}
|
||||
|
||||
- name: Build ${{ matrix.pkg }}
|
||||
run: pnpm turbo run build --filter=${{ matrix.pkg }}
|
||||
|
||||
- name: Test ${{ matrix.pkg }}
|
||||
run: pnpm --filter ${{ matrix.pkg }} run test
|
||||
if: matrix.pkg != 'create-payload-app' # degit doesn't work within GitHub Actions
|
||||
|
||||
templates:
|
||||
needs: changes
|
||||
if: ${{ needs.changes.outputs.templates == 'true' }}
|
||||
if: false # Disable until templates are updated for 3.0
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -296,11 +465,14 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 25
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
- name: Setup Node@${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Start MongoDB
|
||||
uses: supercharge/mongodb-github-action@1.10.0
|
||||
|
||||
103
.github/workflows/pr-title.yml
vendored
Normal file
103
.github/workflows/pr-title.yml
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
name: pr-title
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: lint-pr-title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v5
|
||||
id: lint_pr_title
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
types: |
|
||||
build
|
||||
chore
|
||||
ci
|
||||
docs
|
||||
feat
|
||||
fix
|
||||
perf
|
||||
refactor
|
||||
revert
|
||||
style
|
||||
test
|
||||
types
|
||||
scopes: |
|
||||
cpa
|
||||
db-\*
|
||||
db-mongodb
|
||||
db-postgres
|
||||
email-nodemailer
|
||||
eslint
|
||||
graphql
|
||||
live-preview
|
||||
live-preview-react
|
||||
next
|
||||
payload
|
||||
plugin-cloud
|
||||
plugin-cloud-storage
|
||||
plugin-form-builder
|
||||
plugin-nested-docs
|
||||
plugin-redirects
|
||||
plugin-relationship-object-ids
|
||||
plugin-search
|
||||
plugin-sentry
|
||||
plugin-seo
|
||||
plugin-stripe
|
||||
richtext-\*
|
||||
richtext-lexical
|
||||
richtext-slate
|
||||
storage-\*
|
||||
storage-azure
|
||||
storage-gcs
|
||||
storage-vercel-blob
|
||||
storage-s3
|
||||
translations
|
||||
ui
|
||||
templates
|
||||
examples(\/(\w|-)+)?
|
||||
deps
|
||||
|
||||
# Disallow uppercase letters at the beginning of the subject
|
||||
subjectPattern: ^(?![A-Z]).+$
|
||||
subjectPatternError: |
|
||||
The subject "{subject}" found in the pull request title "{title}"
|
||||
didn't match the configured pattern. Please ensure that the subject
|
||||
doesn't start with an uppercase character.
|
||||
|
||||
- uses: marocchino/sticky-pull-request-comment@v2
|
||||
# When the previous steps fails, the workflow would stop. By adding this
|
||||
# condition you can continue the execution with the populated error message.
|
||||
if: always() && (steps.lint_pr_title.outputs.error_message != null)
|
||||
with:
|
||||
header: pr-title-lint-error
|
||||
message: |
|
||||
Pull Request titles must follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and have valid scopes.
|
||||
|
||||
${{ steps.lint_pr_title.outputs.error_message }}
|
||||
|
||||
```
|
||||
feat(ui): add Button component
|
||||
^ ^ ^
|
||||
| | |__ Subject
|
||||
| |_______ Scope
|
||||
|____________ Type
|
||||
```
|
||||
|
||||
# Delete a previous comment when the issue has been resolved
|
||||
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
header: pr-title-lint-error
|
||||
delete: true
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -3,10 +3,21 @@ package-lock.json
|
||||
dist
|
||||
/.idea/*
|
||||
!/.idea/runConfigurations
|
||||
!/.idea/payload.iml
|
||||
|
||||
test-results
|
||||
.devcontainer
|
||||
.localstack
|
||||
/migrations
|
||||
.localstack
|
||||
.turbo
|
||||
|
||||
.turbo
|
||||
|
||||
# Ignore test directory media folder/files
|
||||
/media
|
||||
test/media
|
||||
/versions
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/node,macos,windows,webstorm,sublimetext,visualstudiocode
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=node,macos,windows,webstorm,sublimetext,visualstudiocode
|
||||
@@ -279,3 +290,4 @@ $RECYCLE.BIN/
|
||||
# End of https://www.toptal.com/developers/gitignore/api/node,macos,windows,webstorm,sublimetext,visualstudiocode
|
||||
|
||||
/build
|
||||
.swc
|
||||
|
||||
54
.idea/payload.iml
generated
Normal file
54
.idea/payload.iml
generated
Normal file
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/payload/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/payload/components" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/payload/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.swc" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/examples" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/media" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/create-payload-app/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/create-payload-app/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/db-mongodb/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/db-mongodb/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/db-postgres/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/db-postgres/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/graphql/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/graphql/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-react/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview-react/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/live-preview/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/next/.swc" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/next/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/payload/fields" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud-storage/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud-storage/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-cloud/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-form-builder/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-nested-docs/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-nested-docs/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-redirects/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-redirects/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-search/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-search/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-sentry/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-seo/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-seo/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/plugin-stripe/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-lexical/.turbo" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages/richtext-lexical/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/templates" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/test/.swc" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/versions" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
5
.idea/runConfigurations/Run_Dev_Fields.xml
generated
5
.idea/runConfigurations/Run_Dev_Fields.xml
generated
@@ -1,5 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Dev Fields" type="NodeJSConfigurationType" application-parameters="fields" path-to-js-file="node_modules/.pnpm/nodemon@3.0.1/node_modules/nodemon/bin/nodemon.js" working-dir="$PROJECT_DIR$">
|
||||
<configuration default="false" name="Run Dev Fields" type="NodeJSConfigurationType" application-parameters="--no-deprecation fields" path-to-js-file="test/dev.js" working-dir="$PROJECT_DIR$">
|
||||
<envs>
|
||||
<env name="NODE_OPTIONS" value="--no-deprecation" />
|
||||
</envs>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
5
.idea/runConfigurations/Run_Dev__community.xml
generated
5
.idea/runConfigurations/Run_Dev__community.xml
generated
@@ -1,5 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Dev _community" type="NodeJSConfigurationType" application-parameters="_community" path-to-js-file="node_modules/.pnpm/nodemon@3.0.1/node_modules/nodemon/bin/nodemon.js" working-dir="$PROJECT_DIR$">
|
||||
<configuration default="false" name="Run Dev _community" type="NodeJSConfigurationType" application-parameters="--no-deprecation _community" path-to-js-file="test/dev.js" working-dir="$PROJECT_DIR$">
|
||||
<envs>
|
||||
<env name="NODE_OPTIONS" value="--no-deprecation" />
|
||||
</envs>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1 +1 @@
|
||||
v18.17.1
|
||||
v18.20.2
|
||||
|
||||
@@ -9,3 +9,6 @@
|
||||
**/node_modules
|
||||
**/temp
|
||||
**/docs/**
|
||||
tsconfig.json
|
||||
packages/payload/*.js
|
||||
packages/payload/*.d.ts
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
module.exports = {
|
||||
verbose: true,
|
||||
git: {
|
||||
requireCleanWorkingDir: false,
|
||||
commit: false,
|
||||
push: false,
|
||||
tag: false,
|
||||
},
|
||||
npm: {
|
||||
skipChecks: true,
|
||||
tag: 'beta',
|
||||
},
|
||||
hooks: {
|
||||
'before:init': ['pnpm install', 'pnpm clean', 'pnpm build'],
|
||||
},
|
||||
}
|
||||
15
.swcrc
Normal file
15
.swcrc
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/swcrc",
|
||||
"sourceMaps": "inline",
|
||||
"jsc": {
|
||||
"target": "esnext",
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true,
|
||||
"dts": true
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "es6"
|
||||
}
|
||||
}
|
||||
7
.vscode/extensions.json
vendored
7
.vscode/extensions.json
vendored
@@ -1,3 +1,8 @@
|
||||
{
|
||||
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"firsttris.vscode-jest-runner",
|
||||
"ms-playwright.playwright"
|
||||
]
|
||||
}
|
||||
|
||||
84
.vscode/launch.json
vendored
84
.vscode/launch.json
vendored
@@ -3,12 +3,51 @@
|
||||
// Hover to view descriptions of existing attributes.
|
||||
"configurations": [
|
||||
{
|
||||
"command": "pnpm run dev _community",
|
||||
"command": "pnpm generate:types",
|
||||
"name": "Generate Types CLI",
|
||||
"request": "launch",
|
||||
"type": "node-terminal",
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js _community",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Community",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js live-preview",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Live Preview",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/loader/init.js",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Loader",
|
||||
"request": "launch",
|
||||
"type": "node-terminal",
|
||||
"env": {
|
||||
"LOADER_TEST_FILE_PATH": "./dependency-test.js"
|
||||
// "LOADER_TEST_FILE_PATH": "../fields/config.ts"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js admin",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Admin",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js auth",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Auth",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev plugin-cloud-storage",
|
||||
"cwd": "${workspaceFolder}",
|
||||
@@ -20,50 +59,50 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev fields",
|
||||
"command": "node --no-deprecation test/dev.js collections-graphql",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev GraphQL",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "node --no-deprecation test/dev.js fields",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Fields",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev:postgres fields",
|
||||
"command": "node --no-deprecation test/dev.js versions",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Postgres",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
"type": "node-terminal",
|
||||
"env": {
|
||||
"PAYLOAD_DATABASE": "postgres"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev versions",
|
||||
"command": "node --no-deprecation test/dev.js versions",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Versions",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev localization",
|
||||
"command": "node --no-deprecation test/dev.js localization",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Localization",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev uploads",
|
||||
"command": "node --no-deprecation test/dev.js uploads",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Uploads",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "PAYLOAD_BUNDLER=vite pnpm run dev fields",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Fields (Vite)",
|
||||
"request": "launch",
|
||||
"type": "node-terminal",
|
||||
"env": {
|
||||
"NODE_ENV": "production"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "pnpm run test:int live-preview",
|
||||
"cwd": "${workspaceFolder}",
|
||||
@@ -102,17 +141,6 @@
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "ts-node ./packages/payload/src/bin/index.ts generate:types",
|
||||
"env": {
|
||||
"PAYLOAD_CONFIG_PATH": "test/_community/config.ts",
|
||||
"DISABLE_SWC": "true" // SWC messes up debugging the bin scripts
|
||||
},
|
||||
"name": "Generate Types CLI",
|
||||
"outputCapture": "std",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "ts-node ./packages/payload/src/bin/index.ts migrate:status",
|
||||
"env": {
|
||||
|
||||
14
.vscode/settings.json
vendored
14
.vscode/settings.json
vendored
@@ -5,21 +5,21 @@
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"[json]": {
|
||||
@@ -35,5 +35,11 @@
|
||||
"eslint.rules.customizations": [{ "rule": "*", "severity": "warn" }],
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
// Load .git-blame-ignore-revs file
|
||||
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"]
|
||||
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"],
|
||||
"[javascript][typescript][typescriptreact]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"files.insertFinalNewline": true
|
||||
}
|
||||
|
||||
114
CHANGELOG.md
114
CHANGELOG.md
@@ -1,11 +1,120 @@
|
||||
## [2.11.2](https://github.com/payloadcms/payload/compare/v2.11.1...v2.11.2) (2024-02-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **db-postgres:** configurable custom schema to use ([#5047](https://github.com/payloadcms/payload/issues/5047)) ([e8f2ca4](https://github.com/payloadcms/payload/commit/e8f2ca484ee56cd7767d5111e46ebd24752ff8de))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Add Context Provider in EditMany Component ([#5005](https://github.com/payloadcms/payload/issues/5005)) ([70e57fe](https://github.com/payloadcms/payload/commit/70e57fef184f7fcf56344ea755465f246f2253a5))
|
||||
* **db-mongodb:** unique sparse for not required fields ([#5114](https://github.com/payloadcms/payload/issues/5114)) ([815bdfa](https://github.com/payloadcms/payload/commit/815bdfac0b0afbff2a20e54d5aee64b90f6b3a77))
|
||||
* **db-postgres:** set _parentID for array nested localized fields ([#5117](https://github.com/payloadcms/payload/issues/5117)) ([ceca5c4](https://github.com/payloadcms/payload/commit/ceca5c4e97f53f1346797a31b6abfc0375e98215))
|
||||
* disabling API Key does not remove the key ([#5145](https://github.com/payloadcms/payload/issues/5145)) ([7a7f0ed](https://github.com/payloadcms/payload/commit/7a7f0ed7e8132253be607c111c160163b84bd770))
|
||||
* handle thrown errors in config-level afterError hook ([#5147](https://github.com/payloadcms/payload/issues/5147)) ([32ed95e](https://github.com/payloadcms/payload/commit/32ed95e1ee87409db234f1b7bd6d2e462fd9ed5d))
|
||||
* only replace the drawer content with full edit component if it exists ([#5144](https://github.com/payloadcms/payload/issues/5144)) ([0a07f60](https://github.com/payloadcms/payload/commit/0a07f607b9fb1217ad956cd05b2a84a4042a19ca))
|
||||
* transaction error from access endpoint ([#5156](https://github.com/payloadcms/payload/issues/5156)) ([ad42d54](https://github.com/payloadcms/payload/commit/ad42d541b342ed56463b81cee6d6307df6f06d7f))
|
||||
|
||||
## [2.11.1](https://github.com/payloadcms/payload/compare/v2.11.0...v2.11.1) (2024-02-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **db-postgres:** adds idType to use uuid or serial id columns ([#3864](https://github.com/payloadcms/payload/issues/3864)) ([d6c2578](https://github.com/payloadcms/payload/commit/d6c25783cfa97983bf9db27ceb5ccd39a62c62f1))
|
||||
* **db-postgres:** reconnect after disconnection from database ([#5086](https://github.com/payloadcms/payload/issues/5086)) ([bf942fd](https://github.com/payloadcms/payload/commit/bf942fdfa6ea9c26cf05295cc9db646bf31fa622))
|
||||
* **plugin-search:** add req to beforeSync args for transactions ([#5068](https://github.com/payloadcms/payload/issues/5068)) ([98b87e2](https://github.com/payloadcms/payload/commit/98b87e22782c0a788f79326f22be05a6b176ad74))
|
||||
* **richtext-lexical:** add justify aligment to AlignFeature ([#4035](https://github.com/payloadcms/payload/issues/4035)) ([#4868](https://github.com/payloadcms/payload/issues/4868)) ([6d6823c](https://github.com/payloadcms/payload/commit/6d6823c3e5609a58eeeeb8d043945a762f9463df))
|
||||
* **richtext-lexical:** AddBlock handle for all nodes, even if they aren't empty paragraphs ([#5063](https://github.com/payloadcms/payload/issues/5063)) ([00fc034](https://github.com/payloadcms/payload/commit/00fc0343dabf184d5bab418d47c403b3ad11698f))
|
||||
* **richtext-lexical:** Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground ([#5066](https://github.com/payloadcms/payload/issues/5066)) ([0d18822](https://github.com/payloadcms/payload/commit/0d18822062275c1826c8e2c3da2571a2b3483310))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **db-mongodb:** find versions pagination ([#5091](https://github.com/payloadcms/payload/issues/5091)) ([5d4022f](https://github.com/payloadcms/payload/commit/5d4022f1445e2809c01cb1dd599280f0a56cdc6e))
|
||||
* **db-postgres:** query using blockType ([#5044](https://github.com/payloadcms/payload/issues/5044)) ([35c2a08](https://github.com/payloadcms/payload/commit/35c2a085efa6d5ad59779960874bc9728a17e3a0))
|
||||
* filterOptions errors cause transaction to abort ([#5079](https://github.com/payloadcms/payload/issues/5079)) ([5f3d016](https://github.com/payloadcms/payload/commit/5f3d0169bee21e1c0963dbd7ede9fe5f1c46a5a5))
|
||||
* **plugin-form-builder:** hooks do not respect transactions ([#5069](https://github.com/payloadcms/payload/issues/5069)) ([82e9d31](https://github.com/payloadcms/payload/commit/82e9d31127c8df83c5bed92a5ffdab76d331900f))
|
||||
* remove collection findByID caching ([#5034](https://github.com/payloadcms/payload/issues/5034)) ([1ac943e](https://github.com/payloadcms/payload/commit/1ac943ed5e8416883b863147fdf3c23380955559))
|
||||
* **richtext-lexical:** do not remove adjacent paragraph node when inserting certain nodes in empty editor ([#5061](https://github.com/payloadcms/payload/issues/5061)) ([6323965](https://github.com/payloadcms/payload/commit/6323965c652ea68dffeb716957b124d165b9ce96))
|
||||
* **uploads:** account for serverURL when retrieving external file ([#5102](https://github.com/payloadcms/payload/issues/5102)) ([25cee8b](https://github.com/payloadcms/payload/commit/25cee8bb102bf80b3a4bfb4b4e46712722cc7f0d))
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES: @payloadcms/richtext-lexical
|
||||
|
||||
* **richtext-lexical:** Update lexical from 0.12.6 to 0.13.1, port over all useful changes from playground (#5066)
|
||||
|
||||
- You HAVE to make sure that any versions of the lexical packages (IF you have any installed) match the lexical version which richtext-lexical uses: v0.13.1. If you do not do this, you may be plagued by React useContext / "cannot find active editor state" errors
|
||||
- Updates to lexical's API, e.g. the removal of INTERNAL_isPointSelection, could be breaking depending on your code. Please consult the [lexical changelog](https://github.com/facebook/lexical/blob/main/CHANGELOG.md).
|
||||
|
||||
## [2.11.0](https://github.com/payloadcms/payload/compare/v2.10.1...v2.11.0) (2024-02-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* exposes collapsible provider with more functionality ([#5043](https://github.com/payloadcms/payload/issues/5043)) ([df39602](https://github.com/payloadcms/payload/commit/df39602758ae8dc3765bb48e51f7a657babfa559))
|
||||
|
||||
## [2.10.1](https://github.com/payloadcms/payload/compare/v2.10.0...v2.10.1) (2024-02-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* clearable cells handle null values ([#5038](https://github.com/payloadcms/payload/issues/5038)) ([f6d7da7](https://github.com/payloadcms/payload/commit/f6d7da751039df25066b51bb91d6453e1a4efd82))
|
||||
* **db-mongodb:** handle null values with exists ([#5037](https://github.com/payloadcms/payload/issues/5037)) ([cdc4cb9](https://github.com/payloadcms/payload/commit/cdc4cb971b9180ba2ed09741f5af1a3c18292828))
|
||||
* **db-postgres:** handle nested docs with drafts ([#5012](https://github.com/payloadcms/payload/issues/5012)) ([da184d4](https://github.com/payloadcms/payload/commit/da184d40ece74bffb224002eb5df8f6987d65043))
|
||||
* ensures docs with the same id are shown in relationship field select ([#4859](https://github.com/payloadcms/payload/issues/4859)) ([e1813fb](https://github.com/payloadcms/payload/commit/e1813fb884e0dc84203fcbab87527a99a4d3a5d7))
|
||||
* query relationships by explicit id field ([#5022](https://github.com/payloadcms/payload/issues/5022)) ([a0a58e7](https://github.com/payloadcms/payload/commit/a0a58e7fd20dff54d210c968f4d5defd67441bdd))
|
||||
* **richtext-lexical:** make editor reactive to initialValue changes ([#5010](https://github.com/payloadcms/payload/issues/5010)) ([2315781](https://github.com/payloadcms/payload/commit/2315781f1891ddde4b4c5f2f0cfa1c17af85b7a9))
|
||||
|
||||
## [2.10.0](https://github.com/payloadcms/payload/compare/v2.9.0...v2.10.0) (2024-02-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add more options to addFieldStatePromise so that it can be used for field flattening ([#4799](https://github.com/payloadcms/payload/issues/4799)) ([8725d41](https://github.com/payloadcms/payload/commit/8725d411645bb0270376e235669f46be2227ecc0))
|
||||
* extend transactions to cover after and beforeOperation hooks ([#4960](https://github.com/payloadcms/payload/issues/4960)) ([1e8a6b7](https://github.com/payloadcms/payload/commit/1e8a6b7899f7b1e6451cc4d777602208478b483c))
|
||||
* previousValue and previousSiblingDoc args added to beforeChange field hooks ([#4958](https://github.com/payloadcms/payload/issues/4958)) ([5d934ba](https://github.com/payloadcms/payload/commit/5d934ba02d07d98f781ce983228858ee5ce5c226))
|
||||
* re-use existing logger instance passed to payload.init ([#3124](https://github.com/payloadcms/payload/issues/3124)) ([471d211](https://github.com/payloadcms/payload/commit/471d2113a790dc0d54b2f8ed84e6899310efd600))
|
||||
* **richtext-lexical:** Blocks: generate type definitions for blocks fields ([#4529](https://github.com/payloadcms/payload/issues/4529)) ([90d7ee3](https://github.com/payloadcms/payload/commit/90d7ee3e6535d51290fc734b284ff3811dbda1f8))
|
||||
* use deletion success message from server if provided ([#4966](https://github.com/payloadcms/payload/issues/4966)) ([e3c8105](https://github.com/payloadcms/payload/commit/e3c8105cc2ed6fdf8007d97cd7b5556fc71ed724))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **db-postgres:** filtering relationships with drafts enabled ([#4998](https://github.com/payloadcms/payload/issues/4998)) ([c3a3942](https://github.com/payloadcms/payload/commit/c3a39429697e9d335e9be199e7caafb82eb26219))
|
||||
* **db-postgres:** handle schema changes with supabase ([#4968](https://github.com/payloadcms/payload/issues/4968)) ([5d3659d](https://github.com/payloadcms/payload/commit/5d3659d48ad8bbf5d96fbcd80434d2287cab97e0))
|
||||
* **db-postgres:** indexes not created for non unique field names ([#4967](https://github.com/payloadcms/payload/issues/4967)) ([64f705c](https://github.com/payloadcms/payload/commit/64f705c3c94148972f67e8175e718015760d6430))
|
||||
* **db-postgres:** indexes not creating for relationships, arrays, hasmany and blocks ([#4976](https://github.com/payloadcms/payload/issues/4976)) ([47106d5](https://github.com/payloadcms/payload/commit/47106d5a1af2ebd073fbbc6e474174c3d3835e5c))
|
||||
* **db-postgres:** localized field sort count ([#4997](https://github.com/payloadcms/payload/issues/4997)) ([f3876c2](https://github.com/payloadcms/payload/commit/f3876c2a39efe19a1864213306725aadcc14f130))
|
||||
* ensures docPermissions fallback to collection permissions on create ([#4969](https://github.com/payloadcms/payload/issues/4969)) ([afa2b94](https://github.com/payloadcms/payload/commit/afa2b942e0aad90c55744ae13e0ffe1cefa4585d))
|
||||
* **migrations:** safely create migration file when no name passed ([#4995](https://github.com/payloadcms/payload/issues/4995)) ([0740d50](https://github.com/payloadcms/payload/commit/0740d5095ee1aef13e4e37f6b174d529f0f2d993))
|
||||
* **plugin-seo:** tabbedUI with email field causes duplicate field ([#4944](https://github.com/payloadcms/payload/issues/4944)) ([db22cbd](https://github.com/payloadcms/payload/commit/db22cbdf21a39ed0604ab96c57ca4242eac82ce7))
|
||||
|
||||
## [2.9.0](https://github.com/payloadcms/payload/compare/v2.8.2...v2.9.0) (2024-01-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* forceAcceptWarning migration arg added to accept prompts ([#4874](https://github.com/payloadcms/payload/issues/4874)) ([eba53ba](https://github.com/payloadcms/payload/commit/eba53ba60afd7c5d37389377ed06a9b556058d49))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* afterLogin hook write conflicts ([#4904](https://github.com/payloadcms/payload/issues/4904)) ([3eb681e](https://github.com/payloadcms/payload/commit/3eb681e847e9c55eaaa69c22bea4f4e66c7eac36))
|
||||
* **db-postgres:** migrate down error ([#4861](https://github.com/payloadcms/payload/issues/4861)) ([dfba522](https://github.com/payloadcms/payload/commit/dfba5222f3abf3f236dc9212a28e1aec7d7214d5))
|
||||
* **db-postgres:** query unset relation ([#4862](https://github.com/payloadcms/payload/issues/4862)) ([8ce15c8](https://github.com/payloadcms/payload/commit/8ce15c8b07800397a50dcf790c263ed5b3cfad53))
|
||||
* migrate down missing filter for latest batch ([#4860](https://github.com/payloadcms/payload/issues/4860)) ([b99d24f](https://github.com/payloadcms/payload/commit/b99d24fcfa698c493ea01c41621201abe18fabe3))
|
||||
* **plugin-cloud-storage:** slow get file performance large collections ([#4927](https://github.com/payloadcms/payload/issues/4927)) ([f73d503](https://github.com/payloadcms/payload/commit/f73d503fecdfa5cefdc26ab9aad60b00563f881e))
|
||||
* remove No Options dropdown from hasMany fields ([#4899](https://github.com/payloadcms/payload/issues/4899)) ([e5a7907](https://github.com/payloadcms/payload/commit/e5a7907a72c1371447ac2f71fce213ed22246092))
|
||||
* upload input drawer does not show draft versions ([#4903](https://github.com/payloadcms/payload/issues/4903)) ([6930c4e](https://github.com/payloadcms/payload/commit/6930c4e9f2200853121391ad8f8df48ea66c40a4))
|
||||
|
||||
## [2.8.2](https://github.com/payloadcms/payload/compare/v2.8.1...v2.8.2) (2024-01-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **db-postgres:** support drizzle logging config ([#4809](https://github.com/payloadcms/payload/issues/4809)) ([371353f](https://github.com/payloadcms/payload/commit/371353f1535fbab4ebd9f56fc14fd10a30eec289))
|
||||
* **plugin-form-builder:** add validation for form ID when creating a submission
|
||||
* **plugin-seo:** allow field and interface overrides
|
||||
* **plugin-form-builder:** add validation for form ID when creating a submission ([#4730](https://github.com/payloadcms/payload/pull/4730))
|
||||
* **plugin-seo:** add support for interfaceName and fieldOverrides ([#4695](https://github.com/payloadcms/payload/pull/4695))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -14,6 +123,7 @@
|
||||
* **db-postgres:** Remove duplicate keys from response ([#4747](https://github.com/payloadcms/payload/issues/4747)) ([eb9e771](https://github.com/payloadcms/payload/commit/eb9e771a9ca03636486d36654f215b73435574cb))
|
||||
* **db-postgres:** validateExistingBlockIsIdentical with arrays ([3b88adc](https://github.com/payloadcms/payload/commit/3b88adc7d0594af63ce190c40c9ee3905df67a31))
|
||||
* **db-postgres:** validateExistingBlockIsIdentical with other tables ([0647c87](https://github.com/payloadcms/payload/commit/0647c870f15dc1b122734b678c2abeb6f56377d4))
|
||||
* **plugin-seo:** fix missing spread operator in URL generator function ([#4723](https://github.com/payloadcms/payload/pull/4723))
|
||||
* removes max-width from field-types class & correctly sets it on uploads ([#4829](https://github.com/payloadcms/payload/issues/4829)) ([ee5390a](https://github.com/payloadcms/payload/commit/ee5390aaca37a4154cde8392b60f091ec3e5175c))
|
||||
|
||||
## [2.8.1](https://github.com/payloadcms/payload/compare/v2.8.0...v2.8.1) (2024-01-12)
|
||||
|
||||
22
app/(payload)/admin/[[...segments]]/not-found.tsx
Normal file
22
app/(payload)/admin/[[...segments]]/not-found.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
|
||||
type Args = {
|
||||
params: {
|
||||
segments: string[]
|
||||
}
|
||||
searchParams: {
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const NotFound = ({ params, searchParams }: Args) => NotFoundPage({ config, params, searchParams })
|
||||
|
||||
export default NotFound
|
||||
22
app/(payload)/admin/[[...segments]]/page.tsx
Normal file
22
app/(payload)/admin/[[...segments]]/page.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
|
||||
type Args = {
|
||||
params: {
|
||||
segments: string[]
|
||||
}
|
||||
searchParams: {
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
|
||||
|
||||
export default Page
|
||||
10
app/(payload)/api/[...slug]/route.ts
Normal file
10
app/(payload)/api/[...slug]/route.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = REST_GET(config)
|
||||
export const POST = REST_POST(config)
|
||||
export const DELETE = REST_DELETE(config)
|
||||
export const PATCH = REST_PATCH(config)
|
||||
export const OPTIONS = REST_OPTIONS(config)
|
||||
6
app/(payload)/api/graphql-playground/route.ts
Normal file
6
app/(payload)/api/graphql-playground/route.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||
6
app/(payload)/api/graphql/route.ts
Normal file
6
app/(payload)/api/graphql/route.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY it because it could be re-written at any time. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
15
app/(payload)/layout.tsx
Normal file
15
app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import configPromise from '@payload-config'
|
||||
import { RootLayout } from '@payloadcms/next/layouts'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import React from 'react'
|
||||
|
||||
import './custom.scss'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
|
||||
|
||||
export default Layout
|
||||
5
app/my-route/route.ts
Normal file
5
app/my-route/route.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const GET = () => {
|
||||
return Response.json({
|
||||
hello: 'elliot',
|
||||
})
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
module.exports = {
|
||||
// gitRawCommitsOpts: {
|
||||
// from: 'v2.0.9',
|
||||
// path: 'packages/payload',
|
||||
// },
|
||||
// infile: 'CHANGELOG.md',
|
||||
options: {
|
||||
preset: {
|
||||
name: 'conventionalcommits',
|
||||
types: [
|
||||
{ section: 'Features', type: 'feat' },
|
||||
{ section: 'Features', type: 'feature' },
|
||||
{ section: 'Bug Fixes', type: 'fix' },
|
||||
{ section: 'Documentation', type: 'docs' },
|
||||
],
|
||||
},
|
||||
},
|
||||
// outfile: 'NEW.md',
|
||||
writerOpts: {
|
||||
commitGroupsSort: (a, b) => {
|
||||
const groupOrder = ['Features', 'Bug Fixes', 'Documentation']
|
||||
return groupOrder.indexOf(a.title) - groupOrder.indexOf(b.title)
|
||||
},
|
||||
|
||||
// Scoped commits at the end, alphabetical sort
|
||||
commitsSort: (a, b) => {
|
||||
if (a.scope || b.scope) {
|
||||
if (!a.scope) return -1
|
||||
if (!b.scope) return 1
|
||||
return a.scope === b.scope
|
||||
? a.subject.localeCompare(b.subject)
|
||||
: a.scope.localeCompare(b.scope)
|
||||
}
|
||||
|
||||
// Alphabetical sort
|
||||
return a.subject.localeCompare(b.subject)
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -33,7 +33,7 @@ import { webpackBundler } from '@payloadcms/bundler-webpack'
|
||||
export default buildConfig({
|
||||
// highlight-start
|
||||
admin: {
|
||||
bundler: webpackBundler() // or viteBundler()
|
||||
bundler: webpackBundler(), // or viteBundler()
|
||||
},
|
||||
// highlight-end
|
||||
})
|
||||
@@ -48,7 +48,7 @@ Since the bundled file is sent to the browser, it can't include any server-only
|
||||
<Banner type="warning">
|
||||
<strong>Using environment variables in the admin UI</strong>
|
||||
<br />
|
||||
Bundles should not contain sensitive information. By default, Payload
|
||||
excludes env variables from the bundle. If you need to use env variables in your payload config,
|
||||
you need to prefix them with `PAYLOAD_PUBLIC_` to make them available to the client-side code.
|
||||
Bundles should not contain sensitive information. By default, Payload excludes env variables from
|
||||
the bundle. If you need to use env variables in your payload config, you need to prefix them with
|
||||
`PAYLOAD_PUBLIC_` to make them available to the client-side code.
|
||||
</Banner>
|
||||
|
||||
@@ -13,29 +13,29 @@ To swap in your own React component, first, consult the list of available compon
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
<br />
|
||||
Custom components will automatically be provided with all props that the default component normally
|
||||
accepts.
|
||||
Custom components will automatically be provided with all props that the default component
|
||||
normally accepts.
|
||||
</Banner>
|
||||
|
||||
### Base Component Overrides
|
||||
|
||||
You can override a set of admin panel-wide components by providing a component to your base Payload config's `admin.components` property. The following options are available:
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Nav`** | Contains the sidebar / mobile menu in its entirety. |
|
||||
| **`BeforeNavLinks`** | Array of components to inject into the built-in Nav, _before_ the links themselves. |
|
||||
| **`AfterNavLinks`** | Array of components to inject into the built-in Nav, _after_ the links. |
|
||||
| **`BeforeDashboard`** | Array of components to inject into the built-in Dashboard, _before_ the default dashboard contents. |
|
||||
| **`AfterDashboard`** | Array of components to inject into the built-in Dashboard, _after_ the default dashboard contents. [Demo](https://github.com/payloadcms/payload/tree/main/test/admin/components/AfterDashboard/index.tsx) |
|
||||
| **`BeforeLogin`** | Array of components to inject into the built-in Login, _before_ the default login form. |
|
||||
| **`AfterLogin`** | Array of components to inject into the built-in Login, _after_ the default login form. |
|
||||
| **`logout.Button`** | A custom React component. |
|
||||
| **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. |
|
||||
| **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. |
|
||||
| **`providers`** | Define your own provider components that will wrap the Payload Admin UI. [More](#custom-providers) |
|
||||
| **`actions`** | Array of custom components to be rendered in the Payload Admin UI header, providing additional interactivity and functionality. |
|
||||
| **`views`** | Override or create new views within the Payload Admin UI. [More](#views) |
|
||||
| Path | Description |
|
||||
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Nav`** | Contains the sidebar / mobile menu in its entirety. |
|
||||
| **`BeforeNavLinks`** | Array of components to inject into the built-in Nav, _before_ the links themselves. |
|
||||
| **`AfterNavLinks`** | Array of components to inject into the built-in Nav, _after_ the links. |
|
||||
| **`BeforeDashboard`** | Array of components to inject into the built-in Dashboard, _before_ the default dashboard contents. |
|
||||
| **`AfterDashboard`** | Array of components to inject into the built-in Dashboard, _after_ the default dashboard contents. [Demo](https://github.com/payloadcms/payload/tree/main/test/admin/components/AfterDashboard/index.tsx) |
|
||||
| **`BeforeLogin`** | Array of components to inject into the built-in Login, _before_ the default login form. |
|
||||
| **`AfterLogin`** | Array of components to inject into the built-in Login, _after_ the default login form. |
|
||||
| **`logout.Button`** | A custom React component. |
|
||||
| **`graphics.Icon`** | Used as a graphic within the `Nav` component. Often represents a condensed version of a full logo. |
|
||||
| **`graphics.Logo`** | The full logo to be used in contexts like the `Login` view. |
|
||||
| **`providers`** | Define your own provider components that will wrap the Payload Admin UI. [More](#custom-providers) |
|
||||
| **`actions`** | Array of custom components to be rendered in the Payload Admin UI header, providing additional interactivity and functionality. |
|
||||
| **`views`** | Override or create new views within the Payload Admin UI. [More](#views) |
|
||||
|
||||
Here is a full example showing how to swap some of these components for your own.
|
||||
|
||||
@@ -77,10 +77,10 @@ export default buildConfig({
|
||||
|
||||
You can easily swap entire views with your own by using the `admin.components.views` property. At the root level, Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Account`** | The Account view is used to show the currently logged in user's Account page. |
|
||||
| **`Dashboard`** | The main landing page of the Admin panel. |
|
||||
| Property | Description |
|
||||
| --------------- | ----------------------------------------------------------------------------- |
|
||||
| **`Account`** | The Account view is used to show the currently logged in user's Account page. |
|
||||
| **`Dashboard`** | The main landing page of the Admin panel. |
|
||||
|
||||
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. For example:
|
||||
|
||||
@@ -135,7 +135,10 @@ To add a _new_ view to the Admin Panel, simply add another key to the `views` ob
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
Routes are cascading. This means that unless explicitly given the `exact` property, they will match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all routes in your application. Alternatively, you could define your nested route _before_ your parent route.
|
||||
Routes are cascading. This means that unless explicitly given the `exact` property, they will
|
||||
match on URLs that simply _start_ with the route's path. This is helpful when creating catch-all
|
||||
routes in your application. Alternatively, you could define your nested route _before_ your parent
|
||||
route.
|
||||
</Banner>
|
||||
|
||||
_For more examples regarding how to customize components, look at the following [examples](https://github.com/payloadcms/payload/tree/main/test/admin/components)._
|
||||
@@ -214,7 +217,7 @@ export const MyCollection: SanitizedCollectionConfig = {
|
||||
PreviewButton: CustomPreviewButton,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -222,10 +225,10 @@ export const MyCollection: SanitizedCollectionConfig = {
|
||||
|
||||
To swap out entire views on collections, you can use the `admin.components.views` property on the collection's config. Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Edit`** | The Edit view is used to edit a single document for a given collection. |
|
||||
| **`List`** | The List view is used to show a list of documents for a given collection. |
|
||||
| Property | Description |
|
||||
| ---------- | ------------------------------------------------------------------------- |
|
||||
| **`Edit`** | The Edit view is used to edit a single document for a given collection. |
|
||||
| **`List`** | The List view is used to show a list of documents for a given collection. |
|
||||
|
||||
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, tabs, etc, _as well as all nested routes_.
|
||||
|
||||
@@ -310,9 +313,9 @@ As with Collections, you can override components on a global-by-global basis via
|
||||
|
||||
To swap out views for globals, you can use the `admin.components.views` property on the global's config. Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Edit`** | The Edit view is used to edit a single document for a given Global. |
|
||||
| Property | Description |
|
||||
| ---------- | ------------------------------------------------------------------- |
|
||||
| **`Edit`** | The Edit view is used to edit a single document for a given Global. |
|
||||
|
||||
To swap out any of these views, simply pass in your custom component to the `admin.components.views` property of your Payload config. This will replace the entire view, including the page breadcrumbs, title, and tabs, _as well as all nested views_.
|
||||
|
||||
@@ -379,13 +382,13 @@ You can also add _new_ tabs to the `Edit` view by adding another key to the `com
|
||||
|
||||
You can easily swap individual collection or global edit views. To do this, pass an _object_ to the `admin.components.views.Edit` property of the config. Payload renders the following views by default, all of which can be overridden:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Default`** | The Default view is the primary view in which your document is edited. |
|
||||
| **`Versions`** | The Versions view is used to view the version history of a single document. [More details](../versions) |
|
||||
| **`Version`** | The Version view is used to view a single version of a single document for a given collection. [More details](../versions). |
|
||||
| **`API`** | The API view is used to display the REST API JSON response for a given document. |
|
||||
| **`LivePreview`** | The LivePreview view is used to display the Live Preview interface. [More details](../live-preview) |
|
||||
| Property | Description |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`Default`** | The Default view is the primary view in which your document is edited. |
|
||||
| **`Versions`** | The Versions view is used to view the version history of a single document. [More details](../versions) |
|
||||
| **`Version`** | The Version view is used to view a single version of a single document for a given collection. [More details](../versions). |
|
||||
| **`API`** | The API view is used to display the REST API JSON response for a given document. |
|
||||
| **`LivePreview`** | The LivePreview view is used to display the Live Preview interface. [More details](../live-preview) |
|
||||
|
||||
Here is an example:
|
||||
|
||||
@@ -396,7 +399,8 @@ export const MyCollection: SanitizedCollectionConfig = {
|
||||
admin: {
|
||||
components: {
|
||||
views: {
|
||||
Edit: { // You can also define `components.views.Edit` as a component, this will override _all_ nested views
|
||||
Edit: {
|
||||
// You can also define `components.views.Edit` as a component, this will override _all_ nested views
|
||||
Default: MyCustomDefaultTab,
|
||||
Versions: MyCustomVersionsTab,
|
||||
Version: MyCustomVersionTab,
|
||||
@@ -423,7 +427,7 @@ export const MyCollection: SanitizedCollectionConfig = {
|
||||
Component: MyCustomTab,
|
||||
path: '/my-custom-tab',
|
||||
// You an swap the entire tab component out for your own
|
||||
Tab: MyCustomTab
|
||||
Tab: MyCustomTab,
|
||||
},
|
||||
AnotherCustomView: {
|
||||
Component: AnotherCustomView,
|
||||
@@ -432,7 +436,7 @@ export const MyCollection: SanitizedCollectionConfig = {
|
||||
Tab: {
|
||||
label: 'Another Custom View',
|
||||
href: '/another-custom-view',
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -539,7 +543,6 @@ const CustomTextField: React.FC<{ path: string }> = ({ path }) => {
|
||||
const { value, setValue } = useField<string>({ path })
|
||||
// highlight-end
|
||||
|
||||
|
||||
return <input onChange={(e) => setValue(e.target.value)} value={value} />
|
||||
}
|
||||
```
|
||||
@@ -553,11 +556,11 @@ const CustomTextField: React.FC<{ path: string }> = ({ path }) => {
|
||||
|
||||
These are the props that will be passed to your custom Label.
|
||||
|
||||
| Property | Description |
|
||||
| ---------------- | ---------------------------------------------------------------- |
|
||||
| **`htmlFor`** | Property used to set `for` attribute for label. |
|
||||
| **`label`** | Label value provided in field, it can be used with i18n. |
|
||||
| **`required`** | A boolean value that represents if the field is required or not. |
|
||||
| Property | Description |
|
||||
| -------------- | ---------------------------------------------------------------- |
|
||||
| **`htmlFor`** | Property used to set `for` attribute for label. |
|
||||
| **`label`** | Label value provided in field, it can be used with i18n. |
|
||||
| **`required`** | A boolean value that represents if the field is required or not. |
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -579,10 +582,12 @@ const CustomLabel: React.FC<Props> = (props) => {
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
if (label) {
|
||||
return (<span>
|
||||
{getTranslation(label, i18n)}
|
||||
{required && <span className="required">*</span>}
|
||||
</span>);
|
||||
return (
|
||||
<span>
|
||||
{getTranslation(label, i18n)}
|
||||
{required && <span className="required">*</span>}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
@@ -593,10 +598,10 @@ const CustomLabel: React.FC<Props> = (props) => {
|
||||
|
||||
These are the props that will be passed to your custom Error.
|
||||
|
||||
| Property | Description |
|
||||
| ---------------- | ------------------------------------------------------------- |
|
||||
| **`message`** | The error message. |
|
||||
| **`showError`** | A boolean value that represents if the error should be shown. |
|
||||
| Property | Description |
|
||||
| --------------- | ------------------------------------------------------------- |
|
||||
| **`message`** | The error message. |
|
||||
| **`showError`** | A boolean value that represents if the error should be shown. |
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -612,8 +617,8 @@ const CustomError: React.FC<Props> = (props) => {
|
||||
const { message, showError } = props
|
||||
|
||||
if (showError) {
|
||||
return <p style={{color: 'red'}}>{message}</p>
|
||||
} else return null;
|
||||
return <p style={{ color: 'red' }}>{message}</p>
|
||||
} else return null
|
||||
}
|
||||
```
|
||||
|
||||
@@ -630,7 +635,15 @@ import { Field } from 'payload/types'
|
||||
import './style.scss'
|
||||
|
||||
const ClearButton: React.FC = () => {
|
||||
return <button onClick={() => {/* ... */}}>X</button>
|
||||
return (
|
||||
<button
|
||||
onClick={() => {
|
||||
/* ... */
|
||||
}}
|
||||
>
|
||||
X
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
const titleField: Field = {
|
||||
@@ -638,12 +651,12 @@ const titleField: Field = {
|
||||
type: 'text',
|
||||
admin: {
|
||||
components: {
|
||||
afterInput: [ClearButton]
|
||||
}
|
||||
}
|
||||
afterInput: [ClearButton],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default titleField;
|
||||
export default titleField
|
||||
```
|
||||
|
||||
## Custom providers
|
||||
|
||||
@@ -104,6 +104,7 @@ By default the browser bundle will now include all the code from that file and a
|
||||
To fix this, we need to alias the `createStripeSubscription` file to a different file that can safely be included in the browser bundle.
|
||||
|
||||
First, we will create a mock file to replace the server-only file when bundling:
|
||||
|
||||
```js
|
||||
// mocks/modules.js
|
||||
|
||||
@@ -131,7 +132,7 @@ import { Subscriptions } from './collections/Subscriptions'
|
||||
const mockModulePath = path.resolve(__dirname, 'mocks/emptyObject.js')
|
||||
const fullFilePath = path.resolve(
|
||||
__dirname,
|
||||
'collections/Subscriptions/hooks/createStripeSubscription'
|
||||
'collections/Subscriptions/hooks/createStripeSubscription',
|
||||
)
|
||||
|
||||
export default buildConfig({
|
||||
@@ -173,24 +174,23 @@ export default buildConfig({
|
||||
admin: {
|
||||
bundler: viteBundler(),
|
||||
vite: (incomingViteConfig) => {
|
||||
const existingAliases = incomingViteConfig?.resolve?.alias || {};
|
||||
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
|
||||
const existingAliases = incomingViteConfig?.resolve?.alias || {}
|
||||
let aliasArray: { find: string | RegExp; replacement: string }[] = []
|
||||
|
||||
// Pass the existing Vite aliases
|
||||
if (Array.isArray(existingAliases)) {
|
||||
aliasArray = existingAliases;
|
||||
aliasArray = existingAliases
|
||||
} else {
|
||||
aliasArray = Object.values(existingAliases);
|
||||
aliasArray = Object.values(existingAliases)
|
||||
}
|
||||
|
||||
|
||||
// highlight-start
|
||||
// Add your own aliases using the find and replacement keys
|
||||
// remember, vite aliases are exact-match only
|
||||
aliasArray.push({
|
||||
find: '../server-only-module',
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
|
||||
});
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js'),
|
||||
})
|
||||
// highlight-end
|
||||
|
||||
return {
|
||||
@@ -198,8 +198,8 @@ export default buildConfig({
|
||||
resolve: {
|
||||
...(incomingViteConfig?.resolve || {}),
|
||||
alias: aliasArray,
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -635,12 +635,44 @@ export const CustomArrayManager = () => {
|
||||
]}
|
||||
/>
|
||||
|
||||
### useCollapsible
|
||||
|
||||
The `useCollapsible` hook allows you to control parent collapsibles:
|
||||
|
||||
| Property | Description |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------ | --- |
|
||||
| **`isCollapsed`** | State of the collapsible. `true` if open, `false` if collapsed |
|
||||
| **`isVisible`** | If nested, determine if the nearest collapsible is visible. `true` if no parent is closed, `false` otherwise |
|
||||
| **`toggle`** | Toggles the state of the nearest collapsible |
|
||||
| **`isWithinCollapsible`** | Determine when you are within another collaspible | |
|
||||
|
||||
**Example:**
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
|
||||
import { useCollapsible } from 'payload/components/utilities'
|
||||
|
||||
const CustomComponent: React.FC = () => {
|
||||
const { isCollapsed, toggle } = useCollapsible()
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p className="field-type">I am {isCollapsed ? 'closed' : 'open'}</p>
|
||||
<button onClick={toggle} type="button">
|
||||
Toggle
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### useDocumentInfo
|
||||
|
||||
The `useDocumentInfo` hook provides lots of information about the document currently being edited, including the following:
|
||||
|
||||
| Property | Description |
|
||||
|---------------------------|--------------------------------------------------------------------------------------------------------------------|
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`collection`** | If the doc is a collection, its collection config will be returned |
|
||||
| **`global`** | If the doc is a global, its global config will be returned |
|
||||
| **`id`** | If the doc is a collection, its ID will be returned |
|
||||
@@ -773,15 +805,17 @@ const MyComponent: React.FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<span>The current theme is {theme} and autoMode is {autoMode}</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setTheme(prev => prev === "light" ? "dark" : "light")}
|
||||
<span>
|
||||
The current theme is {theme} and autoMode is {autoMode}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setTheme((prev) => (prev === 'light' ? 'dark' : 'light'))}
|
||||
>
|
||||
Toggle theme
|
||||
</button>
|
||||
</>
|
||||
)
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -802,10 +836,7 @@ const MyComponent: React.FC = () => {
|
||||
// highlight-end
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={resetColumns}
|
||||
>
|
||||
<button type="button" onClick={resetColumns}>
|
||||
Reset columns
|
||||
</button>
|
||||
)
|
||||
@@ -816,10 +847,10 @@ const MyComponent: React.FC = () => {
|
||||
|
||||
The `useDocumentEvents` hook provides a way of subscribing to cross-document events, such as updates made to nested documents within a drawer. This hook will report document events that are outside the scope of the document currently being edited. This hook provides the following:
|
||||
|
||||
| Property | Description |
|
||||
|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`mostRecentUpdate`** | An object containing the most recently updated document. It contains the `entitySlug`, `id` (if collection), and `updatedAt` properties |
|
||||
| **`reportUpdate`** | A method used to report updates to documents. It accepts the same arguments as the `mostRecentUpdate` property. |
|
||||
| Property | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`mostRecentUpdate`** | An object containing the most recently updated document. It contains the `entitySlug`, `id` (if collection), and `updatedAt` properties |
|
||||
| **`reportUpdate`** | A method used to report updates to documents. It accepts the same arguments as the `mostRecentUpdate` property. |
|
||||
|
||||
**Example:**
|
||||
|
||||
@@ -829,14 +860,11 @@ import { useDocumentEvents } from 'payload/components/hooks'
|
||||
const ListenForUpdates: React.FC = () => {
|
||||
const { mostRecentUpdate } = useDocumentEvents()
|
||||
|
||||
return (
|
||||
<span>
|
||||
{JSON.stringify(mostRecentUpdate)}
|
||||
</span>
|
||||
)
|
||||
return <span>{JSON.stringify(mostRecentUpdate)}</span>
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="info">
|
||||
Right now the `useDocumentEvents` hook only tracks recently updated documents, but in the future it will track more document-related events as needed, such as document creation, deletion, etc.
|
||||
Right now the `useDocumentEvents` hook only tracks recently updated documents, but in the future
|
||||
it will track more document-related events as needed, such as document creation, deletion, etc.
|
||||
</Banner>
|
||||
|
||||
@@ -6,7 +6,8 @@ desc: NEEDS TO BE WRITTEN
|
||||
---
|
||||
|
||||
<Banner type="info">
|
||||
The Vite bundler is currently in beta. If you would like to help us test this package, we'd love to hear from you if you find any [bugs or issues](https://github.com/payloadcms/payload/issues/)!
|
||||
The Vite bundler is currently in beta. If you would like to help us test this package, we'd love
|
||||
to hear from you if you find any [bugs or issues](https://github.com/payloadcms/payload/issues/)!
|
||||
</Banner>
|
||||
|
||||
Payload has a Vite bundler that you can install and bundle the Admin Panel with. This is an alternative to the [Webpack](/docs/admin/webpack) bundler and might give some performance boosts to your development workflow.
|
||||
@@ -27,7 +28,7 @@ export default buildConfig({
|
||||
collections: [],
|
||||
admin: {
|
||||
bundler: viteBundler(),
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -36,7 +37,8 @@ Vite works fundamentally differently than Webpack. In development mode, it will
|
||||
It then uses Rollup to create production builds of your admin UI. With Vite, you should see a decent performance boost—especially after your first cold start. However, that first cold start might take a few more seconds.
|
||||
|
||||
<Banner type="warning">
|
||||
In most cases, Vite should work out of the box. But existing Payload plugins may need to make compatibility changes to support Vite.
|
||||
In most cases, Vite should work out of the box. But existing Payload plugins may need to make
|
||||
compatibility changes to support Vite.
|
||||
</Banner>
|
||||
|
||||
This is because Vite aliases work fundamentally differently than Webpack aliases, and Payload relies on aliasing server-only code out of the Payload config to ensure that the bundled admin JS works within your browser.
|
||||
|
||||
@@ -27,7 +27,7 @@ import { webpackBundler } from '@payloadcms/bundler-webpack'
|
||||
export default buildConfig({
|
||||
// highlight-start
|
||||
admin: {
|
||||
bundler: webpackBundler()
|
||||
bundler: webpackBundler(),
|
||||
},
|
||||
// highlight-end
|
||||
})
|
||||
|
||||
@@ -49,7 +49,8 @@ To enable API keys on a collection, set the `useAPIKey` auth option to `true`. F
|
||||
<strong>Important:</strong>
|
||||
If you change your `PAYLOAD_SECRET`, you will need to regenerate your API keys.
|
||||
<br />
|
||||
The secret key is used to encrypt the API keys, so if you change the secret, existing API keys will no longer be valid.
|
||||
The secret key is used to encrypt the API keys, so if you change the secret, existing API keys will
|
||||
no longer be valid.
|
||||
</Banner>
|
||||
|
||||
#### Authenticating via API Key
|
||||
|
||||
@@ -57,12 +57,7 @@ export const Admins: CollectionConfig = {
|
||||
name: 'role',
|
||||
type: 'select',
|
||||
required: true,
|
||||
options: [
|
||||
'user',
|
||||
'admin',
|
||||
'editor',
|
||||
'developer',
|
||||
],
|
||||
options: ['user', 'admin', 'editor', 'developer'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -13,23 +13,25 @@ It's often best practice to write your Collections in separate files and then im
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
|
||||
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
|
||||
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-options). |
|
||||
| **`hooks`** | Entry points to "tie in" to Collection actions at specific points. [More](/docs/hooks/overview#collection-hooks) |
|
||||
| **`access`** | Provide access control functions to define exactly who should be able to do what with Documents in this Collection. [More](/docs/access-control/overview/#collections) |
|
||||
| **`auth`** | Specify options if you would like this Collection to feature authentication. For more, consult the [Authentication](/docs/authentication/config) documentation. |
|
||||
| **`upload`** | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](/docs/upload/overview) documentation. |
|
||||
| **`timestamps`** | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. |
|
||||
| **`versions`** | Set to true to enable default options, or configure with object properties. [More](/docs/versions/overview#collection-config) |
|
||||
| **`endpoints`** | Add custom routes to the REST API. Set to `false` to disable routes. [More](/docs/rest-api/overview#custom-endpoints) |
|
||||
| **`graphQL`** | An object with `singularName` and `pluralName` strings used in schema generation. Auto-generated from slug if not defined. Set to `false` to disable GraphQL. |
|
||||
| **`typescript`** | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
|
||||
| **`defaultSort`** | Pass a top-level field to sort by default in the collection List view. Prefix the name of the field with a minus symbol ("-") to sort in descending order. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
|------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`slug`** \* | Unique, URL-friendly string that will act as an identifier for this Collection. |
|
||||
| **`fields`** \* | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
|
||||
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-options). |
|
||||
| **`hooks`** | Entry points to "tie in" to Collection actions at specific points. [More](/docs/hooks/overview#collection-hooks) |
|
||||
| **`access`** | Provide access control functions to define exactly who should be able to do what with Documents in this Collection. [More](/docs/access-control/overview/#collections) |
|
||||
| **`auth`** | Specify options if you would like this Collection to feature authentication. For more, consult the [Authentication](/docs/authentication/config) documentation. |
|
||||
| **`upload`** | Specify options if you would like this Collection to support file uploads. For more, consult the [Uploads](/docs/upload/overview) documentation. |
|
||||
| **`timestamps`** | Set to false to disable documents' automatically generated `createdAt` and `updatedAt` timestamps. |
|
||||
| **`versions`** | Set to true to enable default options, or configure with object properties. [More](/docs/versions/overview#collection-config) |
|
||||
| **`endpoints`** | Add custom routes to the REST API. Set to `false` to disable routes. [More](/docs/rest-api/overview#custom-endpoints) |
|
||||
| **`graphQL`** | An object with `singularName` and `pluralName` strings used in schema generation. Auto-generated from slug if not defined. Set to `false` to disable GraphQL. |
|
||||
| **`typescript`** | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
|
||||
| **`disableDuplicate`** | When true, do not show the "Duplicate" button while editing documents within this collection and prevent `duplicate` from all APIs. |
|
||||
| **`defaultSort`** | Pass a top-level field to sort by default in the collection List view. Prefix the name of the field with a minus symbol ("-") to sort in descending order. |
|
||||
| **`dbName`** | Custom table or collection name depending on the database adapter. Auto-generated from slug if not defined.
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -68,14 +70,13 @@ You can customize the way that the Admin panel behaves on a collection-by-collec
|
||||
property on a collection's config.
|
||||
|
||||
| Option | Description |
|
||||
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
|
||||
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this collection from navigation and admin routing. |
|
||||
| `hooks` | Admin-specific hooks for this collection. [More](#admin-hooks) |
|
||||
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin panel. If no field is defined, the ID of the document is used as the title. |
|
||||
| `description` | Text or React component to display below the Collection label in the List view to give editors more information. |
|
||||
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this collection's List view. |
|
||||
| `disableDuplicate ` | Disables the "Duplicate" button while editing documents within this collection. |
|
||||
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
|
||||
| `enableRichTextLink` | The [Rich Text](/docs/fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
|
||||
| `enableRichTextRelationship` | The [Rich Text](/docs/fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
|
||||
@@ -129,7 +130,7 @@ export const Posts: CollectionConfig = {
|
||||
Here are a few options that you can specify options for pagination on a collection-by-collection basis:
|
||||
|
||||
| Option | Description |
|
||||
|----------------|-----------------------------------------------------------------------------------------------------|
|
||||
| -------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `defaultLimit` | Integer that specifies the default per-page limit that should be used. Defaults to 10. |
|
||||
| `limits` | Provide an array of integers to use as per-page options for admins to choose from in the List view. |
|
||||
|
||||
@@ -167,53 +168,6 @@ those three fields plus the ID field.
|
||||
so your admin queries can remain performant.
|
||||
</Banner>
|
||||
|
||||
### Admin Hooks
|
||||
|
||||
In addition to collection hooks themselves, Payload provides for admin UI-specific hooks that you can leverage.
|
||||
|
||||
**`beforeDuplicate`**
|
||||
|
||||
The `beforeDuplicate` hook is an async function that accepts an object containing the data to duplicate, as well as the
|
||||
locale of the doc to duplicate. Within this hook, you can modify the data to be duplicated, which is useful in cases
|
||||
where you have unique fields that need to be incremented or similar, as well as if you want to automatically modify a
|
||||
document's `title`.
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
import { BeforeDuplicate, CollectionConfig } from 'payload/types'
|
||||
// Your auto-generated Page type
|
||||
import { Page } from '../payload-types.ts'
|
||||
|
||||
const beforeDuplicate: BeforeDuplicate<Page> = ({ data }) => {
|
||||
return {
|
||||
...data,
|
||||
title: `${data.title} Copy`,
|
||||
uniqueField: data.uniqueField ? `${data.uniqueField}-copy` : '',
|
||||
}
|
||||
}
|
||||
|
||||
export const Page: CollectionConfig = {
|
||||
slug: 'pages',
|
||||
admin: {
|
||||
hooks: {
|
||||
beforeDuplicate,
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'uniqueField',
|
||||
type: 'text',
|
||||
unique: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
|
||||
You can import collection types as follows:
|
||||
|
||||
@@ -26,6 +26,7 @@ As with Collection configs, it's often best practice to write your Globals in se
|
||||
| **`graphQL.name`** | Text used in schema generation. Auto-generated from slug if not defined. |
|
||||
| **`typescript`** | An object with property `interface` as the text used in schema generation. Auto-generated from slug if not defined. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`dbName`** | Custom table or collection name for this global depending on the database adapter. Auto-generated from slug if not defined.
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -65,14 +66,14 @@ You can find a few [example Global configs](https://github.com/payloadcms/public
|
||||
|
||||
You can customize the way that the Admin panel behaves on a Global-by-Global basis by defining the `admin` property on a Global's config.
|
||||
|
||||
| Option | Description |
|
||||
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
|
||||
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this global from navigation and admin routing. |
|
||||
| `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) |
|
||||
| `preview` | Function to generate a preview URL within the Admin panel for this global that can point to your app. [More](#preview). |
|
||||
| `livePreview`| Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
|
||||
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
|
||||
| Option | Description |
|
||||
| ------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group` | Text used as a label for grouping collection and global links together in the navigation. |
|
||||
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this global from navigation and admin routing. |
|
||||
| `components` | Swap in your own React components to be used within this Global. [More](/docs/admin/components#globals) |
|
||||
| `preview` | Function to generate a preview URL within the Admin panel for this global that can point to your app. [More](#preview). |
|
||||
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More](/docs/live-preview/overview). |
|
||||
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this collection. |
|
||||
|
||||
### Preview
|
||||
|
||||
|
||||
@@ -49,7 +49,8 @@ export default buildConfig({
|
||||
{
|
||||
label: 'Arabic',
|
||||
code: 'ar',
|
||||
// opt-in to setting default text-alignment on Input fields to rtl (right-to-left) when current locale is rtl
|
||||
// opt-in to setting default text-alignment on Input fields to rtl (right-to-left)
|
||||
// when current locale is rtl
|
||||
rtl: true,
|
||||
},
|
||||
],
|
||||
@@ -105,7 +106,7 @@ language and country codes (ISO 3166‑1) 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. |
|
||||
@@ -134,13 +135,9 @@ to support localization, you need to specify each field that you would like to l
|
||||
```js
|
||||
{
|
||||
name: 'title',
|
||||
type
|
||||
:
|
||||
'text',
|
||||
// highlight-start
|
||||
localized
|
||||
:
|
||||
true,
|
||||
type: 'text',
|
||||
// highlight-start
|
||||
localized: true,
|
||||
// highlight-end
|
||||
}
|
||||
```
|
||||
@@ -207,11 +204,11 @@ The `fallbackLocale` arg will accept valid locales as well as `none` to disable
|
||||
|
||||
```graphql
|
||||
query {
|
||||
Posts(locale: de, fallbackLocale: none) {
|
||||
docs {
|
||||
title
|
||||
}
|
||||
Posts(locale: de, fallbackLocale: none) {
|
||||
docs {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -19,33 +19,33 @@ Payload is a _config-based_, code-first CMS and application framework. The Paylo
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Description |
|
||||
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `admin` \* | Base Payload admin configuration. Specify bundler*, custom components, control metadata, set the Admin user collection, and [more](/docs/admin/overview#admin-options). Required. |
|
||||
| `editor` \* | Rich Text Editor which will be used by richText fields. Required. |
|
||||
| `db` \* | Database Adapter which will be used by Payload. Read more [here](/docs/database/overview). Required. |
|
||||
| `serverURL` | A string used to define the absolute URL of your app including the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port |
|
||||
| `collections` | An array of all Collections that Payload will manage. To read more about how to define your collection configs, [click here](/docs/configuration/collections). |
|
||||
| `globals` | An array of all Globals that Payload will manage. For more on Globals and their configs, [click here](/docs/configuration/globals). |
|
||||
| `cors` | Either a whitelist array of URLS to allow CORS requests from, or a wildcard string (`'*'`) to accept incoming requests from any domain. |
|
||||
| `localization` | Opt-in and control how Payload handles the translation of your content into multiple locales. [More](/docs/configuration/localization) |
|
||||
| `graphQL` | Manage GraphQL-specific functionality here. Define your own queries and mutations, manage query complexity limits, and [more](/docs/graphql/overview#graphql-options). |
|
||||
| `cookiePrefix` | A string that will be prefixed to all cookies that Payload sets. |
|
||||
| `csrf` | A whitelist array of URLs to allow Payload cookies to be accepted from as a form of CSRF protection. [More](/docs/authentication/overview#csrf-protection) |
|
||||
| `defaultDepth` | If a user does not specify `depth` while requesting a resource, this depth will be used. [More](/docs/getting-started/concepts#depth) |
|
||||
| `maxDepth` | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. |
|
||||
| `indexSortableFields` | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. |
|
||||
| `upload` | Base Payload upload configuration. [More](/docs/upload/overview#payload-wide-upload-options). |
|
||||
| `routes` | Control the routing structure that Payload binds itself to. Specify `admin`, `api`, `graphQL`, and `graphQLPlayground`. |
|
||||
| `email` | Base email settings to allow Payload to generate email such as Forgot Password requests and other requirements. [More](/docs/email/overview#configuration) |
|
||||
| `express` | Express-specific middleware options such as compression and JSON parsing. [More](/docs/configuration/express) |
|
||||
| `debug` | Enable to expose more detailed error information. |
|
||||
| `telemetry` | Disable Payload telemetry by passing `false`. [More](/docs/configuration/overview#telemetry) |
|
||||
| `rateLimit` | Control IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks and [more](/docs/production/preventing-abuse#rate-limiting-requests). |
|
||||
| `hooks` | Tap into Payload-wide hooks. [More](/docs/hooks/overview) |
|
||||
| `plugins` | An array of Payload plugins. [More](/docs/plugins/overview) |
|
||||
| `endpoints` | An array of custom API endpoints added to the Payload router. [More](/docs/rest-api/overview#custom-endpoints) |
|
||||
| `custom` | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `admin` \* | Base Payload admin configuration. Specify bundler\*, custom components, control metadata, set the Admin user collection, and [more](/docs/admin/overview#admin-options). Required. |
|
||||
| `editor` \* | Rich Text Editor which will be used by richText fields. Required. |
|
||||
| `db` \* | Database Adapter which will be used by Payload. Read more [here](/docs/database/overview). Required. |
|
||||
| `serverURL` | A string used to define the absolute URL of your app including the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port |
|
||||
| `collections` | An array of all Collections that Payload will manage. To read more about how to define your collection configs, [click here](/docs/configuration/collections). |
|
||||
| `globals` | An array of all Globals that Payload will manage. For more on Globals and their configs, [click here](/docs/configuration/globals). |
|
||||
| `cors` | Either a whitelist array of URLS to allow CORS requests from, or a wildcard string (`'*'`) to accept incoming requests from any domain. |
|
||||
| `localization` | Opt-in and control how Payload handles the translation of your content into multiple locales. [More](/docs/configuration/localization) |
|
||||
| `graphQL` | Manage GraphQL-specific functionality here. Define your own queries and mutations, manage query complexity limits, and [more](/docs/graphql/overview#graphql-options). |
|
||||
| `cookiePrefix` | A string that will be prefixed to all cookies that Payload sets. |
|
||||
| `csrf` | A whitelist array of URLs to allow Payload cookies to be accepted from as a form of CSRF protection. [More](/docs/authentication/overview#csrf-protection) |
|
||||
| `defaultDepth` | If a user does not specify `depth` while requesting a resource, this depth will be used. [More](/docs/getting-started/concepts#depth) |
|
||||
| `maxDepth` | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. |
|
||||
| `indexSortableFields` | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. |
|
||||
| `upload` | Base Payload upload configuration. [More](/docs/upload/overview#payload-wide-upload-options). |
|
||||
| `routes` | Control the routing structure that Payload binds itself to. Specify `admin`, `api`, `graphQL`, and `graphQLPlayground`. |
|
||||
| `email` | Base email settings to allow Payload to generate email such as Forgot Password requests and other requirements. [More](/docs/email/overview#configuration) |
|
||||
| `express` | Express-specific middleware options such as compression and JSON parsing. [More](/docs/configuration/express) |
|
||||
| `debug` | Enable to expose more detailed error information. |
|
||||
| `telemetry` | Disable Payload telemetry by passing `false`. [More](/docs/configuration/overview#telemetry) |
|
||||
| `rateLimit` | Control IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks and [more](/docs/production/preventing-abuse#rate-limiting-requests). |
|
||||
| `hooks` | Tap into Payload-wide hooks. [More](/docs/hooks/overview) |
|
||||
| `plugins` | An array of Payload plugins. [More](/docs/plugins/overview) |
|
||||
| `endpoints` | An array of custom API endpoints added to the Payload router. [More](/docs/rest-api/overview#custom-endpoints) |
|
||||
| `custom` | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ Ensure you have an npm script called "payload" in your `package.json` file.
|
||||
```
|
||||
|
||||
<Banner>
|
||||
Note that you need to run Payload migrations through the package manager that you are using, because Payload should not be globally installed on your system.
|
||||
Note that you need to run Payload migrations through the package manager that you are using,
|
||||
because Payload should not be globally installed on your system.
|
||||
</Banner>
|
||||
|
||||
### Migration file contents
|
||||
@@ -41,15 +42,15 @@ Here is an example migration file:
|
||||
```ts
|
||||
import { MigrateUpArgs, MigrateDownArgs } from '@payloadcms/your-db-adapter'
|
||||
|
||||
export async function up ({ payload, req }: MigrateUpArgs): Promise<void> {
|
||||
export async function up({ payload, req }: MigrateUpArgs): Promise<void> {
|
||||
// Perform changes to your database here.
|
||||
// You have access to `payload` as an argument, and
|
||||
// everything is done in TypeScript.
|
||||
};
|
||||
}
|
||||
|
||||
export async function down ({ payload, req }: MigrateDownArgs): Promise<void> {
|
||||
export async function down({ payload, req }: MigrateDownArgs): Promise<void> {
|
||||
// Do whatever you need to revert changes if the `up` function fails
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Migrations Directory
|
||||
|
||||
@@ -31,12 +31,12 @@ 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. | |
|
||||
| `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
|
||||
|
||||
|
||||
@@ -42,15 +42,15 @@ You should prefer a relational DB like Postgres if:
|
||||
|
||||
#### Differences in Payload features
|
||||
|
||||
It's important to note that almost everything Payload does is available in all of our officially supported database adapters, including localization, arrays, blocks, etc.
|
||||
It's important to note that almost everything Payload does is available in all of our officially supported database adapters, including localization, arrays, blocks, etc.
|
||||
|
||||
The only thing that is not supported in Postgres yet is the [Point field](/docs/fields/point), but that should be added soon.
|
||||
The only thing that is not supported in Postgres yet is the [Point field](/docs/fields/point), but that should be added soon.
|
||||
|
||||
It's up to you to choose which database you would like to use.
|
||||
|
||||
## Configuration
|
||||
|
||||
To configure the database for your Payload application, an adapter can be assigned to `config.db`. This property is required within your Payload config.
|
||||
To configure the database for your Payload application, an adapter can be assigned to `config.db`. This property is required within your Payload config.
|
||||
|
||||
Here's an example:
|
||||
|
||||
@@ -67,7 +67,7 @@ export default buildConfig({
|
||||
db: postgresAdapter({
|
||||
pool: {
|
||||
connectionString: process.env.DATABASE_URI,
|
||||
}
|
||||
},
|
||||
}),
|
||||
})
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
title: Postgres
|
||||
label: Postgres
|
||||
order: 50
|
||||
desc: Payload supports Postgres through an officially supported Drizzle database adapter.
|
||||
desc: Payload supports Postgres through an officially supported Drizzle database adapter.
|
||||
keywords: Postgres, documentation, typescript, Content Management System, cms, headless, javascript, node, react, express
|
||||
---
|
||||
|
||||
To use Payload with Postgres, install the package `@payloadcms/db-postgres`. It leverages Drizzle ORM and `node-postgres` to interact with a Postgres database that you provide.
|
||||
|
||||
<Banner>
|
||||
The Postgres database adapter is currently in beta. If you would like to help us test this package, we'd love to hear if you find any bugs or issues!
|
||||
The Postgres database adapter is currently in beta. If you would like to help us test this
|
||||
package, we'd love to hear if you find any bugs or issues!
|
||||
</Banner>
|
||||
|
||||
It automatically manages changes to your database for you in development mode, and exposes a full suite of migration controls for you to leverage in order to keep other database environments in sync with your schema. DDL transformations are automatically generated.
|
||||
@@ -30,18 +31,25 @@ export default buildConfig({
|
||||
// `pool` is required.
|
||||
pool: {
|
||||
connectionString: process.env.DATABASE_URI,
|
||||
}
|
||||
},
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `pool` | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres`. |
|
||||
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
|
||||
| `migrationDir` | Customize the directory that migrations are stored. |
|
||||
| Option | Description |
|
||||
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `pool` \* | [Pool connection options](https://orm.drizzle.team/docs/quick-postgresql/node-postgres) that will be passed to Drizzle and `node-postgres`. |
|
||||
| `push` | Disable Drizzle's [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push) in development mode. By default, `push` is enabled for development mode only. |
|
||||
| `migrationDir` | Customize the directory that migrations are stored. |
|
||||
| `logger` | The instance of the logger to be passed to drizzle. By default Payload's will be used. |
|
||||
| `schemaName` | A string for the postgres schema to use, defaults to 'public'. |
|
||||
| `localesSuffix` | A string appended to the end of table names for storing localized fields. Default is '_locales'. |
|
||||
| `relationshipsSuffix` | A string appended to the end of table names for storing relationships. Default is '_rels'. |
|
||||
| `versionsSuffix` | A string appended to the end of table names for storing versions. Defaults to '_v'. |
|
||||
|
||||
|
||||
|
||||
### Access to Drizzle
|
||||
|
||||
@@ -65,7 +73,7 @@ In addition to exposing Drizzle directly, all of the tables, Drizzle relations,
|
||||
|
||||
Drizzle exposes two ways to work locally in development mode.
|
||||
|
||||
The first is [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push), which automatically pushes changes you make to your Payload config (and therefore, Drizzle schema) to your database so you don't have to manually migrate every time you change your Payload config. This only works in development mode, and should not be mixed with manually running [`migrate`](/docs/database/migrations) commands.
|
||||
The first is [`db push`](https://orm.drizzle.team/kit-docs/overview#prototyping-with-db-push), which automatically pushes changes you make to your Payload config (and therefore, Drizzle schema) to your database so you don't have to manually migrate every time you change your Payload config. This only works in development mode, and should not be mixed with manually running [`migrate`](/docs/database/migrations) commands.
|
||||
|
||||
You will be warned if any changes that you make will entail data loss while in development mode. Push is enabled by default, but you can opt out if you'd like.
|
||||
|
||||
@@ -77,11 +85,13 @@ Migrations are extremely powerful thanks to the seamless way that Payload and Dr
|
||||
|
||||
1. You are building your Payload config locally, with a local database used for testing.
|
||||
1. You have left the default setting of `push` enabled, so every time you change your Payload config (add or remove fields, collections, etc.), Drizzle will automatically push changes to your local DB.
|
||||
1. Once you're done with your changes, or have completed a feature, you can run `npm run payload migrate:create`.
|
||||
1. Once you're done with your changes, or have completed a feature, you can run `npm run payload migrate:create`.
|
||||
1. Payload and Drizzle will look for any existing migrations, and automatically generate all SQL changes necessary to convert your schema from its prior state into the state of your current Payload config, and store the resulting DDL in a newly created migration.
|
||||
1. Once you're ready to go to production, you will be able to run `npm run payload migrate` against your production database, which will apply any new migrations that have not yet run.
|
||||
1. Now your production database is in sync with your Payload config!
|
||||
|
||||
<Banner type="warning">
|
||||
Warning: do not mix "push" and migrations with your local development database. If you use "push" locally, and then try to migrate, Payload will throw a warning, telling you that these two methods are not meant to be used interchangeably.
|
||||
</Banner>
|
||||
Warning: do not mix "push" and migrations with your local development database. If you use "push"
|
||||
locally, and then try to migrate, Payload will throw a warning, telling you that these two methods
|
||||
are not meant to be used interchangeably.
|
||||
</Banner>
|
||||
|
||||
@@ -20,7 +20,8 @@ The initial request made to Payload will begin a new transaction and attach it t
|
||||
|
||||
```ts
|
||||
const afterChange: CollectionAfterChangeHook = async ({ req }) => {
|
||||
// because req.transactionID is assigned from Payload and passed through, my-slug will only persist if the entire request is successful
|
||||
// because req.transactionID is assigned from Payload and passed through,
|
||||
// my-slug will only persist if the entire request is successful
|
||||
await req.payload.create({
|
||||
req,
|
||||
collection: 'my-slug',
|
||||
@@ -66,4 +67,4 @@ The following functions can be used for managing transactions:
|
||||
|
||||
`payload.db.beginTransaction` - Starts a new session and returns a transaction ID for use in other Payload Local API calls.
|
||||
`payload.db.commitTransaction` - Takes the identifier for the transaction, finalizes any changes.
|
||||
`payload.db.rollbackTransaction` - Takes the identifier for the transaction, discards any changes.
|
||||
`payload.db.rollbackTransaction` - Takes the identifier for the transaction, discards any changes.
|
||||
|
||||
@@ -25,13 +25,13 @@ in the `email` property object of your payload init call. Payload will make use
|
||||
|
||||
The following options are configurable in the `email` property object as part of the options object when calling payload.init().
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`fromName`** \* | The name part of the From field that will be seen on the delivered email |
|
||||
| **`fromAddress`** \* | The email address part of the From field that will be used when delivering email |
|
||||
| **`transport`** | The NodeMailer transport object for when you want to do it yourself, not needed when transportOptions is set |
|
||||
| Option | Description |
|
||||
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`fromName`** \* | The name part of the From field that will be seen on the delivered email |
|
||||
| **`fromAddress`** \* | The email address part of the From field that will be used when delivering email |
|
||||
| **`transport`** | The NodeMailer transport object for when you want to do it yourself, not needed when transportOptions is set |
|
||||
| **`transportOptions`** | An object that configures the transporter that Payload will create. For all the available options see the [NodeMailer documentation](https://nodemailer.com) or see the examples below |
|
||||
| **`logMockCredentials`** | If set to true and no transport/transportOptions, ethereal credentials will be logged to console on startup |
|
||||
| **`logMockCredentials`** | If set to true and no transport/transportOptions, ethereal credentials will be logged to console on startup |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ keywords: array, fields, config, configuration, documentation, Content Managemen
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`dbName`** | Custom table name for the field when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -80,7 +80,8 @@ Blocks are defined as separate configs of their own.
|
||||
| **`imageAltText`** | Customize this block's image thumbnail alt text. |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`graphQL.singularName`** | Text to use for the GraphQL schema name. Auto-generated from slug if not defined. NOTE: this is set for deprecation, prefer `interfaceName`. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`dbName`** | Custom table name for this block type when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from slug if not defined.
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
#### Auto-generated data per block
|
||||
|
||||
|
||||
@@ -17,21 +17,21 @@ keywords: checkbox, fields, config, configuration, documentation, Content Manage
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value, will default to false if field is also `required`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value, will default to false if field is also `required`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -23,24 +23,24 @@ This field uses the `monaco-react` editor syntax highlighting.
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database#overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -22,21 +22,21 @@ This field uses [`react-datepicker`](https://www.npmjs.com/package/react-datepic
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -44,20 +44,20 @@ _\* An asterisk denotes that a property is required._
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can customize the following fields that will adjust how the component displays in the admin panel via the `date` property.
|
||||
|
||||
| Property | Description |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------- |
|
||||
| **`placeholder`** | Placeholder text for the field. |
|
||||
| **`date`** | Pass options to customize date field appearance. |
|
||||
| **`date.displayFormat`** | Format date to be shown in field **cell**. |
|
||||
| **`date.pickerAppearance`** \* | Determines the appearance of the datepicker: `dayAndTime` `timeOnly` `dayOnly` `monthOnly`. |
|
||||
| **`date.monthsToShow`** \* | Number of months to display max is 2. Defaults to 1. |
|
||||
| **`date.minDate`** \* | Min date value to allow. |
|
||||
| **`date.maxDate`** \* | Max date value to allow. |
|
||||
| **`date.minTime`** \* | Min time value to allow. |
|
||||
| **`date.maxTime`** \* | Max date value to allow. |
|
||||
| **`date.overrides`** \* | Pass any valid props directly to the [react-datepicker](https://github.com/Hacker0x01/react-datepicker/blob/master/docs/datepicker.md) |
|
||||
| **`date.timeIntervals`** \* | Time intervals to display. Defaults to 30 minutes. |
|
||||
| **`date.timeFormat`** \* | Determines time format. Defaults to `'h:mm aa'`. |
|
||||
| Property | Description |
|
||||
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`placeholder`** | Placeholder text for the field. |
|
||||
| **`date`** | Pass options to customize date field appearance. |
|
||||
| **`date.displayFormat`** | Format date to be shown in field **cell**. |
|
||||
| **`date.pickerAppearance`** \* | Determines the appearance of the datepicker: `dayAndTime` `timeOnly` `dayOnly` `monthOnly`. |
|
||||
| **`date.monthsToShow`** \* | Number of months to display max is 2. Defaults to 1. |
|
||||
| **`date.minDate`** \* | Min date value to allow. |
|
||||
| **`date.maxDate`** \* | Max date value to allow. |
|
||||
| **`date.minTime`** \* | Min time value to allow. |
|
||||
| **`date.maxTime`** \* | Max date value to allow. |
|
||||
| **`date.overrides`** \* | Pass any valid props directly to the [react-datepicker](https://github.com/Hacker0x01/react-datepicker/blob/master/docs/datepicker.md) |
|
||||
| **`date.timeIntervals`** \* | Time intervals to display. Defaults to 30 minutes. |
|
||||
| **`date.timeFormat`** \* | Determines time format. Defaults to `'h:mm aa'`. |
|
||||
|
||||
_\* This property is passed directly to [react-datepicker](https://github.com/Hacker0x01/react-datepicker/blob/master/docs/datepicker.md). ._
|
||||
|
||||
|
||||
@@ -17,22 +17,22 @@ keywords: email, fields, config, configuration, documentation, Content Managemen
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ label: JSON
|
||||
order: 50
|
||||
desc: The JSON field type will store any string in the Database. Learn how to use JSON fields, see examples and options.
|
||||
|
||||
keywords: json, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
keywords: json, jsonSchema, schema, validation, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
---
|
||||
|
||||
<Banner>
|
||||
@@ -23,22 +23,23 @@ This field uses the `monaco-react` editor syntax highlighting.
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build a an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`jsonSchema`** | Provide a JSON schema that will be used for validation. [JSON schemas](https://json-schema.org/learn/getting-started-step-by-step)
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -46,13 +47,13 @@ _\* An asterisk denotes that a property is required._
|
||||
|
||||
In addition to the default [field admin config](/docs/fields/overview#admin-config), you can adjust the following properties:
|
||||
|
||||
| Option | Description |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Option | Description |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`editorOptions`** | Options that can be passed to the monaco editor, [view the full list](https://microsoft.github.io/monaco-editor/typedoc/variables/editor.EditorOptions.html). |
|
||||
|
||||
### Example
|
||||
|
||||
`collections/ExampleCollection.ts
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
@@ -68,3 +69,67 @@ export const ExampleCollection: CollectionConfig = {
|
||||
],
|
||||
}
|
||||
```
|
||||
### JSON Schema Validation
|
||||
|
||||
Payload JSON fields fully support the [JSON schema](https://json-schema.org/) standard. By providing a schema in your field config, the editor will be guided in the admin UI, getting typeahead for properties and their formats automatically. When the document is saved, the default validation will prevent saving any invalid data in the field according to the schema in your config.
|
||||
|
||||
If you only provide a URL to a schema, Payload will fetch the desired schema if it is publicly available. If not, it is recommended to add the schema directly to your config or import it from another file so that it can be implemented consistently in your project.
|
||||
|
||||
|
||||
#### Local JSON Schema
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
|
||||
export const ExampleCollection: CollectionConfig = {
|
||||
slug: 'example-collection',
|
||||
fields: [
|
||||
{
|
||||
name: 'customerJSON', // required
|
||||
type: 'json', // required
|
||||
jsonSchema: {
|
||||
uri: 'a://b/foo.json', // required
|
||||
fileMatch: ['a://b/foo.json'], // required
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: {
|
||||
enum: ['bar', 'foobar'],
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
],
|
||||
}
|
||||
// {"foo": "bar"} or {"foo": "foobar"} - ok
|
||||
// Attempting to create {"foo": "not-bar"} will throw an error
|
||||
```
|
||||
|
||||
#### Remote JSON Schema
|
||||
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
|
||||
export const ExampleCollection: CollectionConfig = {
|
||||
slug: 'example-collection',
|
||||
fields: [
|
||||
{
|
||||
name: 'customerJSON', // required
|
||||
type: 'json', // required
|
||||
jsonSchema: {
|
||||
uri: 'https://example.com/customer.schema.json', // required
|
||||
fileMatch: ['https://example.com/customer.schema.json'], // required
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
// If 'https://example.com/customer.schema.json' has a JSON schema
|
||||
// {"foo": "bar"} or {"foo": "foobar"} - ok
|
||||
// Attempting to create {"foo": "not-bar"} will throw an error
|
||||
```
|
||||
|
||||
@@ -20,27 +20,27 @@ keywords: number, fields, config, configuration, documentation, Content Manageme
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`min`** | Minimum value accepted. Used in the default `validation` function. |
|
||||
| **`max`** | Maximum value accepted. Used in the default `validation` function. |
|
||||
| **`hasMany`** | Makes this field an ordered array of numbers instead of just a single number. |
|
||||
| **`minRows`** | Minimum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`min`** | Minimum value accepted. Used in the default `validation` function. |
|
||||
| **`max`** | Maximum value accepted. Used in the default `validation` function. |
|
||||
| **`hasMany`** | Makes this field an ordered array of numbers instead of just a single number. |
|
||||
| **`minRows`** | Minimum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ export const Page: CollectionConfig = {
|
||||
- [Date](/docs/fields/date) - date / time field that saves a timestamp
|
||||
- [Email](/docs/fields/email) - validates the entry is a properly formatted email
|
||||
- [Group](/docs/fields/group) - nest fields within an object
|
||||
- [JSON](/docs/fields/json) - saves actual JSON in the database
|
||||
- [Number](/docs/fields/number) - field that enforces that its value be a number
|
||||
- [Point](/docs/fields/point) - geometric coordinates for location data
|
||||
- [Radio](/docs/fields/radio) - radio button group, allowing only one value to be selected
|
||||
@@ -82,15 +83,15 @@ There are two arguments available to custom validation functions.
|
||||
|
||||
| Property | Description |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `data` | An object of the full collection or global document. |
|
||||
| `siblingData` | An object of the document data limited to fields within the same parent to the field. |
|
||||
| `operation` | Will be "create" or "update" depending on the UI action or API call. |
|
||||
| `id` | The value of the collection `id`, will be `undefined` on create request. |
|
||||
| `t` | The function for translating text, [more](/docs/configuration/i18n). |
|
||||
| `user` | The currently authenticated user object. |
|
||||
| `data` | An object containing the full collection or global document currently being edited |
|
||||
| `siblingData` | An object containing document data that is scoped to only fields within the same parent of this field |
|
||||
| `operation` | Will be `create` or `update` depending on the UI action or API call |
|
||||
| `id` | The `id` of the current document being edited. `id` is `undefined` during the `create` operation |
|
||||
| `t` | The function for translating text, [more](/docs/configuration/i18n) |
|
||||
| `user` | An object containing the currently authenticated user |
|
||||
| `payload` | If the `validate` function is being executed on the server, Payload will be exposed for easily running local operations. |
|
||||
|
||||
Example:
|
||||
### Example
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
|
||||
@@ -27,22 +27,22 @@ The data structure in the database matches the GeoJSON structure to represent po
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| Option | Description |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Used as a field label in the Admin panel and to name the generated GraphQL type. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. To support location queries, point index defaults to `2dsphere`, to disable the index set to `false`. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -20,22 +20,23 @@ keywords: radio, fields, config, configuration, documentation, Content Managemen
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `label` string and a `value` string. |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `label` string and a `value` string. |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. The default value must exist within provided values in `options`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. The default value must exist within provided values in `options`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`enumName`** | Custom enum name for this field when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined.
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ keywords: relationship, fields, config, configuration, documentation, Content Ma
|
||||
</Banner>
|
||||
|
||||
<LightDarkImage
|
||||
srcLight="https://payloadcms.com/images/docs/fields/relationship.png"
|
||||
srcDark="https://payloadcms.com/images/docs/fields/relationship-dark.png"
|
||||
alt="Shows a relationship field in the Payload admin panel"
|
||||
caption="Admin panel screenshot of a Relationship field"
|
||||
srcLight="https://payloadcms.com/images/docs/fields/relationship.png"
|
||||
srcDark="https://payloadcms.com/images/docs/fields/relationship-dark.png"
|
||||
alt="Shows a relationship field in the Payload admin panel"
|
||||
caption="Admin panel screenshot of a Relationship field"
|
||||
/>
|
||||
|
||||
**Example uses:**
|
||||
@@ -26,28 +26,28 @@ caption="Admin panel screenshot of a Relationship field"
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`relationTo`** \* | Provide one or many collection `slug`s to be able to assign relationships to. |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-relationship-options). |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxDepth`** | Sets a number limit on iterations of related documents to populate when queried. [Depth](/docs/getting-started/concepts#depth) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build a an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| Option | Description |
|
||||
|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`relationTo`** \* | Provide one or many collection `slug`s to be able to assign relationships to. |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-relationship-options). |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxDepth`** | Sets a maximum population depth for this field, regardless of the remaining depth when this field is reached. [Max Depth](/docs/getting-started/concepts#field-level-max-depth) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -131,13 +131,13 @@ The `filterOptions` property can either be a `Where` query, or a function return
|
||||
prevent all, or a `Where` query. When using a function, it will be
|
||||
called with an argument object with the following properties:
|
||||
|
||||
| Property | Description |
|
||||
|---------------|--------------------------------------------------------------------------------------|
|
||||
| `relationTo` | The `relationTo` to filter against (as defined on the field) |
|
||||
| `data` | An object of the full collection or global document currently being edited |
|
||||
| `siblingData` | An object of the document data limited to fields within the same parent to the field |
|
||||
| `id` | The value of the collection `id`, will be `undefined` on create request |
|
||||
| `user` | The currently authenticated user object |
|
||||
| Property | Description |
|
||||
| ------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `relationTo` | The collection `slug` to filter against, limited to this field's `relationTo` property |
|
||||
| `data` | An object containing the full collection or global document currently being edited |
|
||||
| `siblingData` | An object containing document data that is scoped to only fields within the same parent of this field |
|
||||
| `id` | The `id` of the current document being edited. `id` is `undefined` during the `create` operation |
|
||||
| `user` | An object containing the currently authenticated user |
|
||||
|
||||
### Example
|
||||
|
||||
@@ -287,10 +287,7 @@ To save the to `hasMany` relationship field we need to send an array of IDs:
|
||||
|
||||
```json
|
||||
{
|
||||
"owners": [
|
||||
"6031ac9e1289176380734024",
|
||||
"602c3c327b811235943ee12b"
|
||||
]
|
||||
"owners": ["6031ac9e1289176380734024", "602c3c327b811235943ee12b"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -362,5 +359,6 @@ Since we are referencing multiple collections, the field you are querying on may
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
You <strong>cannot</strong> query on a field within a polymorphic relationship as you would with a non-polymorphic relationship.
|
||||
You <strong>cannot</strong> query on a field within a polymorphic relationship as you would with a
|
||||
non-polymorphic relationship.
|
||||
</Banner>
|
||||
|
||||
@@ -18,7 +18,7 @@ keywords: rich text, fields, config, configuration, documentation, Content Manag
|
||||
caption="Admin panel screenshot of a Rich Text field"
|
||||
/>
|
||||
|
||||
Payload's rich text field is built on an "adapter pattern" which lets you specify which rich text editor you'd like to use.
|
||||
Payload's rich text field is built on an "adapter pattern" which lets you specify which rich text editor you'd like to use.
|
||||
|
||||
Right now, Payload is officially supporting two rich text editors:
|
||||
|
||||
@@ -26,7 +26,13 @@ Right now, Payload is officially supporting two rich text editors:
|
||||
2. [Lexical](/docs/rich-text/lexical) - beta, where things will be moving
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Consistent with Payload's goal of making you learn as little of Payload as possible, customizing and using the Rich Text Editor does not involve learning how to develop for a <em>Payload</em> rich text editor.</strong> Instead, you can invest your time and effort into learning the underlying open-source tools that will allow you to apply your learnings elsewhere as well.
|
||||
<strong>
|
||||
Consistent with Payload's goal of making you learn as little of Payload as possible, customizing
|
||||
and using the Rich Text Editor does not involve learning how to develop for a <em>Payload</em>{' '}
|
||||
rich text editor.
|
||||
</strong>{' '}
|
||||
Instead, you can invest your time and effort into learning the underlying open-source tools that
|
||||
will allow you to apply your learnings elsewhere as well.
|
||||
</Banner>
|
||||
|
||||
### Config
|
||||
@@ -67,4 +73,4 @@ Override the default text direction of the Admin panel for this field. Set to `t
|
||||
|
||||
### Editor-specific options
|
||||
|
||||
For a ton more editor-specific options, including how to build custom rich text elements directly into your editor, take a look at either the [Slate docs](/docs/rich-text/slate) or the [Lexical docs](/docs/rich-text/lexical) depending on which editor you're using.
|
||||
For a ton more editor-specific options, including how to build custom rich text elements directly into your editor, take a look at either the [Slate docs](/docs/rich-text/slate) or the [Lexical docs](/docs/rich-text/lexical) depending on which editor you're using.
|
||||
|
||||
@@ -20,24 +20,26 @@ keywords: select, multi-select, fields, config, configuration, documentation, Co
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing a `label` string and a `value` string. |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many selections instead of only one. |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing a `label` string and a `value` string. |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many selections instead of only one. |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`enumName`** | Custom enum name for this field when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`dbName`** | Custom table name (if `hasMany` set to `true`) for this field when using SQL database adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -122,7 +124,7 @@ export const CustomSelectField: Field = {
|
||||
],
|
||||
}),
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -174,9 +176,9 @@ export const CustomSelectComponent: React.FC<CustomSelectProps> = ({ path, optio
|
||||
If you are looking to create a dynamic select field, the following tutorial will walk you through the process of creating a custom select field that fetches its options from an external API.
|
||||
|
||||
<VideoDrawer
|
||||
id='Efn9OxSjA6Y'
|
||||
label='How to Create a Custom Select Field'
|
||||
drawerTitle='How to Create a Custom Select Field: A Step-by-Step Guide'
|
||||
id="Efn9OxSjA6Y"
|
||||
label="How to Create a Custom Select Field"
|
||||
drawerTitle="How to Create a Custom Select Field: A Step-by-Step Guide"
|
||||
/>
|
||||
|
||||
If you want to learn more about custom components check out the [Admin > Custom Component](/docs/admin/components#field-component) docs.
|
||||
|
||||
@@ -20,27 +20,28 @@ keywords: text, fields, config, configuration, documentation, Content Management
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`hasMany`** | Makes this field an ordered array of text instead of just a single text. |
|
||||
| **`minRows`** | Minimum number of texts in the array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of texts in the array, if `hasMany` is set to true. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`hasMany`** | Makes this field an ordered array of text instead of just a single text. |
|
||||
| **`minRows`** | Minimum number of texts in the array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of texts in the array, if `hasMany` is set to true. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
### Admin config
|
||||
|
||||
@@ -20,24 +20,24 @@ keywords: textarea, fields, config, configuration, documentation, Content Manage
|
||||
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| Option | Description |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/config), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide field-based hooks to control logic for this field. [More](/docs/fields/overview#field-level-hooks) |
|
||||
| **`access`** | Provide field-based access control to denote what users can see and do with this field's data. [More](/docs/fields/overview#field-level-access-control) |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-config). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@ keywords: upload, images media, fields, config, configuration, documentation, Co
|
||||
</Banner>
|
||||
|
||||
<LightDarkImage
|
||||
srcLight="https://payloadcms.com/images/docs/fields/upload.png"
|
||||
srcDark="https://payloadcms.com/images/docs/fields/upload-dark.png"
|
||||
alt="Shows an upload field in the Payload admin panel"
|
||||
caption="Admin panel screenshot of an Upload field"
|
||||
srcLight="https://payloadcms.com/images/docs/fields/upload.png"
|
||||
srcDark="https://payloadcms.com/images/docs/fields/upload-dark.png"
|
||||
alt="Shows an upload field in the Payload admin panel"
|
||||
caption="Admin panel screenshot of an Upload field"
|
||||
/>
|
||||
|
||||
**Example uses:**
|
||||
@@ -35,7 +35,7 @@ caption="Admin panel screenshot of an Upload field"
|
||||
### Config
|
||||
|
||||
| Option | Description |
|
||||
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`*relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. <strong>Note: the related collection must be configured to support Uploads.</strong> |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-upload-options). |
|
||||
@@ -85,15 +85,15 @@ The `filterOptions` property can either be a `Where` query, or a function return
|
||||
prevent all, or a `Where` query. When using a function, it will be
|
||||
called with an argument object with the following properties:
|
||||
|
||||
| Property | Description |
|
||||
|---------------|--------------------------------------------------------------------------------------|
|
||||
| `relationTo` | The `relationTo` to filter against (as defined on the field) |
|
||||
| `data` | An object of the full collection or global document currently being edited |
|
||||
| `siblingData` | An object of the document data limited to fields within the same parent to the field |
|
||||
| `id` | The value of the collection `id`, will be `undefined` on create request |
|
||||
| `user` | The currently authenticated user object |
|
||||
| Property | Description |
|
||||
| ------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `relationTo` | The collection `slug` to filter against, limited to this field's `relationTo` property |
|
||||
| `data` | An object containing the full collection or global document currently being edited |
|
||||
| `siblingData` | An object containing document data that is scoped to only fields within the same parent of this field |
|
||||
| `id` | The `id` of the current document being edited. `id` is `undefined` during the `create` operation |
|
||||
| `user` | An object containing the currently authenticated user |
|
||||
|
||||
**Example:**
|
||||
### Example
|
||||
|
||||
```ts
|
||||
const uploadField = {
|
||||
|
||||
@@ -156,6 +156,28 @@ To populate `user.author.department` in it's entirety you could specify `?depth=
|
||||
}
|
||||
```
|
||||
|
||||
#### Field-level max depth
|
||||
|
||||
Fields like relationships or uploads can have a `maxDepth` property that limits the depth of the population for that field. Here are some examples:
|
||||
|
||||
Depth: 10
|
||||
Current depth when field is accessed: 1
|
||||
`maxDepth`: undefined
|
||||
|
||||
In this case, the field would be populated to 9 levels of population.
|
||||
|
||||
Depth: 10
|
||||
Current depth when field is accessed: 0
|
||||
`maxDepth`: 2
|
||||
|
||||
In this case, the field would be populated to 2 levels of population, despite there being a remaining depth of 8.
|
||||
|
||||
Depth: 10
|
||||
Current depth when field is accessed: 2
|
||||
`maxDepth`: 1
|
||||
|
||||
In this case, the field would not be populated, as the current depth (2) has exceeded the `maxDepth` for this field (1).
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
|
||||
@@ -11,7 +11,7 @@ keywords: documentation, getting started, guide, Content Management System, cms,
|
||||
Payload requires the following software:
|
||||
|
||||
- Any JavaScript package manager (Yarn, NPM, or pnpm)
|
||||
- Node.js version 16+
|
||||
- Node.js version 18+
|
||||
- Any [compatible database](/docs/database/overview) (MongoDB or Postgres)
|
||||
|
||||
<Banner type="warning">
|
||||
@@ -62,9 +62,7 @@ import express from 'express'
|
||||
const app = express()
|
||||
|
||||
app.listen(3000, async () => {
|
||||
console.log(
|
||||
"Express is now listening for incoming connections on port 3000."
|
||||
)
|
||||
console.log('Express is now listening for incoming connections on port 3000.')
|
||||
})
|
||||
```
|
||||
|
||||
@@ -86,9 +84,7 @@ const start = async () => {
|
||||
})
|
||||
|
||||
app.listen(3000, async () => {
|
||||
console.log(
|
||||
"Express is now listening for incoming connections on port 3000."
|
||||
)
|
||||
console.log('Express is now listening for incoming connections on port 3000.')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -105,6 +101,7 @@ PAYLOAD_SECRET=your-payload-secret
|
||||
Here is a list of all properties available to pass through `payload.init`:
|
||||
|
||||
##### secret
|
||||
|
||||
**Required**. This is a secure string that will be used to authenticate with Payload. It can be random but should be at least 14 characters and be very difficult to guess.
|
||||
|
||||
Payload uses this secret key to generate secure user tokens (JWT). Behind the scenes, we do not use your secret key to encrypt directly - instead, we first take the secret key and create an encrypted string using the SHA-256 hash function. Then, we reduce the encrypted string to its first 32 characters. This final value is what Payload uses for encryption.
|
||||
@@ -126,6 +123,7 @@ A boolean that disables the database connection when Payload starts up.
|
||||
An object used to configure SMTP. [Read more](/docs/email/overview).
|
||||
|
||||
##### express
|
||||
|
||||
This is your Express app as shown above. Payload will tie into your existing `app` and scope all of its functionalities to sub-routers. By default, Payload will add an `/admin` router and an `/api` router, but you can customize these paths.
|
||||
|
||||
##### local
|
||||
|
||||
@@ -17,7 +17,8 @@ development process, but importantly, stay out of your way as your apps get more
|
||||
<Banner type="success">
|
||||
<strong>Payload 2.0 has been released!</strong>
|
||||
<br />
|
||||
Includes Postgres support, Live Preview, Lexical Editor, and more. <a href="/blog/payload-2-0">Read the announcement</a>.
|
||||
Includes Postgres support, Live Preview, Lexical Editor, and more.{' '}
|
||||
<a href="/blog/payload-2-0">Read the announcement</a>.
|
||||
</Banner>
|
||||
|
||||
Out of the box, Payload gives you a lot of the things that you often need when developing a new website, web app, or native app:
|
||||
|
||||
@@ -16,19 +16,6 @@ Run the following command in a Payload project to generate your project's GraphQ
|
||||
payload generate:graphQLSchema
|
||||
```
|
||||
|
||||
You can run this command whenever you need to regenerate your GraphQL schema and output it to a file, and then you can use the schema for writing your own GraphQL elsewhere in other projects.
|
||||
|
||||
### Custom output file path
|
||||
|
||||
```js
|
||||
{
|
||||
// the remainder of your config
|
||||
graphQL: {
|
||||
schemaOutputFile: path.resolve(__dirname, './graphql/schema.graphql'),
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Field Schemas
|
||||
|
||||
For `array`, `block`, `group` and named `tab` fields, you can generate top level reusable interfaces. The following group field config:
|
||||
|
||||
@@ -16,14 +16,13 @@ The labels you provide for your Collections and Globals are used to name the Gra
|
||||
|
||||
At the top of your Payload config you can define all the options to manage GraphQL.
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `mutations` | Any custom Mutations to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
|
||||
| `queries` | Any custom Queries to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
|
||||
| `maxComplexity` | A number used to set the maximum allowed complexity allowed by requests [More](/docs/graphql/overview#query-complexity-limits) |
|
||||
| `disablePlaygroundInProduction` | A boolean that if false will enable the GraphQL playground, defaults to true. [More](/docs/graphql/overview#graphql-playground) |
|
||||
| `disable` | A boolean that if true will disable the GraphQL entirely, defaults to false. |
|
||||
| `schemaOutputFile` | A string for the file path used by the generate schema command. Defaults to `graphql.schema` next to `payload.config.ts` [More](/docs/graphql/graphql-schema) |
|
||||
| Option | Description |
|
||||
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `mutations` | Any custom Mutations to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
|
||||
| `queries` | Any custom Queries to be added in addition to what Payload provides. [More](/docs/graphql/extending) |
|
||||
| `maxComplexity` | A number used to set the maximum allowed complexity allowed by requests [More](/docs/graphql/overview#query-complexity-limits) |
|
||||
| `disablePlaygroundInProduction` | A boolean that if false will enable the GraphQL playground, defaults to true. [More](/docs/graphql/overview#graphql-playground) |
|
||||
| `disable` | A boolean that if true will disable the GraphQL entirely, defaults to false. |
|
||||
|
||||
## Collections
|
||||
|
||||
@@ -43,11 +42,12 @@ export const PublicUser: CollectionConfig = {
|
||||
|
||||
**Payload will automatically open up the following queries:**
|
||||
|
||||
| Query Name | Operation |
|
||||
| ------------------ | ------------------- |
|
||||
| **`PublicUser`** | `findByID` |
|
||||
| **`PublicUsers`** | `find` |
|
||||
| **`mePublicUser`** | `me` auth operation |
|
||||
| Query Name | Operation |
|
||||
| ------------------ | ------------------- |
|
||||
| **`PublicUser`** | `findByID` |
|
||||
| **`PublicUsers`** | `find` |
|
||||
| **`countPublicUsers`** | `count` |
|
||||
| **`mePublicUser`** | `me` auth operation |
|
||||
|
||||
**And the following mutations:**
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ import { CollectionBeforeOperationHook } from 'payload/types'
|
||||
const beforeOperationHook: CollectionBeforeOperationHook = async ({
|
||||
args, // original arguments passed into the operation
|
||||
operation, // name of the operation
|
||||
req, // full express request
|
||||
}) => {
|
||||
return args // return modified operation arguments as necessary
|
||||
}
|
||||
@@ -209,6 +210,7 @@ import { CollectionAfterOperationHook } from 'payload/types'
|
||||
const afterOperationHook: CollectionAfterOperationHook = async ({
|
||||
args, // arguments passed into the operation
|
||||
operation, // name of the operation
|
||||
req, // full express request
|
||||
result, // the result of the operation, before modifications
|
||||
}) => {
|
||||
return result // return modified result as necessary
|
||||
@@ -290,13 +292,11 @@ For auth-enabled Collections, this hook runs after successful `forgotPassword` o
|
||||
```ts
|
||||
import { CollectionAfterForgotPasswordHook } from 'payload/types'
|
||||
|
||||
const afterLoginHook: CollectionAfterForgotPasswordHook = async ({
|
||||
req, // full express request
|
||||
user, // user being logged in
|
||||
token, // user token
|
||||
}) => {
|
||||
return user
|
||||
}
|
||||
const afterForgotPasswordHook: CollectionAfterForgotPasswordHook = async ({
|
||||
args, // arguments passed into the operation
|
||||
context,
|
||||
collection, // The collection which this hook is being run on
|
||||
}) => {...}
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
|
||||
@@ -6,7 +6,8 @@ desc: Hooks can be added to any fields, and optionally modify the return value o
|
||||
keywords: hooks, fields, config, configuration, documentation, Content Management System, cms, headless, javascript, node, react, express
|
||||
---
|
||||
|
||||
Field-level hooks offer incredible potential for encapsulating your logic. They help to isolate concerns and package up functionalities to be easily reusable across your projects.
|
||||
Field-level hooks offer incredible potential for encapsulating your logic. They help to isolate concerns and package up
|
||||
functionalities to be easily reusable across your projects.
|
||||
|
||||
**Example use cases include:**
|
||||
|
||||
@@ -20,6 +21,7 @@ Field-level hooks offer incredible potential for encapsulating your logic. They
|
||||
|
||||
- [beforeValidate](#beforevalidate)
|
||||
- [beforeChange](#beforechange)
|
||||
- beforeDuplicate(#beforeduplicate)
|
||||
- [afterChange](#afterchange)
|
||||
- [afterRead](#afterread)
|
||||
|
||||
@@ -37,6 +39,7 @@ const ExampleField: Field = {
|
||||
hooks: {
|
||||
beforeValidate: [(args) => {...}],
|
||||
beforeChange: [(args) => {...}],
|
||||
beforeDuplicate: [(args) => {...}],
|
||||
afterChange: [(args) => {...}],
|
||||
afterRead: [(args) => {...}],
|
||||
}
|
||||
@@ -46,7 +49,8 @@ const ExampleField: Field = {
|
||||
|
||||
## Arguments and return values
|
||||
|
||||
All field-level hooks are formatted to accept the same arguments, although some arguments may be `undefined` based on which field hook you are utilizing.
|
||||
All field-level hooks are formatted to accept the same arguments, although some arguments may be `undefined` based on
|
||||
which field hook you are utilizing.
|
||||
|
||||
<Banner type="success">
|
||||
<strong>Tip:</strong>
|
||||
@@ -62,17 +66,17 @@ All field-level hooks are formatted to accept the same arguments, although some
|
||||
Field Hooks receive one `args` argument that contains the following properties:
|
||||
|
||||
| Option | Description |
|
||||
|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`data`** | The data passed to update the document within `create` and `update` operations, and the full document itself in the `afterRead` hook. |
|
||||
| **`siblingData`** | The sibling data passed to a field that the hook is running against. |
|
||||
| **`findMany`** | Boolean to denote if this hook is running against finding one, or finding many within the `afterRead` hook. |
|
||||
| **`operation`** | A string relating to which operation the field type is currently executing within. Useful within `beforeValidate`, `beforeChange`, and `afterChange` hooks to differentiate between `create` and `update` operations. |
|
||||
| **`originalDoc`** | The full original document in `update` operations. In the `afterChange` hook, this is the resulting document of the operation. |
|
||||
| **`previousDoc`** | The document before changes were applied, only in `afterChange` hooks. |
|
||||
| **`previousSiblingDoc`** | The sibling data from the previous document in `afterChange` hook. |
|
||||
| **`previousSiblingDoc`** | The sibling data of the document before changes being applied, only in `beforeChange` and `afterChange` hook. |
|
||||
| **`req`** | The Express `request` object. It is mocked for Local API operations. |
|
||||
| **`value`** | The value of the field. |
|
||||
| **`previousValue`** | The previous value of the field, before changes were applied, only in `afterChange` hooks. |
|
||||
| **`previousValue`** | The previous value of the field, before changes, only in `beforeChange` and `afterChange` hooks. |
|
||||
| **`context`** | Context passed to this hook. More info can be found under [Context](/docs/hooks/context) |
|
||||
| **`field`** | The field which the hook is running against. |
|
||||
| **`collection`** | The collection which the field belongs to. If the field belongs to a global, this will be null. |
|
||||
@@ -80,7 +84,8 @@ Field Hooks receive one `args` argument that contains the following properties:
|
||||
|
||||
#### Return value
|
||||
|
||||
All field hooks can optionally modify the return value of the field before the operation continues. Field Hooks may optionally return the value that should be used within the field.
|
||||
All field hooks can optionally modify the return value of the field before the operation continues. Field Hooks may
|
||||
optionally return the value that should be used within the field.
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Important</strong>
|
||||
@@ -92,11 +97,14 @@ All field hooks can optionally modify the return value of the field before the o
|
||||
|
||||
## Examples of Field Hooks
|
||||
|
||||
To better illustrate how field-level hooks can be applied, here are some specific examples. These demonstrate the flexibility and potential of field hooks in different contexts. Remember, these examples are just a starting point - the true potential of field-level hooks lies in their adaptability to a wide array of use cases.
|
||||
To better illustrate how field-level hooks can be applied, here are some specific examples. These demonstrate the
|
||||
flexibility and potential of field hooks in different contexts. Remember, these examples are just a starting point - the
|
||||
true potential of field-level hooks lies in their adaptability to a wide array of use cases.
|
||||
|
||||
### beforeValidate
|
||||
|
||||
Runs before the `update` operation. This hook allows you to pre-process or format field data before it undergoes validation.
|
||||
Runs before the `update` operation. This hook allows you to pre-process or format field data before it undergoes
|
||||
validation.
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
@@ -105,19 +113,25 @@ const usernameField: Field = {
|
||||
name: 'username',
|
||||
type: 'text',
|
||||
hooks: {
|
||||
beforeValidate: [({ value }) => {
|
||||
// Trim whitespace and convert to lowercase
|
||||
return value.trim().toLowerCase()
|
||||
}],
|
||||
}
|
||||
beforeValidate: [
|
||||
({ value }) => {
|
||||
// Trim whitespace and convert to lowercase
|
||||
return value.trim().toLowerCase()
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the `beforeValidate` hook is used to process the `username` field. The hook takes the incoming value of the field and transforms it by trimming whitespace and converting it to lowercase. This ensures that the username is stored in a consistent format in the database.
|
||||
In this example, the `beforeValidate` hook is used to process the `username` field. The hook takes the incoming value of
|
||||
the field and transforms it by trimming whitespace and converting it to lowercase. This ensures that the username is
|
||||
stored in a consistent format in the database.
|
||||
|
||||
### beforeChange
|
||||
|
||||
Immediately following validation, `beforeChange` hooks will run within `create` and `update` operations. At this stage, you can be confident that the field data that will be saved to the document is valid in accordance to your field validations.
|
||||
Immediately following validation, `beforeChange` hooks will run within `create` and `update` operations. At this stage,
|
||||
you can be confident that the field data that will be saved to the document is valid in accordance to your field
|
||||
validations.
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
@@ -126,21 +140,26 @@ const emailField: Field = {
|
||||
name: 'email',
|
||||
type: 'email',
|
||||
hooks: {
|
||||
beforeChange: [({ value, operation }) => {
|
||||
if (operation === 'create') {
|
||||
// Perform additional validation or transformation for 'create' operation
|
||||
}
|
||||
return value
|
||||
}],
|
||||
}
|
||||
beforeChange: [
|
||||
({ value, operation }) => {
|
||||
if (operation === 'create') {
|
||||
// Perform additional validation or transformation for 'create' operation
|
||||
}
|
||||
return value
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
In the `emailField`, the `beforeChange` hook checks the `operation` type. If the operation is `create`, it performs additional validation or transformation on the email field value. This allows for operation-specific logic to be applied to the field.
|
||||
In the `emailField`, the `beforeChange` hook checks the `operation` type. If the operation is `create`, it performs
|
||||
additional validation or transformation on the email field value. This allows for operation-specific logic to be applied
|
||||
to the field.
|
||||
|
||||
### afterChange
|
||||
|
||||
The `afterChange` hook is executed after a field's value has been changed and saved in the database. This hook is useful for post-processing or triggering side effects based on the new value of the field.
|
||||
The `afterChange` hook is executed after a field's value has been changed and saved in the database. This hook is useful
|
||||
for post-processing or triggering side effects based on the new value of the field.
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
@@ -151,25 +170,33 @@ const membershipStatusField: Field = {
|
||||
options: [
|
||||
{ label: 'Standard', value: 'standard' },
|
||||
{ label: 'Premium', value: 'premium' },
|
||||
{ label: 'VIP', value: 'vip' }
|
||||
{ label: 'VIP', value: 'vip' },
|
||||
],
|
||||
hooks: {
|
||||
afterChange: [({ value, previousValue, req }) => {
|
||||
if (value !== previousValue) {
|
||||
// Log or perform an action when the membership status changes
|
||||
console.log(`User ID ${req.user.id} changed their membership status from ${previousValue} to ${value}.`)
|
||||
// Here, you can implement actions that could track conversions from one tier to another
|
||||
}
|
||||
}],
|
||||
}
|
||||
afterChange: [
|
||||
({ value, previousValue, req }) => {
|
||||
if (value !== previousValue) {
|
||||
// Log or perform an action when the membership status changes
|
||||
console.log(
|
||||
`User ID ${req.user.id} changed their membership status from ${previousValue} to ${value}.`,
|
||||
)
|
||||
// Here, you can implement actions that could track conversions from one tier to another
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the `afterChange` hook is used with a `membershipStatusField`, which allows users to select their membership level (Standard, Premium, VIP). The hook monitors changes in the membership status. When a change occurs, it logs the update and can be used to trigger further actions, such as tracking conversion from one tier to another or notifying them about changes in their membership benefits.
|
||||
In this example, the `afterChange` hook is used with a `membershipStatusField`, which allows users to select their
|
||||
membership level (Standard, Premium, VIP). The hook monitors changes in the membership status. When a change occurs, it
|
||||
logs the update and can be used to trigger further actions, such as tracking conversion from one tier to another or
|
||||
notifying them about changes in their membership benefits.
|
||||
|
||||
### afterRead
|
||||
|
||||
The `afterRead` hook is invoked after a field value is read from the database. This is ideal for formatting or transforming the field data for output.
|
||||
The `afterRead` hook is invoked after a field value is read from the database. This is ideal for formatting or
|
||||
transforming the field data for output.
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
@@ -178,17 +205,45 @@ const dateField: Field = {
|
||||
name: 'createdAt',
|
||||
type: 'date',
|
||||
hooks: {
|
||||
afterRead: [({ value }) => {
|
||||
// Format date for display
|
||||
return new Date(value).toLocaleDateString()
|
||||
afterRead: [
|
||||
({ value }) => {
|
||||
// Format date for display
|
||||
return new Date(value).toLocaleDateString()
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `afterRead` hook for the `dateField` is used to format the date into a more readable format
|
||||
using `toLocaleDateString()`. This hook modifies the way the date is presented to the user, making it more
|
||||
user-friendly.
|
||||
|
||||
### beforeDuplicate
|
||||
|
||||
The `beforeDuplicate` field hook is called on each locale (when using localization), when duplicating a document. It may be used when documents having the
|
||||
exact same properties may cause issue. This gives you a way to avoid duplicate names on `unique`, `required` fields or when external systems expect non-repeating values on documents.
|
||||
|
||||
This hook gets called after `beforeChange` hooks are called and before the document is saved to the database.
|
||||
|
||||
By Default, unique and required text fields Payload will append "- Copy" to the original document value. The default is not added if your field has its own, you must return non-unique values from your beforeDuplicate hook to avoid errors or enable the `disableDuplicate` option on the collection.
|
||||
Here is an example of a number field with a hook that increments the number to avoid unique constraint errors when duplicating a document:
|
||||
|
||||
```ts
|
||||
import { Field } from 'payload/types'
|
||||
|
||||
const numberField: Field = {
|
||||
name: 'number',
|
||||
type: 'number',
|
||||
hooks: {
|
||||
// increment existing value by 1
|
||||
beforeDuplicate: [({ value }) => {
|
||||
return (value ?? 0) + 1
|
||||
}],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `afterRead` hook for the `dateField` is used to format the date into a more readable format using `toLocaleDateString()`. This hook modifies the way the date is presented to the user, making it more user-friendly.
|
||||
|
||||
|
||||
## TypeScript
|
||||
|
||||
Payload exports a type for field hooks which can be accessed and used as follows:
|
||||
|
||||
@@ -36,7 +36,7 @@ If your Hook simply performs a side-effect, such as updating a CRM, it might be
|
||||
|
||||
#### Server-only execution
|
||||
|
||||
Payload Hooks do not have any effect within the Payload Admin panel. You can safely [remove your hooks](/docs/admin/webpack#aliasing-server-only-modules) from your Admin panel's code by customizing the Webpack config, which not only keeps your Admin bundles' filesize small but also ensures that any server-side only code does not cause problems within browser environments.
|
||||
Payload Hooks are only triggered on the server. You can safely [remove your hooks](/docs/admin/webpack#aliasing-server-only-modules) from your Admin panel's client-side code by customizing the Webpack config, which not only keeps your Admin bundles' filesize small but also ensures that any server-side only code does not cause problems within browser environments.
|
||||
|
||||
## Hook Types
|
||||
|
||||
|
||||
@@ -8,28 +8,36 @@ keywords: live preview, frontend, react, next.js, vue, nuxt.js, svelte, hook, us
|
||||
|
||||
While using Live Preview, the Admin panel emits a new `window.postMessage` event every time a change is made to the document. Your front-end application can listen for these events and re-render accordingly.
|
||||
|
||||
Wiring your front-end into Live Preview is easy. If your front-end application is built with React or Next.js, use the [`useLivePreview`](#react) React hook that Payload provides. In the future, all other major frameworks like Vue, Svelte, etc will be officially supported. If you are using any of these frameworks today, you can still integrate with Live Preview yourself using the underlying tooling that Payload provides. See [building your own hook](#building-your-own-hook) for more information.
|
||||
Wiring your front-end into Live Preview is easy. If your front-end application is built with React, Next.js, Vue or Nuxt.js, use the `useLivePreview` hook that Payload provides. In the future, all other major frameworks like Svelte will be officially supported. If you are using any of these frameworks today, you can still integrate with Live Preview yourself using the underlying tooling that Payload provides. See [building your own hook](#building-your-own-hook) for more information.
|
||||
|
||||
By default, all hooks accept the following args:
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`serverURL`** \* | The URL of your Payload server. |
|
||||
| **`initialData`** | The initial data of the document. The live data will be merged in as changes are made. |
|
||||
| **`depth`** | The depth of the relationships to fetch. Defaults to `0`. |
|
||||
| **`apiRoute`** | The path of your API route as defined in `routes.api`. Defaults to `/api`. |
|
||||
| Path | Description |
|
||||
| ------------------ | -------------------------------------------------------------------------------------- |
|
||||
| **`serverURL`** \* | The URL of your Payload server. |
|
||||
| **`initialData`** | The initial data of the document. The live data will be merged in as changes are made. |
|
||||
| **`depth`** | The depth of the relationships to fetch. Defaults to `0`. |
|
||||
| **`apiRoute`** | The path of your API route as defined in `routes.api`. Defaults to `/api`. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
And return the following values:
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`data`** | The live data of the document, merged with the initial data. |
|
||||
| **`isLoading`** | A boolean that indicates whether or not the document is loading. |
|
||||
| Path | Description |
|
||||
| --------------- | ---------------------------------------------------------------- |
|
||||
| **`data`** | The live data of the document, merged with the initial data. |
|
||||
| **`isLoading`** | A boolean that indicates whether or not the document is loading. |
|
||||
|
||||
<Banner type="info">
|
||||
If your front-end is tightly coupled to required fields, you should ensure that your UI does not break when these fields are removed. For example, if you are rendering something like `data.relatedPosts[0].title`, your page will break once you remove the first related post. To get around this, use conditional logic, optional chaining, or default values in your UI where needed. For example, `data?.relatedPosts?.[0]?.title`.
|
||||
If your front-end is tightly coupled to required fields, you should ensure that your UI does not
|
||||
break when these fields are removed. For example, if you are rendering something like
|
||||
`data.relatedPosts[0].title`, your page will break once you remove the first related post. To get
|
||||
around this, use conditional logic, optional chaining, or default values in your UI where needed.
|
||||
For example, `data?.relatedPosts?.[0]?.title`.
|
||||
</Banner>
|
||||
|
||||
<Banner type="info">
|
||||
It is important that the `depth` argument matches exactly with the depth of your initial page request. The depth property is used to populated relationships and uploads beyond their IDs. See [Depth](../getting-started/concepts#depth) for more information.
|
||||
</Banner>
|
||||
|
||||
### React
|
||||
@@ -45,8 +53,8 @@ npm install @payloadcms/live-preview-react
|
||||
Then, use the `useLivePreview` hook in your React component:
|
||||
|
||||
```tsx
|
||||
'use client';
|
||||
import { useLivePreview } from '@payloadcms/live-preview-react';
|
||||
'use client'
|
||||
import { useLivePreview } from '@payloadcms/live-preview-react'
|
||||
import { Page as PageType } from '@/payload-types'
|
||||
|
||||
// Fetch the page in a server component, pass it to the client component, then thread it through the hook
|
||||
@@ -63,15 +71,44 @@ export const PageClient: React.FC<{
|
||||
depth: 2,
|
||||
})
|
||||
|
||||
return (
|
||||
<h1>{data.title}</h1>
|
||||
)
|
||||
return <h1>{data.title}</h1>
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="info">
|
||||
If is important that the `depth` argument matches exactly with the depth of your initial page request. The depth property is used to populated relationships and uploads beyond their IDs. See [Depth](../getting-started/concepts#depth) for more information.
|
||||
</Banner>
|
||||
### Vue
|
||||
|
||||
If your front-end application is built with Vue 3 or Nuxt 3, you can use the `useLivePreview` composable that Payload provides.
|
||||
|
||||
First, install the `@payloadcms/live-preview-vue` package:
|
||||
|
||||
```bash
|
||||
npm install @payloadcms/live-preview-vue
|
||||
```
|
||||
|
||||
Then, use the `useLivePreview` hook in your Vue component:
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import type { PageData } from '~/types';
|
||||
import { defineProps } from 'vue';
|
||||
import { useLivePreview } from '@payloadcms/live-preview-vue';
|
||||
|
||||
// Fetch the initial data on the parent component or using async state
|
||||
const props = defineProps<{ initialData: PageData }>();
|
||||
|
||||
// The hook will take over from here and keep the preview in sync with the changes you make.
|
||||
// The `data` property will contain the live data of the document only when viewed from the Preview view of the Admin UI.
|
||||
const { data } = useLivePreview<PageData>({
|
||||
initialData: props.initialData,
|
||||
serverURL: "<PAYLOAD_SERVER_URL>",
|
||||
depth: 2,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ data.title }}</h1>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Building your own hook
|
||||
|
||||
@@ -85,25 +122,25 @@ npm install @payloadcms/live-preview
|
||||
|
||||
This package provides the following functions:
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`subscribe`** | Subscribes to the Admin panel's `window.postMessage` events and calls the provided callback function. |
|
||||
| **`unsubscribe`** | Unsubscribes from the Admin panel's `window.postMessage` events. |
|
||||
| **`ready`** | Sends a `window.postMessage` event to the Admin panel to indicate that the front-end is ready to receive messages. |
|
||||
| Path | Description |
|
||||
| ----------------- | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`subscribe`** | Subscribes to the Admin panel's `window.postMessage` events and calls the provided callback function. |
|
||||
| **`unsubscribe`** | Unsubscribes from the Admin panel's `window.postMessage` events. |
|
||||
| **`ready`** | Sends a `window.postMessage` event to the Admin panel to indicate that the front-end is ready to receive messages. |
|
||||
|
||||
The `subscribe` function takes the following args:
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`callback`** \* | A callback function that is called with `data` every time a change is made to the document. |
|
||||
| **`serverURL`** \* | The URL of your Payload server. |
|
||||
| **`initialData`** | The initial data of the document. The live data will be merged in as changes are made. |
|
||||
| **`depth`** | The depth of the relationships to fetch. Defaults to `0`. |
|
||||
| Path | Description |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------- |
|
||||
| **`callback`** \* | A callback function that is called with `data` every time a change is made to the document. |
|
||||
| **`serverURL`** \* | The URL of your Payload server. |
|
||||
| **`initialData`** | The initial data of the document. The live data will be merged in as changes are made. |
|
||||
| **`depth`** | The depth of the relationships to fetch. Defaults to `0`. |
|
||||
|
||||
With these functions, you can build your own hook using your front-end framework of choice:
|
||||
|
||||
```tsx
|
||||
import { subscribe, unsubscribe } from '@payloadcms/live-preview';
|
||||
import { subscribe, unsubscribe } from '@payloadcms/live-preview'
|
||||
|
||||
// To build your own hook, subscribe to Live Preview events using the`subscribe` function
|
||||
// It handles everything from:
|
||||
@@ -159,7 +196,7 @@ export const useLivePreview = <T extends any>(props: {
|
||||
hasSentReadyMessage.current = true
|
||||
|
||||
ready({
|
||||
serverURL
|
||||
serverURL,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -177,7 +214,8 @@ export const useLivePreview = <T extends any>(props: {
|
||||
```
|
||||
|
||||
<Banner type="info">
|
||||
When building your own hook, ensure that the args and return values are consistent with the ones listed at the top of this document. This will ensure that all hooks follow the same API.
|
||||
When building your own hook, ensure that the args and return values are consistent with the ones
|
||||
listed at the top of this document. This will ensure that all hooks follow the same API.
|
||||
</Banner>
|
||||
|
||||
## Example
|
||||
@@ -226,8 +264,8 @@ const { docs } = await payload.find({
|
||||
where: {
|
||||
slug: {
|
||||
equals: 'home',
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -13,19 +13,23 @@ Live Preview works by rendering an iframe on the page that loads your front-end
|
||||
{/* IMAGE OF LIVE PREVIEW HERE */}
|
||||
|
||||
<Banner type="warning">
|
||||
Live Preview is currently in beta. You may use this feature in production, but please be aware that it is subject to change and may not be fully stable for all use cases. If you encounter any issues, please [report them](https://github.com/payloadcms/payload/issues/new?assignees=jacobsfletch&labels=possible-bug&projects=&title=Live%20Preview&template=1.bug_report.yml) with as much detail as possible.
|
||||
Live Preview is currently in beta. You may use this feature in production, but please be aware
|
||||
that it is subject to change and may not be fully stable for all use cases. If you encounter any
|
||||
issues, please [report
|
||||
them](https://github.com/payloadcms/payload/issues/new?assignees=jacobsfletch&labels=possible-bug&projects=&title=Live%20Preview&template=1.bug_report.yml)
|
||||
with as much detail as possible.
|
||||
</Banner>
|
||||
|
||||
## Setup
|
||||
|
||||
Setting up Live Preview is easy. You first need to enable it through the `admin.livePreview` property of your Payload config. It takes the following options:
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`url`** \* | String, or function that returns a string, pointing to your front-end application. This value is used as the iframe `src`. [More details](#url). |
|
||||
| **`breakpoints`** | Array of breakpoints to be used as “device sizes” in the preview window. Each item appears as an option in the toolbar. [More details](#breakpoints). |
|
||||
| **`collections`** | Array of collection slugs to enable Live Preview on. |
|
||||
| **`globals`** | Array of global slugs to enable Live Preview on. |
|
||||
| Path | Description |
|
||||
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`url`** \* | String, or function that returns a string, pointing to your front-end application. This value is used as the iframe `src`. [More details](#url). |
|
||||
| **`breakpoints`** | Array of breakpoints to be used as “device sizes” in the preview window. Each item appears as an option in the toolbar. [More details](#breakpoints). |
|
||||
| **`collections`** | Array of collection slugs to enable Live Preview on. |
|
||||
| **`globals`** | Array of global slugs to enable Live Preview on. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -68,11 +72,11 @@ The `url` property is a string that points to your front-end application. This v
|
||||
|
||||
You can also pass a function in order to dynamically format URLs. This function is called with the following arguments:
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`data`** | The data of the document being edited. This includes changes that have not yet been saved. |
|
||||
| **`documentInfo`** | Information about the document being edited like collection slug. [More details](../admin/hooks#usedocumentinfo). |
|
||||
| **`locale`** | The locale currently being edited (if applicable). [More details](../configuration/localization). |
|
||||
| Path | Description |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------- |
|
||||
| **`data`** | The data of the document being edited. This includes changes that have not yet been saved. |
|
||||
| **`documentInfo`** | Information about the document being edited like collection slug. [More details](../admin/hooks#usedocumentinfo). |
|
||||
| **`locale`** | The locale currently being edited (if applicable). [More details](../configuration/localization). |
|
||||
|
||||
Here is an example of using a function that returns a dynamic URL:
|
||||
|
||||
@@ -100,12 +104,12 @@ Here is an example of using a function that returns a dynamic URL:
|
||||
|
||||
The breakpoints property is an array of objects which are used as “device sizes” in the preview window. Each item will render as an option in the toolbar. When selected, the preview window will resize to the exact dimensions specified in that breakpoint. Each breakpoint takes the following properties:
|
||||
|
||||
| Path | Description |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`label`** \* | The label to display in the drop-down. This is what the user will see. |
|
||||
| **`name`** \* | The name of the breakpoint. |
|
||||
| **`width`** \* | The width of the breakpoint. This is used to set the width of the iframe. |
|
||||
| **`height`** \* | The height of the breakpoint. This is used to set the height of the iframe. |
|
||||
| Path | Description |
|
||||
| --------------- | --------------------------------------------------------------------------- |
|
||||
| **`label`** \* | The label to display in the drop-down. This is what the user will see. |
|
||||
| **`name`** \* | The name of the breakpoint. |
|
||||
| **`width`** \* | The width of the breakpoint. This is used to set the width of the iframe. |
|
||||
| **`height`** \* | The height of the breakpoint. This is used to set the height of the iframe. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ You can specify more options within the Local API vs. REST or GraphQL due to the
|
||||
executed in.
|
||||
|
||||
| Local Option | Description |
|
||||
|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `collection` | Required for Collection operations. Specifies the Collection slug to operate against. |
|
||||
| `data` | The data to use within the operation. Required for `create`, `update`. |
|
||||
| `depth` | [Control auto-population](/docs/getting-started/concepts#depth) of nested relationship and upload fields. |
|
||||
@@ -164,6 +164,22 @@ const result = await payload.findByID({
|
||||
})
|
||||
```
|
||||
|
||||
#### Count
|
||||
|
||||
```js
|
||||
// Result will be an object with:
|
||||
// {
|
||||
// totalDocs: 10, // count of the documents satisfies query
|
||||
// }
|
||||
const result = await payload.count({
|
||||
collection: 'posts', // required
|
||||
locale: 'en',
|
||||
where: {}, // pass a `where` query here
|
||||
user: dummyUser,
|
||||
overrideAccess: false,
|
||||
})
|
||||
```
|
||||
|
||||
#### Update by ID
|
||||
|
||||
```js
|
||||
|
||||
@@ -9,14 +9,16 @@ keywords: plugins, template, config, configuration, extensions, custom, document
|
||||
Building your own plugin is easy, and if you're already familiar with Payload then you'll have everything you need to get started. You can either start from scratch or use the Payload plugin template to get up and running quickly.
|
||||
|
||||
<Banner type="success">
|
||||
To use the template, run `npx create-payload-app@latest -t plugin -n my-new-plugin` directly in your terminal or [clone the template directly from GitHub](https://github.com/payloadcms/payload-plugin-template).
|
||||
To use the template, run `npx create-payload-app@latest -t plugin -n my-new-plugin` directly in
|
||||
your terminal or [clone the template directly from
|
||||
GitHub](https://github.com/payloadcms/payload-plugin-template).
|
||||
</Banner>
|
||||
|
||||
Our plugin template includes everything you need to build a full life-cycle plugin:
|
||||
|
||||
* Example files and functions for extending the payload config
|
||||
* A local dev environment to develop the plugin
|
||||
* Test suite with integrated GitHub workflow
|
||||
- Example files and functions for extending the payload config
|
||||
- A local dev environment to develop the plugin
|
||||
- Test suite with integrated GitHub workflow
|
||||
|
||||
By abstracting your code into a plugin, you'll be able to reuse your feature across multiple projects and make it available for other developers to use.
|
||||
|
||||
@@ -24,7 +26,6 @@ By abstracting your code into a plugin, you'll be able to reuse your featur
|
||||
|
||||
Here is a brief recap of how to integrate plugins with Payload, to learn more head back to the [plugin overview page](https://payloadcms.com/docs/plugins/overview).
|
||||
|
||||
|
||||
#### How to install a plugin
|
||||
|
||||
To install any plugin, simply add it to your Payload config in the plugins array.
|
||||
@@ -44,7 +45,6 @@ const config = buildConfig({
|
||||
export default config;
|
||||
```
|
||||
|
||||
|
||||
#### Initialization
|
||||
|
||||
The initialization process goes in the following order:
|
||||
@@ -55,7 +55,6 @@ The initialization process goes in the following order:
|
||||
4. Sanitization cleans and validates data
|
||||
5. Final config gets initialized
|
||||
|
||||
|
||||
### Plugin Template
|
||||
|
||||
In the [Payload plugin template](https://github.com/payloadcms/payload-plugin-template), you will see a common file structure that is used across plugins:
|
||||
@@ -64,14 +63,12 @@ In the [Payload plugin template](https://github.com/payloadcms/payload-plugin-te
|
||||
2. /src folder - everything related to the plugin
|
||||
3. /dev folder - sanitized test project for development
|
||||
|
||||
|
||||
#### Root
|
||||
|
||||
In the root folder, you will see various files related to the configuration of the plugin. We set up our environment in a similar manner in Payload core and across other projects. The only two files you need to modify are:
|
||||
|
||||
* **README**.md - This contains instructions on how to use the template. When you are ready, update this to contain instructions on how to use your Plugin.
|
||||
* **package**.json - Contains necessary scripts and dependencies. Overwrite the metadata in this file to describe your Plugin.
|
||||
|
||||
- **README**.md - This contains instructions on how to use the template. When you are ready, update this to contain instructions on how to use your Plugin.
|
||||
- **package**.json - Contains necessary scripts and dependencies. Overwrite the metadata in this file to describe your Plugin.
|
||||
|
||||
#### Dev
|
||||
|
||||
@@ -104,7 +101,6 @@ When you're ready to start development, navigate into this folder with `cd
|
||||
|
||||
And then start the project with `yarn dev` and pull up `http://localhost:3000` in your browser.
|
||||
|
||||
|
||||
### Testing
|
||||
|
||||
Another benefit of the dev folder is that you have the perfect environment established for testing.
|
||||
@@ -133,7 +129,6 @@ describe('Plugin tests', () => {
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
### Seeding data
|
||||
|
||||
For development and testing, you will likely need some data to work with. You can streamline this process by seeding and dropping your database - instead of manually entering data.
|
||||
@@ -164,17 +159,14 @@ export const seed = async (payload: Payload): Promise<void> => {
|
||||
|
||||
```
|
||||
|
||||
|
||||
#### Src
|
||||
|
||||
Now that we have our environment setup and dev project ready to go - it's time to build the plugin!
|
||||
|
||||
|
||||
**index.ts**
|
||||
|
||||
First up, the `src/index.ts` file - this is where the plugin should be imported from. It is best practice not to build the plugin directly in this file, instead we use this to export the plugin and types from their respective files.
|
||||
|
||||
|
||||
**Plugin.ts**
|
||||
|
||||
To reiterate, the essence of a payload plugin is simply to extend the Payload config - and that is exactly what we are doing in this file.
|
||||
@@ -196,7 +188,6 @@ export const samplePlugin =
|
||||
3. From here, you can extend the config however you like!
|
||||
4. Finally, return the config and you're all set.
|
||||
|
||||
|
||||
### Spread Syntax
|
||||
|
||||
[Spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) (or the spread operator) is a feature in JavaScript that uses the dot notation **(...)** to spread elements from arrays, strings, or objects into various contexts.
|
||||
@@ -244,7 +235,6 @@ If you wish to add to the `onInit`, you must include the async/await. We don&apo
|
||||
|
||||
In the template, we have stubbed out a basic `onInitExtension` file that you can use, if not needed feel free to delete it.
|
||||
|
||||
|
||||
### Webpack
|
||||
|
||||
If any of your files use server only packages such as fs, stripe, nodemailer, etc, they will need to be removed from the browser bundle. To do that, you can [alias the file imports with webpack](https://payloadcms.com/docs/admin/webpack#aliasing-server-only-modules).
|
||||
@@ -283,12 +273,21 @@ If possible, include [JSDoc comments](https://www.typescriptlang.org/docs/handbo
|
||||
In addition to the setup covered above, here are other best practices to follow:
|
||||
|
||||
##### Providing an enable / disable option:
|
||||
|
||||
For a better user experience, provide a way to disable the plugin without uninstalling it. This is especially important if your plugin adds additional webpack aliases, this will allow you to still let the webpack run to prevent errors.
|
||||
|
||||
##### Include tests in your GitHub CI workflow:
|
||||
|
||||
If you've configured tests for your package, integrate them into your workflow to run the tests each time you commit to the plugin repository. Learn more about [how to configure tests into your GitHub CI workflow.](https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs)
|
||||
|
||||
##### Publish your finished plugin to NPM:
|
||||
|
||||
The best way to share and allow others to use your plugin once it is complete is to publish an NPM package. This process is straightforward and well documented, find out more about [creating and publishing a NPM package here](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
|
||||
|
||||
##### Add payload-plugin topic tag:
|
||||
|
||||
Apply the tag **payload-plugin** to your GitHub repository. This will boost the visibility of your plugin and ensure it gets listed with [existing payload plugins](https://github.com/topics/payload-plugin).
|
||||
##### Use [Semantic Versioning](https://semver.org/) (SemVar):
|
||||
With the SemVar system you release version numbers that reflect the nature of changes (major, minor, patch). Ensure all major versions reference their Payload compatibility.
|
||||
|
||||
##### Use [Semantic Versioning](https://semver.org/) (SemVer):
|
||||
|
||||
With the SemVer system you release version numbers that reflect the nature of changes (major, minor, patch). Ensure all major versions reference their Payload compatibility.
|
||||
|
||||
@@ -15,7 +15,12 @@ All form submissions are stored directly in your database and are managed direct
|
||||
Forms can be as simple or complex as you need, from a basic contact form, to a multi-step lead generation engine, or even a donation form that processes payment. You may not need to reach for third-party services like HubSpot or Mailchimp for this, but instead use your own first-party tooling, built directly into your own application.
|
||||
|
||||
<Banner type="info">
|
||||
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-form-builder). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20form-builder&template=bug_report.md&title=plugin-form-builder%3A) with as much detail as possible.
|
||||
This plugin is completely open-source and the [source code can be found
|
||||
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-form-builder). If you need
|
||||
help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've
|
||||
found a bug, please [open a new
|
||||
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20form-builder&template=bug_report.md&title=plugin-form-builder%3A)
|
||||
with as much detail as possible.
|
||||
</Banner>
|
||||
|
||||
##### Core Features
|
||||
@@ -52,7 +57,7 @@ const config = buildConfig({
|
||||
plugins: [
|
||||
formBuilder({
|
||||
// see below for a list of available options
|
||||
})
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
@@ -79,8 +84,8 @@ formBuilder({
|
||||
checkbox: true,
|
||||
number: true,
|
||||
message: true,
|
||||
payment: false
|
||||
}
|
||||
payment: false,
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -92,7 +97,7 @@ The `redirectRelationships` property is an array of collection slugs that, when
|
||||
// payload.config.ts
|
||||
formBuilder({
|
||||
// ...
|
||||
redirectRelationships: ['pages']
|
||||
redirectRelationships: ['pages'],
|
||||
})
|
||||
```
|
||||
|
||||
@@ -110,7 +115,7 @@ formBuilder({
|
||||
...email,
|
||||
html: email.html, // transform the html in any way you'd like (maybe wrap it in an html template?)
|
||||
}))
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -123,18 +128,18 @@ Override anything on the `forms` collection by sending a [Payload Collection Con
|
||||
formBuilder({
|
||||
// ...
|
||||
formOverrides: {
|
||||
slug: "contact-forms",
|
||||
slug: 'contact-forms',
|
||||
access: {
|
||||
read: () => true,
|
||||
update: () => false,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: "custom-field",
|
||||
type: "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
name: 'custom-field',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -143,7 +148,12 @@ formBuilder({
|
||||
Override anything on the `form-submissions` collection by sending a [Payload Collection Config](https://payloadcms.com/docs/configuration/collections) to the `formSubmissionOverrides` property.
|
||||
|
||||
<Banner type="warning">
|
||||
By default, this plugin relies on [Payload access control](https://payloadcms.com/docs/access-control/collections) to restrict the `update` and `read` operations on the `form-submissions` collection. This is because _anyone_ should be able to create a form submission, even from a public-facing website, but _no one_ should be able to update a submission one it has been created, or read a submission unless they have permission. You can override this behavior or any other property as needed.
|
||||
By default, this plugin relies on [Payload access
|
||||
control](https://payloadcms.com/docs/access-control/collections) to restrict the `update` and
|
||||
`read` operations on the `form-submissions` collection. This is because _anyone_ should be able to
|
||||
create a form submission, even from a public-facing website, but _no one_ should be able to update
|
||||
a submission one it has been created, or read a submission unless they have permission. You can
|
||||
override this behavior or any other property as needed.
|
||||
</Banner>
|
||||
|
||||
```ts
|
||||
@@ -151,8 +161,8 @@ Override anything on the `form-submissions` collection by sending a [Payload Col
|
||||
formBuilder({
|
||||
// ...
|
||||
formSubmissionOverrides: {
|
||||
slug: "leads",
|
||||
}
|
||||
slug: 'leads',
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -164,7 +174,7 @@ First import the utility function. This will execute all of the price conditions
|
||||
|
||||
```ts
|
||||
// payload.config.ts
|
||||
import { getPaymentTotal } from '@payloadcms/plugin-form-builder';
|
||||
import { getPaymentTotal } from '@payloadcms/plugin-form-builder'
|
||||
```
|
||||
|
||||
Then in your plugin's config:
|
||||
@@ -175,14 +185,14 @@ formBuilder({
|
||||
// ...
|
||||
handlePayment: async ({ form, submissionData }) => {
|
||||
// first calculate the price
|
||||
const paymentField = form.fields?.find((field) => field.blockType === 'payment');
|
||||
const paymentField = form.fields?.find((field) => field.blockType === 'payment')
|
||||
const price = getPaymentTotal({
|
||||
basePrice: paymentField.basePrice,
|
||||
priceConditions: paymentField.priceConditions,
|
||||
fieldValues: submissionData,
|
||||
});
|
||||
})
|
||||
// then asynchronously process the payment here
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -192,139 +202,140 @@ Each field represents a form input. To override default settings pass either a b
|
||||
|
||||
<Banner type="info">
|
||||
<strong>Note:</strong>
|
||||
"Fields" here is in reference to the _fields to build forms with_, not to be confused with the _fields of a collection_ which are set via `formOverrides.fields`.
|
||||
"Fields" here is in reference to the _fields to build forms with_, not to be confused with the _fields
|
||||
of a collection_ which are set via `formOverrides.fields`.
|
||||
</Banner>
|
||||
|
||||
#### Text
|
||||
|
||||
Maps to a `text` input in your front-end. Used to collect a simple string.
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| Property | Type | Description |
|
||||
| -------------- | -------- | ---------------------------------------------------- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
|
||||
#### Textarea
|
||||
|
||||
Maps to a `textarea` input on your front-end. Used to collect a multi-line string.
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| Property | Type | Description |
|
||||
| -------------- | -------- | ---------------------------------------------------- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
|
||||
#### Select
|
||||
|
||||
Maps to a `select` input on your front-end. Used to display a list of options.
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| `options` | array | An array of objects with `label` and `value` properties. |
|
||||
| Property | Type | Description |
|
||||
| -------------- | -------- | -------------------------------------------------------- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| `options` | array | An array of objects with `label` and `value` properties. |
|
||||
|
||||
#### Email (field)
|
||||
|
||||
Maps to a `text` input with type `email` on your front-end. Used to collect an email address.
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| Property | Type | Description |
|
||||
| -------------- | -------- | ---------------------------------------------------- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
|
||||
#### State
|
||||
|
||||
Maps to a `select` input on your front-end. Used to collect a US state.
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| Property | Type | Description |
|
||||
| -------------- | -------- | ---------------------------------------------------- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
|
||||
#### Country
|
||||
|
||||
Maps to a `select` input on your front-end. Used to collect a country.
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| Property | Type | Description |
|
||||
| -------------- | -------- | ---------------------------------------------------- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
|
||||
#### Checkbox
|
||||
|
||||
Maps to a `checkbox` input on your front-end. Used to collect a boolean value.
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | checkbox | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| Property | Type | Description |
|
||||
| -------------- | -------- | ---------------------------------------------------- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | checkbox | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
|
||||
#### Number
|
||||
|
||||
Maps to a `number` input on your front-end. Used to collect a number.
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. || `defaultValue` | number | The default value of the field. |
|
||||
| Property | Type | Description |
|
||||
| -------------- | -------- | ---------------------------------------------------- | --- | -------------- | ------ | ------------------------------- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | string | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. | | `defaultValue` | number | The default value of the field. |
|
||||
|
||||
#### Message
|
||||
|
||||
Maps to a `RichText` component on your front-end. Used to display an arbitrary message to the user anywhere in the form.
|
||||
|
||||
| property | type | description |
|
||||
| --- | --- | --- |
|
||||
| property | type | description |
|
||||
| --------- | -------- | ----------------------------------- |
|
||||
| `message` | richText | The message to display on the form. |
|
||||
|
||||
#### Payment
|
||||
|
||||
Add this field to your form if it should collect payment. Upon submission, the `handlePayment` callback is executed with the form and submission data. You can use this to integrate with any third-party payment processing API.
|
||||
|
||||
| property | type | description |
|
||||
| --- | --- | --- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | number | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| `priceConditions` | array | An array of objects that define the price conditions. See below for more details. |
|
||||
| property | type | description |
|
||||
| ----------------- | -------- | --------------------------------------------------------------------------------- |
|
||||
| `name` | string | The name of the field. |
|
||||
| `label` | string | The label of the field. |
|
||||
| `defaultValue` | number | The default value of the field. |
|
||||
| `width` | string | The width of the field on the front-end. |
|
||||
| `required` | checkbox | Whether or not the field is required when submitted. |
|
||||
| `priceConditions` | array | An array of objects that define the price conditions. See below for more details. |
|
||||
|
||||
##### Price Conditions
|
||||
|
||||
Each of the `priceConditions` are executed by the `getPaymentTotal` utility that this plugin provides. You can call this function in your `handlePayment` callback to dynamically calculate the total price of a form upon submission based on the user's input. For example, you could create a price condition that says "if the user selects 'yes' for this checkbox, add $10 to the total price".
|
||||
|
||||
| property | type | description |
|
||||
| --- | --- | --- |
|
||||
| `fieldToUse` | relationship | The field to use to determine the price. |
|
||||
| `condition` | string | The condition to use to determine the price. |
|
||||
| `valueForOperator` | string | The value to use for the operator. |
|
||||
| `operator` | string | The operator to use to determine the price. |
|
||||
| `valueType` | string | The type of value to use to determine the price. |
|
||||
| `value` | string | The value to use to determine the price. |
|
||||
| property | type | description |
|
||||
| ------------------ | ------------ | ------------------------------------------------ |
|
||||
| `fieldToUse` | relationship | The field to use to determine the price. |
|
||||
| `condition` | string | The condition to use to determine the price. |
|
||||
| `valueForOperator` | string | The value to use for the operator. |
|
||||
| `operator` | string | The operator to use to determine the price. |
|
||||
| `valueType` | string | The type of value to use to determine the price. |
|
||||
| `value` | string | The value to use to determine the price. |
|
||||
|
||||
#### Field Overrides
|
||||
|
||||
@@ -344,11 +355,11 @@ formBuilder({
|
||||
text: {
|
||||
...fields.text,
|
||||
labels: {
|
||||
singular: "Custom Text Field",
|
||||
plural: "Custom Text Fields",
|
||||
}
|
||||
}
|
||||
}
|
||||
singular: 'Custom Text Field',
|
||||
plural: 'Custom Text Fields',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -388,6 +399,7 @@ Below are some common troubleshooting tips. To help other developers, please con
|
||||
## Screenshots
|
||||
|
||||

|
||||
|
||||
<br />
|
||||

|
||||
<br />
|
||||
|
||||
@@ -25,7 +25,12 @@ field instead of the original title. This is especially useful if you happen to
|
||||
but different parents.
|
||||
|
||||
<Banner type="info">
|
||||
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-nested-docs). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20nested-docs&template=bug_report.md&title=plugin-nested-docs%3A) with as much detail as possible.
|
||||
This plugin is completely open-source and the [source code can be found
|
||||
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-nested-docs). If you need
|
||||
help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've
|
||||
found a bug, please [open a new
|
||||
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20nested-docs&template=bug_report.md&title=plugin-nested-docs%3A)
|
||||
with as much detail as possible.
|
||||
</Banner>
|
||||
|
||||
##### Core features
|
||||
@@ -96,7 +101,7 @@ The `breadcrumbs` field is an array which dynamically populates all parent relat
|
||||
level and stores the following fields.
|
||||
|
||||
| Field | Description |
|
||||
|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `label` | The label of the breadcrumb. This field is automatically set to either the `collection.admin.useAsTitle` (if defined) or is set to the `ID` of the document. You can also dynamically define the `label` by passing a function to the options property of [`generateLabel`](#generateLabel). |
|
||||
| `url` | The URL of the breadcrumb. By default, this field is undefined. You can manually define this field by passing a property called function to the plugin options property of [`generateURL`](#generateURL). |
|
||||
|
||||
@@ -117,14 +122,14 @@ You can also pass a function to dynamically set the `label` of your breadcrumb.
|
||||
// payload.config.ts
|
||||
nestedDocs({
|
||||
//...
|
||||
generateLabel: (_, doc) => doc.title // NOTE: 'title' is a hypothetical field
|
||||
generateLabel: (_, doc) => doc.title, // NOTE: 'title' is a hypothetical field
|
||||
})
|
||||
```
|
||||
|
||||
The function takes two arguments and returns a string:
|
||||
|
||||
| Argument | Type | Description |
|
||||
|----------|----------|----------------------------------------------|
|
||||
| -------- | -------- | -------------------------------------------- |
|
||||
| `docs` | `Array` | An array of the breadcrumbs up to that point |
|
||||
| `doc` | `Object` | The current document being edited |
|
||||
|
||||
@@ -143,7 +148,7 @@ nestedDocs({
|
||||
```
|
||||
|
||||
| Argument | Type | Description |
|
||||
|----------|----------|----------------------------------------------|
|
||||
| -------- | -------- | -------------------------------------------- |
|
||||
| `docs` | `Array` | An array of the breadcrumbs up to that point |
|
||||
| `doc` | `Object` | The current document being edited |
|
||||
|
||||
@@ -161,7 +166,9 @@ own `breadcrumbs` field to each collection manually. Set this property to the `n
|
||||
<Banner type="info">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
If you opt out of automatically being provided a `parent` or `breadcrumbs` field, you need to make sure that both fields are placed at the top-level of your document. They cannot exist within any nested data structures like a `group`, `array`, or `blocks`.
|
||||
If you opt out of automatically being provided a `parent` or `breadcrumbs` field, you need to make
|
||||
sure that both fields are placed at the top-level of your document. They cannot exist within any
|
||||
nested data structures like a `group`, `array`, or `blocks`.
|
||||
</Banner>
|
||||
|
||||
## Overrides
|
||||
@@ -170,48 +177,49 @@ You can also extend the built-in `parent` and `breadcrumbs` fields per collectio
|
||||
and `createBreadcrumbField` methods. They will merge your customizations overtop the plugin's base field configurations.
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from "payload/types";
|
||||
import { createParentField } from "@payloadcms/plugin-nested-docs/fields";
|
||||
import { createBreadcrumbsField } from "@payloadcms/plugin-nested-docs/fields";
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
import { createParentField } from '@payloadcms/plugin-nested-docs/fields'
|
||||
import { createBreadcrumbsField } from '@payloadcms/plugin-nested-docs/fields'
|
||||
|
||||
const examplePageConfig: CollectionConfig = {
|
||||
slug: "pages",
|
||||
slug: 'pages',
|
||||
fields: [
|
||||
createParentField(
|
||||
// First argument is equal to the slug of the collection
|
||||
// that the field references
|
||||
"pages",
|
||||
'pages',
|
||||
|
||||
// Second argument is equal to field overrides that you specify,
|
||||
// which will be merged into the base parent field config
|
||||
{
|
||||
admin: {
|
||||
position: "sidebar",
|
||||
position: 'sidebar',
|
||||
},
|
||||
// Note: if you override the `filterOptions` of the `parent` field,
|
||||
// be sure to continue to prevent the document from referencing itself as the parent like this:
|
||||
// filterOptions: ({ id }) => ({ id: {not_equals: id }})`
|
||||
}
|
||||
},
|
||||
),
|
||||
createBreadcrumbsField(
|
||||
// First argument is equal to the slug of the collection
|
||||
// that the field references
|
||||
"pages",
|
||||
'pages',
|
||||
|
||||
// Argument equal to field overrides that you specify,
|
||||
// which will be merged into the base `breadcrumbs` field config
|
||||
{
|
||||
label: "Page Breadcrumbs",
|
||||
}
|
||||
label: 'Page Breadcrumbs',
|
||||
},
|
||||
),
|
||||
],
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
If overriding the `name` of either `breadcrumbs` or `parent` fields, you must specify the `breadcrumbsFieldSlug` or `parentFieldSlug` respectively.
|
||||
If overriding the `name` of either `breadcrumbs` or `parent` fields, you must specify the
|
||||
`breadcrumbsFieldSlug` or `parentFieldSlug` respectively.
|
||||
</Banner>
|
||||
|
||||
## Localization
|
||||
|
||||
@@ -13,7 +13,12 @@ This plugin allows you to easily manage redirects for your application from with
|
||||
For example, if you have a page at `/about` and you want to change it to `/about-us`, you can create a redirect from the old page to the new one, then you can use this data to write HTTP redirects into your front-end application. This will ensure that users are redirected to the correct page without penalty because search engines are notified of the change at the request level. This is a very lightweight plugin that will allow you to integrate managed redirects for any front-end framework.
|
||||
|
||||
<Banner type="info">
|
||||
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-redirects). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%redirects&template=bug_report.md&title=plugin-redirects%3A) with as much detail as possible.
|
||||
This plugin is completely open-source and the [source code can be found
|
||||
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-redirects). If you need
|
||||
help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've
|
||||
found a bug, please [open a new
|
||||
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%redirects&template=bug_report.md&title=plugin-redirects%3A)
|
||||
with as much detail as possible.
|
||||
</Banner>
|
||||
|
||||
##### Core features
|
||||
@@ -35,39 +40,39 @@ Install the plugin using any JavaScript package manager like [Yarn](https://yarn
|
||||
In the `plugins` array of your [Payload config](https://payloadcms.com/docs/configuration/overview), call the plugin with [options](#options):
|
||||
|
||||
```ts
|
||||
import { buildConfig } from "payload/config";
|
||||
import redirects from "@payloadcms/plugin-redirects";
|
||||
import { buildConfig } from 'payload/config'
|
||||
import redirects from '@payloadcms/plugin-redirects'
|
||||
|
||||
const config = buildConfig({
|
||||
collections: [
|
||||
{
|
||||
slug: "pages",
|
||||
slug: 'pages',
|
||||
fields: [],
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
redirects({
|
||||
collections: ["pages"],
|
||||
collections: ['pages'],
|
||||
}),
|
||||
],
|
||||
});
|
||||
})
|
||||
|
||||
export default config;
|
||||
export default config
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `collections` | `string[]` | An array of collection slugs to populate in the `to` field of each redirect. |
|
||||
| `overrides` | `object` | A partial collection config that allows you to override anything on the `redirects` collection. |
|
||||
| Option | Type | Description |
|
||||
| ------------- | ---------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `collections` | `string[]` | An array of collection slugs to populate in the `to` field of each redirect. |
|
||||
| `overrides` | `object` | A partial collection config that allows you to override anything on the `redirects` collection. |
|
||||
|
||||
## TypeScript
|
||||
|
||||
All types can be directly imported:
|
||||
|
||||
```ts
|
||||
import { PluginConfig } from "@payloadcms/plugin-redirects/types";
|
||||
import { PluginConfig } from '@payloadcms/plugin-redirects/types'
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -17,7 +17,12 @@ To query search results, use all the existing Payload APIs that you are already
|
||||
This plugin is a great way to implement a fast, immersive search experience such as a search bar in a front-end application. Many applications may not need the power and complexity of a third-party service like Algolia or ElasticSearch. This plugin provides a first-party alternative that is easy to set up and runs entirely on your own database.
|
||||
|
||||
<Banner type="info">
|
||||
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-search). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20search&template=bug_report.md&title=plugin-search%3A) with as much detail as possible.
|
||||
This plugin is completely open-source and the [source code can be found
|
||||
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-search). If you need help,
|
||||
check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a
|
||||
bug, please [open a new
|
||||
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20search&template=bug_report.md&title=plugin-search%3A)
|
||||
with as much detail as possible.
|
||||
</Banner>
|
||||
|
||||
##### Core Features
|
||||
|
||||
@@ -15,7 +15,12 @@ As users are editing documents within the admin panel, they have the option to "
|
||||
To help you visualize what your page might look like in a search engine, a preview is rendered on page just beneath the meta fields. This preview is updated in real-time as you edit your metadata. There are also visual indicators to help you write effective meta, such as a character counter for the title and description fields. You can even inject your own custom fields into the `meta` field group as your application requires, like `og:title` or `json-ld`. If you've ever used something like Yoast SEO, this plugin might feel very familiar.
|
||||
|
||||
<Banner type="info">
|
||||
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-seo). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20seo&template=bug_report.md&title=plugin-seo%3A) with as much detail as possible.
|
||||
This plugin is completely open-source and the [source code can be found
|
||||
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-seo). If you need help,
|
||||
check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a
|
||||
bug, please [open a new
|
||||
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20seo&template=bug_report.md&title=plugin-seo%3A)
|
||||
with as much detail as possible.
|
||||
</Banner>
|
||||
|
||||
##### Core features
|
||||
@@ -86,10 +91,10 @@ An array of global slugs to enable SEO. Enabled globals receive a `meta` field w
|
||||
|
||||
An array of fields that allows you to inject your own custom fields onto the `meta` field group. The following fields are provided by default:
|
||||
|
||||
- `title`: text
|
||||
- `description`: textarea
|
||||
- `image`: upload (if an `uploadsCollection` is provided)
|
||||
- `preview`: ui
|
||||
- `title`: text
|
||||
- `description`: textarea
|
||||
- `image`: upload (if an `uploadsCollection` is provided)
|
||||
- `preview`: ui
|
||||
|
||||
##### `uploadsCollection`
|
||||
|
||||
@@ -100,7 +105,9 @@ Set the `uploadsCollection` to your application's upload-enabled collection slug
|
||||
When the `tabbedUI` property is `true`, it appends an `SEO` tab onto your config using Payload's [Tabs Field](https://payloadcms.com/docs/fields/tabs). If your collection is not already tab-enabled, meaning the first field in your config is not of type `tabs`, then one will be created for you called `Content`. Defaults to `false`.
|
||||
|
||||
<Banner type="info">
|
||||
If you wish to continue to use top-level or sidebar fields with `tabbedUI`, you must not let the default `Content` tab get created for you (see the note above). Instead, you must define the first field of your config with type `tabs` and place all other fields adjacent to this one.
|
||||
If you wish to continue to use top-level or sidebar fields with `tabbedUI`, you must not let the
|
||||
default `Content` tab get created for you (see the note above). Instead, you must define the first
|
||||
field of your config with type `tabs` and place all other fields adjacent to this one.
|
||||
</Banner>
|
||||
|
||||
##### `generateTitle`
|
||||
@@ -126,7 +133,7 @@ A function that allows you to return any meta description, including from docume
|
||||
{
|
||||
// ...
|
||||
seoPlugin({
|
||||
generateDescription: ({ ...docInfo, doc, locale }) => doc?.excerpt?.value
|
||||
generateDescription: ({ ...docInfo, doc, locale }) => doc?.excerpt?.value,
|
||||
})
|
||||
}
|
||||
```
|
||||
@@ -140,7 +147,7 @@ A function that allows you to return any meta image, including from document's c
|
||||
{
|
||||
// ...
|
||||
seoPlugin({
|
||||
generateImage: ({ ...docInfo, doc, locale }) => doc?.featuredImage?.value
|
||||
generateImage: ({ ...docInfo, doc, locale }) => doc?.featuredImage?.value,
|
||||
})
|
||||
}
|
||||
```
|
||||
@@ -154,7 +161,8 @@ A function called by the search preview component to display the actual URL of y
|
||||
{
|
||||
// ...
|
||||
seoPlugin({
|
||||
generateURL: ({ ...docInfo, doc, locale }) => `https://yoursite.com/${collection?.slug}/${doc?.slug?.value}`
|
||||
generateURL: ({ ...docInfo, doc, locale }) =>
|
||||
`https://yoursite.com/${collection?.slug}/${doc?.slug?.value}`,
|
||||
})
|
||||
}
|
||||
```
|
||||
@@ -168,7 +176,7 @@ Rename the meta group interface name that is generated for TypeScript and GraphQ
|
||||
{
|
||||
// ...
|
||||
seoPlugin({
|
||||
interfaceName: 'customInterfaceNameSEO'
|
||||
interfaceName: 'customInterfaceNameSEO',
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
@@ -17,7 +17,12 @@ To build a checkout flow on your front-end you can either use [Stripe Checkout](
|
||||
The beauty of this plugin is the entirety of your application's content and business logic can be handled in Payload while Stripe handles solely the billing and payment processing. You can build a completely proprietary application that is endlessly customizable and extendable, on APIs and databases that you own. Hosted services like Shopify or BigCommerce might fracture your application's content then charge you for access.
|
||||
|
||||
<Banner type="info">
|
||||
This plugin is completely open-source and the [source code can be found here](https://github.com/payloadcms/payload/tree/main/packages/plugin-stripe). If you need help, check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a bug, please [open a new issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20stripe&template=bug_report.md&title=plugin-stripe%3A) with as much detail as possible.
|
||||
This plugin is completely open-source and the [source code can be found
|
||||
here](https://github.com/payloadcms/payload/tree/main/packages/plugin-stripe). If you need help,
|
||||
check out our [Community Help](https://payloadcms.com/community-help). If you think you've found a
|
||||
bug, please [open a new
|
||||
issue](https://github.com/payloadcms/payload/issues/new?assignees=&labels=plugin%3A%20stripe&template=bug_report.md&title=plugin-stripe%3A)
|
||||
with as much detail as possible.
|
||||
</Banner>
|
||||
|
||||
##### Core features
|
||||
@@ -58,14 +63,14 @@ export default config
|
||||
|
||||
### Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `stripeSecretKey` \* | string | `undefined` | Your Stripe secret key |
|
||||
| `stripeWebhooksEndpointSecret` | string | `undefined` | Your Stripe webhook endpoint secret |
|
||||
| `rest` | boolean | `false` | When `true`, opens the `/api/stripe/rest` endpoint |
|
||||
| `webhooks` | object \| function | `undefined` | Either a function to handle all webhooks events, or an object of Stripe webhook handlers, keyed to the name of the event |
|
||||
| `sync` | array | `undefined` | An array of sync configs |
|
||||
| `logs` | boolean | `false` | When `true`, logs sync events to the console as they happen |
|
||||
| Option | Type | Default | Description |
|
||||
| ------------------------------ | ------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `stripeSecretKey` \* | string | `undefined` | Your Stripe secret key |
|
||||
| `stripeWebhooksEndpointSecret` | string | `undefined` | Your Stripe webhook endpoint secret |
|
||||
| `rest` | boolean | `false` | When `true`, opens the `/api/stripe/rest` endpoint |
|
||||
| `webhooks` | object \| function | `undefined` | Either a function to handle all webhooks events, or an object of Stripe webhook handlers, keyed to the name of the event |
|
||||
| `sync` | array | `undefined` | An array of sync configs |
|
||||
| `logs` | boolean | `false` | When `true`, logs sync events to the console as they happen |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -73,14 +78,14 @@ _\* An asterisk denotes that a property is required._
|
||||
|
||||
The following custom endpoints are automatically opened for you:
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --- | --- | --- |
|
||||
| `/api/stripe/rest` | `POST` | Proxies the [Stripe REST API](https://stripe.com/docs/api) behind [Payload access control](https://payloadcms.com/docs/access-control/overview) and returns the result. See the [REST Proxy](#stripe-rest-proxy) section for more details. |
|
||||
| `/api/stripe/webhooks` | `POST` | Handles all Stripe webhook events |
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `/api/stripe/rest` | `POST` | Proxies the [Stripe REST API](https://stripe.com/docs/api) behind [Payload access control](https://payloadcms.com/docs/access-control/overview) and returns the result. See the [REST Proxy](#stripe-rest-proxy) section for more details. |
|
||||
| `/api/stripe/webhooks` | `POST` | Handles all Stripe webhook events |
|
||||
|
||||
##### Stripe REST Proxy
|
||||
|
||||
If `rest` is true, proxies the [Stripe REST API](https://stripe.com/docs/api) behind [Payload access control](https://payloadcms.com/docs/access-control/overview) and returns the result. If you need to proxy the API server-side, use the [stripeProxy](#node) function.
|
||||
If `rest` is true, proxies the [Stripe REST API](https://stripe.com/docs/api) behind [Payload access control](https://payloadcms.com/docs/access-control/overview) and returns the result. This flag should only be used for local development, see the security note below for more information.
|
||||
|
||||
```ts
|
||||
const res = await fetch(`/api/stripe/rest`, {
|
||||
@@ -101,10 +106,19 @@ const res = await fetch(`/api/stripe/rest`, {
|
||||
})
|
||||
```
|
||||
|
||||
If you need to proxy the API server-side, use the [stripeProxy](#node) function.
|
||||
|
||||
<Banner type="info">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
The `/api` part of these routes may be different based on the settings defined in your Payload config.
|
||||
The `/api` part of these routes may be different based on the settings defined in your Payload
|
||||
config.
|
||||
</Banner>
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Warning:</strong>
|
||||
<br />
|
||||
Opening the REST proxy endpoint in production is a potential security risk. Authenticated users will have open access to the Stripe REST API. In production, open your own endpoint and use the [stripeProxy](#node) function to proxy the Stripe API server-side.
|
||||
</Banner>
|
||||
|
||||
## Webhooks
|
||||
@@ -220,7 +234,8 @@ This option will setup a basic sync between Payload collections and Stripe resou
|
||||
<Banner type="info">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
If you wish to enable a _two-way_ sync, be sure to setup [`webhooks`](#webhooks) and pass the `stripeWebhooksEndpointSecret` through your config.
|
||||
If you wish to enable a _two-way_ sync, be sure to setup [`webhooks`](#webhooks) and pass the
|
||||
`stripeWebhooksEndpointSecret` through your config.
|
||||
</Banner>
|
||||
|
||||
```ts
|
||||
@@ -255,7 +270,10 @@ export default config
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
Due to limitations in the Stripe API, this currently only works with top-level fields. This is because every Stripe object is a separate entity, making it difficult to abstract into a simple reusable library. In the future, we may find a pattern around this. But for now, cases like that will need to be hard-coded.
|
||||
Due to limitations in the Stripe API, this currently only works with top-level fields. This is
|
||||
because every Stripe object is a separate entity, making it difficult to abstract into a simple
|
||||
reusable library. In the future, we may find a pattern around this. But for now, cases like that
|
||||
will need to be hard-coded.
|
||||
</Banner>
|
||||
|
||||
Using `sync` will do the following:
|
||||
@@ -288,4 +306,3 @@ 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/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.
|
||||
|
||||
|
||||
@@ -44,7 +44,10 @@ Because _**you**_ are in complete control of who can do what with your data, you
|
||||
wield that power responsibly before deploying to Production.
|
||||
|
||||
<Banner type="error">
|
||||
<strong>By default, all Access Control functions require that a user is successfully logged in to Payload to create, read, update, or delete data.</strong>{' '}
|
||||
<strong>
|
||||
By default, all Access Control functions require that a user is successfully logged in to
|
||||
Payload to create, read, update, or delete data.
|
||||
</strong>{' '}
|
||||
But, if you allow public user registration, for example, you will want to make sure that your
|
||||
access control functions are more strict - permitting <strong>only appropriate users</strong> to
|
||||
perform appropriate actions.
|
||||
|
||||
@@ -9,7 +9,9 @@ keywords: query, documents, overview, documentation, Content Management System,
|
||||
Payload provides an extremely granular querying language through all APIs. Each API takes the same syntax and fully supports all options.
|
||||
|
||||
<Banner>
|
||||
<strong>Here, "querying" relates to filtering or searching through documents within a Collection.</strong>{' '}
|
||||
<strong>
|
||||
Here, "querying" relates to filtering or searching through documents within a Collection.
|
||||
</strong>{' '}
|
||||
You can build queries to pass to Find operations as well as to [restrict which documents certain
|
||||
users can access](/docs/access-control/overview) via access control functions.
|
||||
</Banner>
|
||||
|
||||
@@ -90,6 +90,19 @@ Note: Collection slugs must be formatted in kebab-case
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
operation: "Count",
|
||||
method: "GET",
|
||||
path: "/api/{collection-slug}/count",
|
||||
description: "Count the documents",
|
||||
example: {
|
||||
slug: "count",
|
||||
req: true,
|
||||
res: {
|
||||
totalDocs: 10
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
operation: "Create",
|
||||
method: "POST",
|
||||
|
||||
@@ -11,7 +11,9 @@ One of Payload's goals is to build the best rich text editor experience that we
|
||||
Classically, we've used SlateJS to work toward this goal, but building custom elements into Slate has proven to be more difficult than we'd like, and we've been keeping our options open.
|
||||
|
||||
<Banner type="warning">
|
||||
Payload's Lexical rich text editor is currently in beta. It's stable enough to use as you build on Payload, so if you're up for helping us fine-tune it, you should use it. But if you're looking for stability, use Slate instead.
|
||||
Payload's Lexical rich text editor is currently in beta. It's stable enough to use as you build on
|
||||
Payload, so if you're up for helping us fine-tune it, you should use it. But if you're looking for
|
||||
stability, use Slate instead.
|
||||
</Banner>
|
||||
|
||||
Lexical is extremely impressive and trivializes a lot of the hard parts of building new elements into a rich text editor. It has a few distinct advantages over Slate, including the following:
|
||||
@@ -38,7 +40,7 @@ export default buildConfig({
|
||||
// your collections here
|
||||
],
|
||||
// Pass the Lexical editor to the root config
|
||||
editor: lexicalEditor({})
|
||||
editor: lexicalEditor({}),
|
||||
})
|
||||
```
|
||||
|
||||
@@ -46,9 +48,7 @@ You can also override Lexical settings on a field-by-field basis as follows:
|
||||
|
||||
```ts
|
||||
import type { CollectionConfig } from 'payload/types'
|
||||
import {
|
||||
lexicalEditor
|
||||
} from '@payloadcms/richtext-lexical'
|
||||
import { lexicalEditor } from '@payloadcms/richtext-lexical'
|
||||
|
||||
export const Pages: CollectionConfig = {
|
||||
slug: 'pages',
|
||||
@@ -57,9 +57,9 @@ export const Pages: CollectionConfig = {
|
||||
name: 'content',
|
||||
type: 'richText',
|
||||
// Pass the Lexical editor here and override base settings as necessary
|
||||
editor: lexicalEditor({})
|
||||
}
|
||||
]
|
||||
editor: lexicalEditor({}),
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
@@ -82,7 +82,7 @@ import {
|
||||
BlocksFeature,
|
||||
LinkFeature,
|
||||
UploadFeature,
|
||||
lexicalEditor
|
||||
lexicalEditor,
|
||||
} from '@payloadcms/richtext-lexical'
|
||||
import { Banner } from '../blocks/Banner'
|
||||
import { CallToAction } from '../blocks/CallToAction'
|
||||
@@ -126,12 +126,9 @@ import { CallToAction } from '../blocks/CallToAction'
|
||||
// This is incredibly powerful. You can re-use your Payload blocks
|
||||
// directly in the Lexical editor as follows:
|
||||
BlocksFeature({
|
||||
blocks: [
|
||||
Banner,
|
||||
CallToAction,
|
||||
],
|
||||
blocks: [Banner, CallToAction],
|
||||
}),
|
||||
]
|
||||
],
|
||||
})
|
||||
}
|
||||
```
|
||||
@@ -153,14 +150,15 @@ Here's an overview of all the included features:
|
||||
| **`HeadingFeature`** | Yes | Adds Heading Nodes (by default, H1 - H6, but that can be customized) |
|
||||
| **`AlignFeature`** | Yes | Allows you to align text left, centered and right |
|
||||
| **`IndentFeature`** | Yes | Allows you to indent text with the tab key |
|
||||
| **`UnorderedListFeature`** | Yes | Adds unordered lists (ul) |
|
||||
| **`UnorderedListFeature`** | Yes | Adds unordered lists (ul) |
|
||||
| **`OrderedListFeature`** | Yes | Adds ordered lists (ol) |
|
||||
| **`CheckListFeature`** | Yes | Adds checklists |
|
||||
| **`LinkFeature`** | Yes | Allows you to create internal and external links |
|
||||
| **`RelationshipFeature`** | Yes | Allows you to create block-level (not inline) relationships to other documents |
|
||||
| **`BlockQuoteFeature`** | Yes | Allows you to create block-level quotes |
|
||||
| **`UploadFeature`** | Yes | Allows you to create block-level upload nodes - this supports all kinds of uploads, not just images |
|
||||
| **`BlocksFeature`** | No | Allows you to use Payload's [Blocks Field](/docs/fields/blocks) directly inside your editor. In the feature props, you can specify the allowed blocks - just like in the Blocks field. |
|
||||
| **`HorizontalRuleFeature`** | Yes | Horizontal rules / separators. Basically displays an <hr> element |
|
||||
| **`BlocksFeature`** | No | Allows you to use Payload's [Blocks Field](/docs/fields/blocks) directly inside your editor. In the feature props, you can specify the allowed blocks - just like in the Blocks field. |
|
||||
| **`TreeViewFeature`** | No | Adds a debug box under the editor, which allows you to see the current editor state live, the dom, as well as time travel. Very useful for debugging |
|
||||
|
||||
## Creating your own, custom Feature
|
||||
@@ -176,7 +174,7 @@ Next, take a look at the [features we've already built](https://github.com/paylo
|
||||
Lexical saves data in JSON, but can also generate its HTML representation via two main methods:
|
||||
|
||||
1. **Outputting HTML from the Collection:** Create a new field in your collection to convert saved JSON content to HTML. Payload generates and outputs the HTML for use in your frontend.
|
||||
2. **Generating HTML on the Frontend:** Convert JSON to HTML on-demand, either in your frontend or elsewhere.
|
||||
2. **Generating HTML on any server** Convert JSON to HTML on-demand on the server.
|
||||
|
||||
The editor comes with built-in HTML serializers, simplifying the process of converting JSON to HTML.
|
||||
|
||||
@@ -187,11 +185,7 @@ To add HTML generation directly within the collection, follow the example below:
|
||||
```ts
|
||||
import type { CollectionConfig } from 'payload/types'
|
||||
|
||||
import {
|
||||
HTMLConverterFeature,
|
||||
lexicalEditor,
|
||||
lexicalHTML
|
||||
} from '@payloadcms/richtext-lexical'
|
||||
import { HTMLConverterFeature, lexicalEditor, lexicalHTML } from '@payloadcms/richtext-lexical'
|
||||
|
||||
const Pages: CollectionConfig = {
|
||||
slug: 'pages',
|
||||
@@ -202,7 +196,8 @@ const Pages: CollectionConfig = {
|
||||
editor: lexicalEditor({
|
||||
features: ({ defaultFeatures }) => [
|
||||
...defaultFeatures,
|
||||
// The HTMLConverter Feature is the feature which manages the HTML serializers. If you do not pass any arguments to it, it will use the default serializers.
|
||||
// The HTMLConverter Feature is the feature which manages the HTML serializers.
|
||||
// If you do not pass any arguments to it, it will use the default serializers.
|
||||
HTMLConverterFeature({}),
|
||||
],
|
||||
}),
|
||||
@@ -211,9 +206,10 @@ const Pages: CollectionConfig = {
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
The `lexicalHTML()` function creates a new field that automatically converts the referenced lexical richText field into HTML through an afterRead hook.
|
||||
|
||||
#### Generating HTML in the Frontend:
|
||||
#### Generating HTML anywhere on the server:
|
||||
|
||||
If you wish to convert JSON to HTML ad-hoc, use this code snippet:
|
||||
|
||||
@@ -225,17 +221,34 @@ import {
|
||||
consolidateHTMLConverters,
|
||||
} from '@payloadcms/richtext-lexical'
|
||||
|
||||
async function lexicalToHTML(editorData: SerializedEditorState, editorConfig: SanitizedEditorConfig) {
|
||||
async function lexicalToHTML(
|
||||
editorData: SerializedEditorState,
|
||||
editorConfig: SanitizedEditorConfig,
|
||||
) {
|
||||
return await convertLexicalToHTML({
|
||||
converters: consolidateHTMLConverters({ editorConfig }),
|
||||
data: editorData,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
This method employs `convertLexicalToHTML` from `@payloadcms/richtext-lexical`, which converts the serialized editor state into HTML.
|
||||
|
||||
Because every `Feature` is able to provide html converters, and because the `htmlFeature` can modify those or provide their own, we need to consolidate them with the default html Converters using the `consolidateHTMLConverters` function.
|
||||
|
||||
#### CSS
|
||||
|
||||
Payload's lexical HTML converter does not generate CSS for you, but it does add classes to the generated HTML. You can use these classes to style the HTML in your frontend.
|
||||
|
||||
Here is some "base" CSS you can use to ensure that nested lists render correctly:
|
||||
|
||||
```css
|
||||
/* Base CSS for Lexical HTML */
|
||||
.nestedListItem, .list-check {
|
||||
list-style-type: none;
|
||||
}
|
||||
```
|
||||
|
||||
#### Creating your own HTML Converter
|
||||
|
||||
HTML Converters are typed as `HTMLConverter`, which contains the node type it should handle, and a function that accepts the serialized node from the lexical editor, and outputs the HTML string. Here's the HTML Converter of the Upload node as an example:
|
||||
@@ -286,9 +299,13 @@ export const UploadFeature = (props?: UploadFeatureProps): FeatureProvider => {
|
||||
//...
|
||||
},
|
||||
],
|
||||
plugins: [/*...*/],
|
||||
plugins: [
|
||||
/*...*/
|
||||
],
|
||||
props: props,
|
||||
slashMenu: {/*...*/},
|
||||
slashMenu: {
|
||||
/*...*/
|
||||
},
|
||||
}
|
||||
},
|
||||
key: 'upload',
|
||||
@@ -299,6 +316,7 @@ export const UploadFeature = (props?: UploadFeatureProps): FeatureProvider => {
|
||||
### Headless Editor
|
||||
|
||||
Lexical provides a seamless way to perform conversions between various other formats:
|
||||
|
||||
- HTML to Lexical (or, importing HTML into the lexical editor)
|
||||
- Markdown to Lexical (or, importing Markdown into the lexical editor)
|
||||
- Lexical to Markdown
|
||||
@@ -307,12 +325,9 @@ A headless editor can perform such conversions outside of the main editor instan
|
||||
|
||||
```ts
|
||||
import { createHeadlessEditor } from '@lexical/headless' // <= make sure this package is installed
|
||||
import {
|
||||
getEnabledNodes,
|
||||
sanitizeEditorConfig,
|
||||
} from '@payloadcms/richtext-lexical'
|
||||
import { getEnabledNodes, sanitizeEditorConfig } from '@payloadcms/richtext-lexical'
|
||||
|
||||
const yourEditorConfig; // <= your editor config here
|
||||
const yourEditorConfig // <= your editor config here
|
||||
|
||||
const headlessEditor = createHeadlessEditor({
|
||||
nodes: getEnabledNodes({
|
||||
@@ -345,23 +360,26 @@ Once you have your headless editor instance, you can use it to convert HTML to L
|
||||
|
||||
```ts
|
||||
import { $generateNodesFromDOM } from '@lexical/html'
|
||||
import { $getRoot,$getSelection } from 'lexical'
|
||||
import { JSDOM } from 'jsdom';
|
||||
import { $getRoot, $getSelection } from 'lexical'
|
||||
import { JSDOM } from 'jsdom'
|
||||
|
||||
headlessEditor.update(() => {
|
||||
// In a headless environment you can use a package such as JSDom to parse the HTML string.
|
||||
const dom = new JSDOM(htmlString)
|
||||
headlessEditor.update(
|
||||
() => {
|
||||
// In a headless environment you can use a package such as JSDom to parse the HTML string.
|
||||
const dom = new JSDOM(htmlString)
|
||||
|
||||
// Once you have the DOM instance it's easy to generate LexicalNodes.
|
||||
const nodes = $generateNodesFromDOM(headlessEditor, dom.window.document)
|
||||
// Once you have the DOM instance it's easy to generate LexicalNodes.
|
||||
const nodes = $generateNodesFromDOM(headlessEditor, dom.window.document)
|
||||
|
||||
// Select the root
|
||||
$getRoot().select()
|
||||
// Select the root
|
||||
$getRoot().select()
|
||||
|
||||
// Insert them at a selection.
|
||||
const selection = $getSelection()
|
||||
selection.insertNodes(nodes)
|
||||
}, { discrete: true })
|
||||
// Insert them at a selection.
|
||||
const selection = $getSelection()
|
||||
selection.insertNodes(nodes)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
|
||||
// Do this if you then want to get the editor JSON
|
||||
const editorJSON = headlessEditor.getEditorState().toJSON()
|
||||
@@ -374,7 +392,8 @@ This has been taken from the [lexical serialization & deserialization docs](http
|
||||
<Banner type="success">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
Using the <code>discrete: true</code> flag ensures instant updates to the editor state. If immediate reading of the updated state isn't necessary, you can omit the flag.
|
||||
Using the <code>discrete: true</code> flag ensures instant updates to the editor state. If
|
||||
immediate reading of the updated state isn't necessary, you can omit the flag.
|
||||
</Banner>
|
||||
|
||||
### Markdown => Lexical
|
||||
@@ -388,7 +407,12 @@ import { sanitizeEditorConfig } from '@payloadcms/richtext-lexical'
|
||||
const yourSanitizedEditorConfig = sanitizeEditorConfig(yourEditorConfig) // <= your editor config here
|
||||
const markdown = `# Hello World`
|
||||
|
||||
headlessEditor.update(() => { $convertFromMarkdownString(markdown, yourSanitizedEditorConfig.features.markdownTransformers) }, { discrete: true })
|
||||
headlessEditor.update(
|
||||
() => {
|
||||
$convertFromMarkdownString(markdown, yourSanitizedEditorConfig.features.markdownTransformers)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
|
||||
// Do this if you then want to get the editor JSON
|
||||
const editorJSON = headlessEditor.getEditorState().toJSON()
|
||||
@@ -406,7 +430,7 @@ Here's the code for it:
|
||||
```ts
|
||||
import { $convertToMarkdownString } from '@lexical/markdown'
|
||||
import { sanitizeEditorConfig } from '@payloadcms/richtext-lexical'
|
||||
import type { SerializedEditorState } from "lexical"
|
||||
import type { SerializedEditorState } from 'lexical'
|
||||
|
||||
const yourSanitizedEditorConfig = sanitizeEditorConfig(yourEditorConfig) // <= your editor config here
|
||||
const yourEditorState: SerializedEditorState // <= your current editor state here
|
||||
@@ -427,7 +451,6 @@ headlessEditor.getEditorState().read(() => {
|
||||
|
||||
The `.setEditorState()` function immediately updates your editor state. Thus, there's no need for the `discrete: true` flag when reading the state afterward.
|
||||
|
||||
|
||||
### Lexical => Plain Text
|
||||
|
||||
Export content from the Lexical editor into plain text using these steps:
|
||||
@@ -438,8 +461,8 @@ Export content from the Lexical editor into plain text using these steps:
|
||||
Here's the code for it:
|
||||
|
||||
```ts
|
||||
import type { SerializedEditorState } from "lexical"
|
||||
import { $getRoot } from "lexical"
|
||||
import type { SerializedEditorState } from 'lexical'
|
||||
import { $getRoot } from 'lexical'
|
||||
|
||||
const yourEditorState: SerializedEditorState // <= your current editor state here
|
||||
|
||||
@@ -451,9 +474,10 @@ try {
|
||||
}
|
||||
|
||||
// Export to plain text
|
||||
const plainTextContent = headlessEditor.getEditorState().read(() => {
|
||||
return $getRoot().getTextContent()
|
||||
}) || ''
|
||||
const plainTextContent =
|
||||
headlessEditor.getEditorState().read(() => {
|
||||
return $getRoot().getTextContent()
|
||||
}) || ''
|
||||
```
|
||||
|
||||
## Migrating from Slate
|
||||
@@ -469,10 +493,7 @@ Simply add the `SlateToLexicalFeature` to your editor:
|
||||
```ts
|
||||
import type { CollectionConfig } from 'payload/types'
|
||||
|
||||
import {
|
||||
SlateToLexicalFeature,
|
||||
lexicalEditor,
|
||||
} from '@payloadcms/richtext-lexical'
|
||||
import { SlateToLexicalFeature, lexicalEditor } from '@payloadcms/richtext-lexical'
|
||||
|
||||
const Pages: CollectionConfig = {
|
||||
slug: 'pages',
|
||||
@@ -481,10 +502,7 @@ const Pages: CollectionConfig = {
|
||||
name: 'nameOfYourRichTextField',
|
||||
type: 'richText',
|
||||
editor: lexicalEditor({
|
||||
features: ({ defaultFeatures }) => [
|
||||
...defaultFeatures,
|
||||
SlateToLexicalFeature({})
|
||||
],
|
||||
features: ({ defaultFeatures }) => [...defaultFeatures, SlateToLexicalFeature({})],
|
||||
}),
|
||||
},
|
||||
],
|
||||
@@ -494,6 +512,7 @@ const Pages: CollectionConfig = {
|
||||
and done! Now, everytime this lexical editor is initialized, it converts the slate date to lexical on-the-fly. If the data is already in lexical format, it will just pass it through.
|
||||
|
||||
This is by far the easiest way to migrate from Slate to Lexical, although it does come with a few caveats:
|
||||
|
||||
- There is a performance hit when initializing the lexical editor
|
||||
- The editor will still output the Slate data in the output JSON, as the on-the-fly converter only runs for the admin panel
|
||||
|
||||
@@ -535,7 +554,8 @@ export async function convertAll(payload: Payload, collectionName: string, field
|
||||
const promises = batch.map(async (doc: YourDocumentType) => {
|
||||
const richText = doc[fieldName]
|
||||
|
||||
if (richText && Array.isArray(richText) && !('root' in richText)) { // It's Slate data - skip already-converted data
|
||||
if (richText && Array.isArray(richText) && !('root' in richText)) {
|
||||
// It's Slate data - skip already-converted data
|
||||
const converted = convertSlateToLexical({
|
||||
converters: converters,
|
||||
slateData: richText,
|
||||
@@ -604,7 +624,7 @@ import type { CollectionConfig } from 'payload/types'
|
||||
import {
|
||||
SlateToLexicalFeature,
|
||||
lexicalEditor,
|
||||
defaultSlateConverters
|
||||
defaultSlateConverters,
|
||||
} from '@payloadcms/richtext-lexical'
|
||||
|
||||
import { YourCustomConverter } from '../converters/YourCustomConverter'
|
||||
@@ -619,10 +639,7 @@ const Pages: CollectionConfig = {
|
||||
features: ({ defaultFeatures }) => [
|
||||
...defaultFeatures,
|
||||
SlateToLexicalFeature({
|
||||
converters: [
|
||||
...defaultSlateConverters,
|
||||
YourCustomConverter
|
||||
]
|
||||
converters: [...defaultSlateConverters, YourCustomConverter],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
||||
@@ -16,7 +16,6 @@ To use the Slate editor, first you need to install it:
|
||||
npm install --save @payloadcms/richtext-slate
|
||||
```
|
||||
|
||||
|
||||
After installation, you can pass it to your top-level Payload config:
|
||||
|
||||
```ts
|
||||
@@ -28,7 +27,7 @@ export default buildConfig({
|
||||
// your collections here
|
||||
],
|
||||
// Pass the Slate editor to the root config
|
||||
editor: slateEditor({})
|
||||
editor: slateEditor({}),
|
||||
})
|
||||
```
|
||||
|
||||
@@ -52,11 +51,11 @@ export const Pages: CollectionConfig = {
|
||||
],
|
||||
leaves: [
|
||||
// customize leaves allowed in Slate editor here
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
]
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
@@ -168,7 +167,9 @@ Specifying custom `Type`s let you extend your custom elements by adding addition
|
||||
`collections/ExampleCollection.ts`
|
||||
|
||||
```ts
|
||||
import { CollectionConfig } from 'payload/types'
|
||||
import type { CollectionConfig } from 'payload/types'
|
||||
|
||||
import { slateEditor } from '@payloadcms/richtext-slate'
|
||||
|
||||
export const ExampleCollection: CollectionConfig = {
|
||||
slug: 'example-collection',
|
||||
@@ -182,57 +183,59 @@ export const ExampleCollection: CollectionConfig = {
|
||||
},
|
||||
],
|
||||
required: true,
|
||||
admin: {
|
||||
elements: [
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'link',
|
||||
'blockquote',
|
||||
{
|
||||
name: 'cta',
|
||||
Button: CustomCallToActionButton,
|
||||
Element: CustomCallToActionElement,
|
||||
plugins: [
|
||||
// any plugins that are required by this element go here
|
||||
],
|
||||
},
|
||||
],
|
||||
leaves: [
|
||||
'bold',
|
||||
'italic',
|
||||
{
|
||||
name: 'highlight',
|
||||
Button: CustomHighlightButton,
|
||||
Leaf: CustomHighlightLeaf,
|
||||
plugins: [
|
||||
// any plugins that are required by this leaf go here
|
||||
],
|
||||
},
|
||||
],
|
||||
link: {
|
||||
// Inject your own fields into the Link element
|
||||
fields: [
|
||||
editor: slateEditor({
|
||||
admin: {
|
||||
elements: [
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'link',
|
||||
'blockquote',
|
||||
{
|
||||
name: 'rel',
|
||||
label: 'Rel Attribute',
|
||||
type: 'select',
|
||||
hasMany: true,
|
||||
options: ['noopener', 'noreferrer', 'nofollow'],
|
||||
},
|
||||
],
|
||||
},
|
||||
upload: {
|
||||
collections: {
|
||||
media: {
|
||||
fields: [
|
||||
// any fields that you would like to save
|
||||
// on an upload element in the `media` collection
|
||||
name: 'cta',
|
||||
Button: CustomCallToActionButton,
|
||||
Element: CustomCallToActionElement,
|
||||
plugins: [
|
||||
// any plugins that are required by this element go here
|
||||
],
|
||||
},
|
||||
],
|
||||
leaves: [
|
||||
'bold',
|
||||
'italic',
|
||||
{
|
||||
name: 'highlight',
|
||||
Button: CustomHighlightButton,
|
||||
Leaf: CustomHighlightLeaf,
|
||||
plugins: [
|
||||
// any plugins that are required by this leaf go here
|
||||
],
|
||||
},
|
||||
],
|
||||
link: {
|
||||
// Inject your own fields into the Link element
|
||||
fields: [
|
||||
{
|
||||
name: 'rel',
|
||||
label: 'Rel Attribute',
|
||||
type: 'select',
|
||||
hasMany: true,
|
||||
options: ['noopener', 'noreferrer', 'nofollow'],
|
||||
},
|
||||
],
|
||||
},
|
||||
upload: {
|
||||
collections: {
|
||||
media: {
|
||||
fields: [
|
||||
// any fields that you would like to save
|
||||
// on an upload element in the `media` collection
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -40,21 +40,22 @@ Every Payload Collection can opt-in to supporting Uploads by specifying the `upl
|
||||
|
||||
### Collection Upload Options
|
||||
|
||||
| Option | Description |
|
||||
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`staticURL`** \* | The URL path to use to access your uploads. Relative path like `/media` will be served by payload. Full path like `https://example.com/media` needs to be served by another web server. |
|
||||
| **`staticDir`** \* | The folder directory to use to store media in. Can be either an absolute path or relative to the directory that contains your config. |
|
||||
| **`adminThumbnail`** | Set the way that the Admin panel will display thumbnails for this Collection. [More](#admin-thumbnails) |
|
||||
| **`crop`** | Set to `false` to disable the cropping tool in the Admin panel. Crop is enabled by default. [More](#crop-and-focal-point-selector) |
|
||||
| **`disableLocalStorage`** | Completely disable uploading files to disk locally. [More](#disabling-local-upload-storage) |
|
||||
| **`focalPoint`** | Set to `false` to disable the focal point selection tool in the Admin panel. The focal point selector is only available when `imageSizes` or `resizeOptions` are defined. [More](#crop-and-focal-point-selector) |
|
||||
| **`formatOptions`** | An object with `format` and `options` that are used with the Sharp image library to format the upload file. [More](https://sharp.pixelplumbing.com/api-output#toformat) |
|
||||
| **`handlers`** | Array of Express request handlers to execute before the built-in Payload static middleware executes. |
|
||||
| **`imageSizes`** | If specified, image uploads will be automatically resized in accordance to these image sizes. [More](#image-sizes) |
|
||||
| **`mimeTypes`** | Restrict mimeTypes in the file picker. Array of valid mimetypes or mimetype wildcards [More](#mimetypes) |
|
||||
| **`staticOptions`** | Set options for `express.static` to use while serving your static files. [More](http://expressjs.com/en/resources/middleware/serve-static.html) |
|
||||
| **`resizeOptions`** | An object passed to the the Sharp image library to resize the uploaded file. [More](https://sharp.pixelplumbing.com/api-resize) |
|
||||
| **`filesRequiredOnCreate`** | Mandate file data on creation, default is true. |
|
||||
| Option | Description |
|
||||
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`staticURL`** \* | The URL path to use to access your uploads. Relative path like `/media` will be served by payload. Full path like `https://example.com/media` needs to be served by another web server. |
|
||||
| **`staticDir`** \* | The folder directory to use to store media in. Can be either an absolute path or relative to the directory that contains your config. |
|
||||
| **`adminThumbnail`** | Set the way that the Admin panel will display thumbnails for this Collection. [More](#admin-thumbnails) |
|
||||
| **`crop`** | Set to `false` to disable the cropping tool in the Admin panel. Crop is enabled by default. [More](#crop-and-focal-point-selector) |
|
||||
| **`disableLocalStorage`** | Completely disable uploading files to disk locally. [More](#disabling-local-upload-storage) |
|
||||
| **`externalFileHeaderFilter`** | Accepts existing headers and can filter/modify them. |
|
||||
| **`focalPoint`** | Set to `false` to disable the focal point selection tool in the Admin panel. The focal point selector is only available when `imageSizes` or `resizeOptions` are defined. [More](#crop-and-focal-point-selector) |
|
||||
| **`formatOptions`** | An object with `format` and `options` that are used with the Sharp image library to format the upload file. [More](https://sharp.pixelplumbing.com/api-output#toformat) |
|
||||
| **`handlers`** | Array of Express request handlers to execute before the built-in Payload static middleware executes. |
|
||||
| **`imageSizes`** | If specified, image uploads will be automatically resized in accordance to these image sizes. [More](#image-sizes) |
|
||||
| **`mimeTypes`** | Restrict mimeTypes in the file picker. Array of valid mimetypes or mimetype wildcards [More](#mimetypes) |
|
||||
| **`staticOptions`** | Set options for `express.static` to use while serving your static files. [More](http://expressjs.com/en/resources/middleware/serve-static.html) |
|
||||
| **`resizeOptions`** | An object passed to the the Sharp image library to resize the uploaded file. [More](https://sharp.pixelplumbing.com/api-resize) |
|
||||
| **`filesRequiredOnCreate`** | Mandate file data on creation, default is true. |
|
||||
|
||||
_An asterisk denotes that a property above is required._
|
||||
|
||||
@@ -154,15 +155,13 @@ When an uploaded image is smaller than the defined image size, we have 3 options
|
||||
|
||||
`withoutEnlargement: undefined | false | true`
|
||||
|
||||
1.`undefined` [default]: uploading images with smaller width AND height than the image size will return null
|
||||
2. `false`: always enlarge images to the image size
|
||||
3. `true`: if the image is smaller than the image size, return the original image
|
||||
1.`undefined` [default]: uploading images with smaller width AND height than the image size will return null 2. `false`: always enlarge images to the image size 3. `true`: if the image is smaller than the image size, return the original image
|
||||
|
||||
<Banner type="error">
|
||||
<strong>Note:</strong>
|
||||
<br />
|
||||
By default, the image size will return NULL when the uploaded image is smaller than the defined image size.
|
||||
Use the `withoutEnlargement` prop to change this.
|
||||
By default, the image size will return NULL when the uploaded image is smaller than the defined
|
||||
image size. Use the `withoutEnlargement` prop to change this.
|
||||
</Banner>
|
||||
|
||||
### Crop and Focal Point Selector
|
||||
@@ -209,8 +208,7 @@ export const Media: CollectionConfig = {
|
||||
// ... image sizes here
|
||||
],
|
||||
// highlight-start
|
||||
adminThumbnail: ({ doc }) =>
|
||||
`https://google.com/custom-path-to-file/${doc.filename}`,
|
||||
adminThumbnail: ({ doc }) => `https://google.com/custom-path-to-file/${doc.filename}`,
|
||||
// highlight-end
|
||||
},
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ _If Autosave is enabled, drafts will be created automatically as the document is
|
||||
|
||||
Collections and Globals both support the same options for configuring autosave. You can either set `versions.drafts.autosave` to `true`, or pass an object to configure autosave properties.
|
||||
|
||||
| Drafts Autosave Options | Description |
|
||||
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Drafts Autosave Options | Description |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `interval` | Define an `interval` in milliseconds to automatically save progress while documents are edited. Document updates are "debounced" at this interval. Defaults to `800`. |
|
||||
|
||||
**Example config with versions, drafts, and autosave enabled:**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
module.exports = {
|
||||
printWidth: 100,
|
||||
parser: "typescript",
|
||||
parser: 'typescript',
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
trailingComma: "all",
|
||||
arrowParens: "avoid",
|
||||
};
|
||||
trailingComma: 'all',
|
||||
arrowParens: 'avoid',
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# Payload Auth Example Front-End
|
||||
|
||||
This is a [Payload](https://payloadcms.com) + [Next.js](https://nextjs.org) app using the [App Router](https://nextjs.org/docs/app) made explicitly for the [Payload Auth Example](https://github.com/payloadcms/payload/tree/main/examples/auth). It demonstrates how to authenticate your Next.js app using [Payload Authentication](https://payloadcms.com/docs/authentication/overview).
|
||||
This is a [Next.js](https://nextjs.org) [App Router](https://nextjs.org/docs/app) front-end made explicitly for the [Payload Auth Example](https://github.com/payloadcms/payload/tree/main/examples/auth). This example demonstrates how to authenticate your Next.js app using [Payload Authentication](https://payloadcms.com/docs/authentication/overview).
|
||||
|
||||
> This example uses the App Router, the latest API of Next.js. If your app is using the legacy [Pages Router](https://nextjs.org/docs/pages), check out the official [Pages Router Example](https://github.com/payloadcms/payload/tree/main/examples/auth/next-pages).
|
||||
|
||||
**IMPORTANT—This application runs on a different server as Payload and establishes a connection from another domain or port over HTTP.** For an integrated setup that runs on a single server and uses the [Local API](https://payloadcms.com/docs/local-api/overview#local-api), check out [how to serve Payload alongside Next.js](https://github.com/payloadcms/payload/tree/main/examples/auth/payload). To learn more about this, check out [how Payload can be used in its various headless capacities](https://payloadcms.com/blog/the-ultimate-guide-to-using-nextjs-with-payload).
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Payload
|
||||
@@ -13,9 +15,10 @@ First you'll need a running Payload app. There is one made explicitly for this e
|
||||
### Next.js
|
||||
|
||||
1. Clone this repo
|
||||
2. `cd` into this directory and run `yarn` or `npm install`
|
||||
2. `cd` into this directory and run `pnpm i --ignore-workspace`\*, `yarn`, or `npm install`
|
||||
> \*If you are running using pnpm within the Payload Monorepo, the `--ignore-workspace` flag is needed so that pnpm generates a lockfile in this example's directory despite the fact that one exists in root.
|
||||
3. `cp .env.example .env` to copy the example environment variables
|
||||
4. `yarn dev` or `npm run dev` to start the server
|
||||
4. `pnpm dev`, `yarn dev`, or `npm run dev` to start the server
|
||||
5. `open http://localhost:3001` to see the result
|
||||
|
||||
Once running, a user is automatically seeded in your local environment with some basic instructions. See the [Payload Auth Example](https://github.com/payloadcms/payload/tree/main/examples/auth) for full details.
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function Home() {
|
||||
{". This example demonstrates how to implement Payload's "}
|
||||
<Link href="https://payloadcms.com/docs/authentication/overview">Authentication</Link>
|
||||
{
|
||||
' strategies in both the REST and GraphQL APIs. To toggle between these APIs, see `_layout.tsx`.'
|
||||
' strategies through http using the REST and GraphQL APIs. To toggle between these two APIs, see `_layout.tsx`.'
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
|
||||
@@ -8,23 +8,23 @@
|
||||
|
||||
export interface Config {
|
||||
collections: {
|
||||
users: User;
|
||||
};
|
||||
globals: {};
|
||||
users: User
|
||||
}
|
||||
globals: {}
|
||||
}
|
||||
export interface User {
|
||||
id: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
roles?: ('admin' | 'user')[];
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
email: string;
|
||||
resetPasswordToken?: string;
|
||||
resetPasswordExpiration?: string;
|
||||
salt?: string;
|
||||
hash?: string;
|
||||
loginAttempts?: number;
|
||||
lockUntil?: string;
|
||||
password?: string;
|
||||
id: string
|
||||
firstName?: string
|
||||
lastName?: string
|
||||
roles?: ('admin' | 'user')[]
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
email: string
|
||||
resetPasswordToken?: string
|
||||
resetPasswordExpiration?: string
|
||||
salt?: string
|
||||
hash?: string
|
||||
loginAttempts?: number
|
||||
lockUntil?: string
|
||||
password?: string
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ export const RecoverPasswordForm: React.FC = () => {
|
||||
<div className={classes.formWrapper}>
|
||||
<p>
|
||||
{`Please enter your email below. You will receive an email message with instructions on
|
||||
how to reset your password. To manage your all users, `}
|
||||
how to reset your password. To manage all of your users, `}
|
||||
<Link href={`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/admin/collections/users`}>
|
||||
login to the admin dashboard
|
||||
</Link>
|
||||
|
||||
2765
examples/auth/next-app/pnpm-lock.yaml
generated
Normal file
2765
examples/auth/next-app/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
module.exports = {
|
||||
printWidth: 100,
|
||||
parser: "typescript",
|
||||
parser: 'typescript',
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
trailingComma: "all",
|
||||
arrowParens: "avoid",
|
||||
};
|
||||
trailingComma: 'all',
|
||||
arrowParens: 'avoid',
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Payload Auth Example Front-End
|
||||
|
||||
This is a [Payload](https://payloadcms.com) + [Next.js](https://nextjs.org) app using the [Pages Router](https://nextjs.org/docs/pages) made explicitly for the [Payload Auth Example](https://github.com/payloadcms/payload/tree/main/examples/auth). It demonstrates how to authenticate your Next.js app using [Payload Authentication](https://payloadcms.com/docs/authentication/overview).
|
||||
This is a [Next.js](https://nextjs.org) [Pages Router](https://nextjs.org/docs/pages) front-end made explicitly for the [Payload Auth Example](https://github.com/payloadcms/payload/tree/main/examples/auth). This example demonstrates how to authenticate your Next.js app using [Payload Authentication](https://payloadcms.com/docs/authentication/overview).
|
||||
|
||||
> This example uses the Pages Router, the legacy API of Next.js. If your app is using the latest [App Router](https://nextjs.org/docs/pages), check out the official [App Router Example](https://github.com/payloadcms/payload/tree/main/examples/auth/next-app).
|
||||
> This example uses the Pages Router, the legacy API of Next.js. If your app is using the latest [App Router](https://nextjs.org/docs/app), check out the official [App Router Example](https://github.com/payloadcms/payload/tree/main/examples/auth/next-app).
|
||||
|
||||
**IMPORTANT—This application runs on a different server as Payload and establishes a connection from another domain or port over HTTP.** For an integrated setup that runs on a single server and uses the [Local API](https://payloadcms.com/docs/local-api/overview#local-api), check out [how to serve Payload alongside Next.js](https://github.com/payloadcms/payload/tree/main/examples/auth/payload). To learn more about this, check out [how Payload can be used in its various headless capacities](https://payloadcms.com/blog/the-ultimate-guide-to-using-nextjs-with-payload).
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -13,9 +15,10 @@ First you'll need a running Payload app. There is one made explicitly for this e
|
||||
### Next.js
|
||||
|
||||
1. Clone this repo
|
||||
2. `cd` into this directory and run `yarn` or `npm install`
|
||||
2. `cd` into this directory and run `pnpm i --ignore-workspace`\*, `yarn`, or `npm install`
|
||||
> \*If you are running using pnpm within the Payload Monorepo, the `--ignore-workspace` flag is needed so that pnpm generates a lockfile in this example's directory despite the fact that one exists in root.
|
||||
3. `cp .env.example .env` to copy the example environment variables
|
||||
4. `yarn dev` or `npm run dev` to start the server
|
||||
4. `pnpm i`, `yarn dev`, or `npm run dev` to start the server
|
||||
5. `open http://localhost:3001` to see the result
|
||||
|
||||
Once running, a user is automatically seeded in your local environment with some basic instructions. See the [Payload Auth Example](https://github.com/payloadcms/payload/tree/main/examples/auth) for full details.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user