Compare commits

...

22 Commits

Author SHA1 Message Date
Elliot DeNolf
2d6e7f8a37 chore(release): v3.0.0-beta.84 [skip ci] 2024-08-16 13:56:50 -04:00
James Mikrut
3d37d74c6e fix: adds default drizzle package exports (#7728)
Default exports were missing for Drizzle package.
2024-08-16 13:40:41 -04:00
James Mikrut
de19822ed4 fix: ensures user is accurate in useAuth (#7727)
## Description

Fixes an issue where the `user` could be out of date after logging in.
2024-08-16 17:10:32 +00:00
Tylan Davis
2b2bcb5264 fix: corrects logout icon styling (#7726)
## Description

before: 
<img width="89" alt="Screenshot 2024-08-16 at 12 43 56 PM"
src="https://github.com/user-attachments/assets/1052cfdb-6dde-4b65-a4c0-e37a909dac34">

after:
<img width="48" alt="Screenshot 2024-08-16 at 12 43 35 PM"
src="https://github.com/user-attachments/assets/aa4d6aed-4a78-4b17-a209-df3618b273a1">

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

## Type of change

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

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

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 17:01:42 +00:00
Elliot DeNolf
e9b01e6d9f chore(release): v3.0.0-beta.83 [skip ci] 2024-08-16 12:36:30 -04:00
Alessio Gravili
b0a760193e fix: type RelationshipFieldClient typed incorrectly (#7725) 2024-08-16 12:35:05 -04:00
Jarrod Flesch
95569e44e4 fix: login with username server validations (#7719) 2024-08-16 12:07:53 -04:00
Paul
11816080a6 fix: bin script error when running on linux (#7721)
Fixes https://github.com/payloadcms/payload/issues/7717
2024-08-16 10:07:03 -06:00
Paul
3a86822f0a fix(ui): ensure that aborting Autosave always has a valid reason for the controller - fixes uncaught error (#7723) 2024-08-16 16:04:32 +00:00
Jarrod Flesch
6f8604e18c fix: ensures users cannot be created without confirming pw (#7583) 2024-08-16 11:44:27 -04:00
Tylan Davis
aec3f5e308 chore: admin panel style updates (#7720)
## Description

Minor admin panel style updates:
- Adjusts document header title spacing.
- Makes toast notifications more apparent.
- Adjusts alignment of create new button.
- Improves chevron icon.

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

## Type of change

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

- [x] Chore (non-breaking change which does not add functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 15:23:08 +00:00
Jarrod Flesch
e0a5de6730 chore: extends dropzone and upload field (#7713)
## Description

Tweaks to Upload and Dropzone components, making them more extendable.

- Dropzone adds prop to allow multiple files
- Upload correctly sets url if state is initialized with a File

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

## Type of change

- [x] Chore (non-breaking change which does not add functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
2024-08-16 09:38:41 -04:00
Paul
5eee49da9a feat(plugin-seo): pass req through to generate functions (#7711)
Closes https://github.com/payloadcms/payload/issues/7708
2024-08-15 23:09:08 +00:00
dependabot[bot]
b7d01dec70 chore(deps): bump pnpm/action-setup from 3 to 4 in /.github/actions/setup in the github_actions group across 1 directory (#7687)
Bumps the github_actions group with 1 update in the
/.github/actions/setup directory:
[pnpm/action-setup](https://github.com/pnpm/action-setup).

Updates `pnpm/action-setup` from 3 to 4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pnpm/action-setup/releases">pnpm/action-setup's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<p>An error is thrown if one version of pnpm is specified in the
<code>packageManager</code> field of <code>package.json</code> and a
different version is specified in the action's settings <a
href="https://redirect.github.com/pnpm/action-setup/pull/122">#122</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe02b34f77"><code>fe02b34</code></a>
docs: bump action-setup version in README</li>
<li><a
href="bee1f099e5"><code>bee1f09</code></a>
feat: throw error when multiple versions specified (<a
href="https://redirect.github.com/pnpm/action-setup/issues/122">#122</a>)</li>
<li><a
href="ce859e384f"><code>ce859e3</code></a>
refactor: replace <code>fs-extra</code> with Node.js built-in fs methods
(<a
href="https://redirect.github.com/pnpm/action-setup/issues/120">#120</a>)</li>
<li><a
href="2ab6dce4f5"><code>2ab6dce</code></a>
docs(README): fix link to LICENSE</li>
<li><a
href="e280758d01"><code>e280758</code></a>
docs(README): update dependency versions (<a
href="https://redirect.github.com/pnpm/action-setup/issues/117">#117</a>)</li>
<li><a
href="129abb77bf"><code>129abb7</code></a>
Bump undici from 5.28.2 to 5.28.3 (<a
href="https://redirect.github.com/pnpm/action-setup/issues/115">#115</a>)</li>
<li>See full diff in <a
href="https://github.com/pnpm/action-setup/compare/v3...v4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pnpm/action-setup&package-manager=github_actions&previous-version=3&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-15 15:57:33 -04:00
Elliot DeNolf
0618130fe3 chore(release): v3.0.0-beta.82 [skip ci] 2024-08-15 15:46:12 -04:00
Jacob Fletcher
cd245793fc chore(ui): resolves self-referencing imports (#7707) 2024-08-15 14:27:19 -04:00
Dan Ribbens
3a6c75a1a3 fix: importMap windows paths (#7706)
Fix windows compatibility for importMap generation
2024-08-15 17:57:48 +00:00
Alessio Gravili
5a683b6947 chore: fix issues running postgres in our dev test suites (#7704) 2024-08-15 16:58:00 +00:00
Elliot DeNolf
9b27f03e61 feat(eslint): no-imports-from-self rule (#7691)
New rule to prevent a package from importing from itself.
2024-08-15 09:02:29 -04:00
Elliot DeNolf
89746ebe09 chore(eslint): update relative import regex to handle more scenarios (#7690)
Updates no-relative-monorepo-import regex to handle more scenarios:

 Scenarios that will violate the rule:
```ts
import { something } from '../../payload/src/utilities/some-util.js'
import { something } from '../../../packages/payload/src/utilities/some-util.js'
import { something } from 'packages/payload/src/utilities/some-util.js'
```
2024-08-14 23:57:22 -04:00
dependabot[bot]
eacf2030cd chore(deps): bump the github_actions group with 2 updates (#7686)
Bumps the github_actions group with 2 updates:
[pnpm/action-setup](https://github.com/pnpm/action-setup) and
[supercharge/mongodb-github-action](https://github.com/supercharge/mongodb-github-action).

Updates `pnpm/action-setup` from 3 to 4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pnpm/action-setup/releases">pnpm/action-setup's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<p>An error is thrown if one version of pnpm is specified in the
<code>packageManager</code> field of <code>package.json</code> and a
different version is specified in the action's settings <a
href="https://redirect.github.com/pnpm/action-setup/pull/122">#122</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fe02b34f77"><code>fe02b34</code></a>
docs: bump action-setup version in README</li>
<li><a
href="bee1f099e5"><code>bee1f09</code></a>
feat: throw error when multiple versions specified (<a
href="https://redirect.github.com/pnpm/action-setup/issues/122">#122</a>)</li>
<li><a
href="ce859e384f"><code>ce859e3</code></a>
refactor: replace <code>fs-extra</code> with Node.js built-in fs methods
(<a
href="https://redirect.github.com/pnpm/action-setup/issues/120">#120</a>)</li>
<li><a
href="2ab6dce4f5"><code>2ab6dce</code></a>
docs(README): fix link to LICENSE</li>
<li><a
href="e280758d01"><code>e280758</code></a>
docs(README): update dependency versions (<a
href="https://redirect.github.com/pnpm/action-setup/issues/117">#117</a>)</li>
<li><a
href="129abb77bf"><code>129abb7</code></a>
Bump undici from 5.28.2 to 5.28.3 (<a
href="https://redirect.github.com/pnpm/action-setup/issues/115">#115</a>)</li>
<li>See full diff in <a
href="https://github.com/pnpm/action-setup/compare/v3...v4">compare
view</a></li>
</ul>
</details>
<br />

Updates `supercharge/mongodb-github-action` from 1.10.0 to 1.11.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/supercharge/mongodb-github-action/releases">supercharge/mongodb-github-action's
releases</a>.</em></p>
<blockquote>
<p>Release 1.11.0</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/supercharge/mongodb-github-action/blob/main/CHANGELOG.md">supercharge/mongodb-github-action's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/superchargejs/mongodb-github-action/compare/v1.10.0...v1.11.0">1.11.0</a>
- 2024-05-22</h2>
<h3>Added</h3>
<ul>
<li>added <code>mongodb-container-name</code> input: this option allows
you to define the Docker container name</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>use the <code>mongo</code> command to interact with MongoDB versions
4.x or lower. Previously, we only checked for MongoDB 4 and would use
<code>mongosh</code> for MongoDB 3 (and lower). <a
href="https://redirect.github.com/supercharge/mongodb-github-action/pull/61">Thanks
to Aravind!</a></li>
</ul>
<h3>Updated</h3>
<ul>
<li>bump dependencies</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5a87bd81f8"><code>5a87bd8</code></a>
prepare changelog for 1.11.0</li>
<li><a
href="7c12fc679c"><code>7c12fc6</code></a>
update readme</li>
<li><a
href="ad73029553"><code>ad73029</code></a>
bump mongoose dependency</li>
<li><a
href="268fb2c93c"><code>268fb2c</code></a>
Merge pull request <a
href="https://redirect.github.com/supercharge/mongodb-github-action/issues/61">#61</a>
from aravindnc/main</li>
<li><a
href="12b898a9c8"><code>12b898a</code></a>
Fix to use mongo client if MongoDB verison is less than or equal to
4.</li>
<li><a
href="b8277548e0"><code>b827754</code></a>
wait 20 seconds</li>
<li><a
href="5f37c5fb42"><code>5f37c5f</code></a>
revert ESLint to 8.x</li>
<li><a
href="fcc7443a6b"><code>fcc7443</code></a>
bump verions</li>
<li><a
href="fde299bc70"><code>fde299b</code></a>
bump deps</li>
<li><a
href="9ceda80ede"><code>9ceda80</code></a>
bump versions of GitHub Actions</li>
<li>Additional commits viewable in <a
href="https://github.com/supercharge/mongodb-github-action/compare/1.10.0...1.11.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-14 21:56:24 -04:00
Elliot DeNolf
86428539f5 chore: add packageManager property for dependabot 2024-08-14 21:30:53 -04:00
82 changed files with 365 additions and 205 deletions

View File

@@ -25,7 +25,7 @@ runs:
node-version: ${{ inputs.node-version }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ inputs.pnpm-version }}
run_install: false

View File

@@ -74,7 +74,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -120,7 +120,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -167,7 +167,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -217,7 +217,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -332,7 +332,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -407,7 +407,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -420,7 +420,7 @@ jobs:
key: ${{ github.sha }}-${{ github.run_number }}
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0
uses: supercharge/mongodb-github-action@1.11.0
with:
mongodb-version: 6.0
@@ -451,7 +451,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
@@ -492,7 +492,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Start MongoDB
uses: supercharge/mongodb-github-action@1.10.0
uses: supercharge/mongodb-github-action@1.11.0
with:
mongodb-version: 6.0
@@ -520,7 +520,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v3
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false

View File

@@ -119,7 +119,7 @@ A function that allows you to return any meta title, including from document's c
{
// ...
seoPlugin({
generateTitle: ({ ...docInfo, doc, locale }) => `Website.com — ${doc?.title}`,
generateTitle: ({ ...docInfo, doc, locale, req }) => `Website.com — ${doc?.title}`,
})
}
```
@@ -133,7 +133,7 @@ A function that allows you to return any meta description, including from docume
{
// ...
seoPlugin({
generateDescription: ({ ...docInfo, doc, locale }) => doc?.excerpt,
generateDescription: ({ ...docInfo, doc, locale, req }) => doc?.excerpt,
})
}
```
@@ -147,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,
generateImage: ({ ...docInfo, doc, locale, req }) => doc?.featuredImage,
})
}
```
@@ -161,7 +161,7 @@ A function called by the search preview component to display the actual URL of y
{
// ...
seoPlugin({
generateURL: ({ ...docInfo, doc, locale }) =>
generateURL: ({ ...docInfo, doc, locale, req }) =>
`https://yoursite.com/${collection?.slug}/${doc?.slug}`,
})
}

View File

@@ -62,6 +62,7 @@ export const rootEslintConfig = [
'payload/no-jsx-import-statements': 'warn',
'payload/no-relative-monorepo-imports': 'error',
'payload/no-imports-from-exports-dir': 'error',
'payload/no-imports-from-self': 'error',
},
},
{

View File

@@ -1,6 +1,6 @@
{
"name": "payload-monorepo",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"private": true,
"type": "module",
"scripts": {
@@ -103,6 +103,8 @@
"@payloadcms/eslint-config": "workspace:*",
"@payloadcms/eslint-plugin": "workspace:*",
"@payloadcms/live-preview-react": "workspace:*",
"@payloadcms/db-postgres": "workspace:*",
"drizzle-kit": "0.23.2-df9e596",
"@playwright/test": "1.46.0",
"@swc-node/register": "1.10.9",
"@swc/cli": "0.4.0",
@@ -164,6 +166,7 @@
"node": "^18.20.2 || >=20.9.0",
"pnpm": "^9.7.0"
},
"packageManager": "pnpm@9.7.0",
"pnpm": {
"allowedDeprecatedVersions": {
"abab": "2",

View File

@@ -1,6 +1,6 @@
{
"name": "create-payload-app",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-mongodb",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The officially supported MongoDB database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-postgres",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The officially supported Postgres database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-sqlite",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The officially supported SQLite database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/drizzle",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "A library of shared functions used by different payload database adapters",
"homepage": "https://payloadcms.com",
"repository": {
@@ -58,11 +58,13 @@
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./types": {
"import": "./dist/types.js",
"types": "./dist/types.d.ts"
"types": "./dist/types.d.ts",
"default": "./dist/types.js"
}
},
"main": "./dist/index.js",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/email-nodemailer",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Payload Nodemailer Email Adapter",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/email-resend",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Payload Resend Email Adapter",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -0,0 +1,67 @@
import fs from 'fs'
import path from 'path'
/** @type {import('eslint').Rule.RuleModule} */
export const rule = {
meta: {
docs: {
description: 'Disallow a package from importing from itself',
category: 'Best Practices',
recommended: true,
},
fixable: 'code',
schema: [],
},
create(context) {
let packageName = null
return {
ImportDeclaration(node) {
const importPath = node.source.value
const pkgName = getPackageName(context, packageName)
if (pkgName && importPath.startsWith(pkgName)) {
context.report({
node,
message: `Package "${pkgName}" should not import from itself. Use relative instead.`,
})
}
},
}
},
}
export default rule
/**
* @param {import('eslint').Rule.RuleContext} context
* @param {string|undefined} packageName
*/
function getPackageName(context, packageName) {
if (packageName) {
return packageName
}
const fileName = context.getFilename()
const pkg = findNearestPackageJson(path.dirname(fileName))
if (pkg) {
return pkg.name
}
}
/**
* @param {string} startDir
*/
function findNearestPackageJson(startDir) {
let currentDir = startDir
while (currentDir !== path.dirname(currentDir)) {
// Root directory check
const pkgPath = path.join(currentDir, 'package.json')
if (fs.existsSync(pkgPath)) {
const pkgContent = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
return pkgContent
}
currentDir = path.dirname(currentDir)
}
return null
}

View File

@@ -21,7 +21,7 @@ export const rule = {
const importPath = node.source.value
// Match imports starting with any number of "../" followed by "packages/"
const regex = /^(\.\.\/)*packages\/[^/]+\/src/
const regex = /^(\.\.\/)*((?!src\b)\w+\/)+src\//
if (regex.test(importPath)) {
context.report({

View File

@@ -3,6 +3,7 @@ import noNonRetryableAssertions from './customRules/no-non-retryable-assertions.
import noRelativeMonorepoImports from './customRules/no-relative-monorepo-imports.js'
import noImportsFromExportsDir from './customRules/no-imports-from-exports-dir.js'
import noFlakyAssertions from './customRules/no-flaky-assertions.js'
import noImportsFromSelf from './customRules/no-imports-from-self.js'
/**
* @type {import('eslint').ESLint.Plugin}
@@ -13,6 +14,7 @@ const index = {
'no-non-retryable-assertions': noNonRetryableAssertions,
'no-relative-monorepo-imports': noRelativeMonorepoImports,
'no-imports-from-exports-dir': noImportsFromExportsDir,
'no-imports-from-self': noImportsFromSelf,
'no-flaky-assertions': noFlakyAssertions,
'no-wait-function': {
create: function (context) {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/graphql",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/live-preview-react",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The official React SDK for Payload Live Preview",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/live-preview-vue",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The official Vue SDK for Payload Live Preview",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/live-preview",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The official live preview JavaScript SDK for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/next",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -2,8 +2,8 @@
.doc-header {
width: 100%;
margin-top: base(0.5);
padding-bottom: calc(var(--base) * 1.5);
margin-top: base(0.4);
padding-bottom: calc(var(--base) * 1.2);
display: flex;
align-items: center;
position: relative;
@@ -27,6 +27,9 @@
overflow: hidden;
text-overflow: ellipsis;
margin: 0;
padding-bottom: base(0.2);
line-height: 1;
vertical-align: top;
}
@include mid-break {

View File

@@ -8,7 +8,7 @@
position: absolute;
order: 3;
left: unset;
inset-inline-end: base(0.5);
inset-inline-end: base(0.8);
top: 50%;
transform: translateY(-50%);
color: var(--theme-elevation-600);
@@ -16,8 +16,8 @@
border: none;
svg {
width: base(0.75);
height: base(0.75);
width: base(0.8);
height: base(0.8);
}
&:hover {
@@ -33,10 +33,11 @@
.toast-title {
line-height: base(1);
margin-right: base(1);
}
.payload-toast-item {
padding: base(0.5);
padding: base(0.8);
color: var(--theme-elevation-800);
font-style: normal;
font-weight: 600;
@@ -69,8 +70,8 @@
}
.toast-icon {
width: base(1);
height: base(1);
width: base(0.8);
height: base(0.8);
margin: 0;
display: flex;
align-items: center;
@@ -84,8 +85,8 @@
&.toast-warning {
color: var(--theme-warning-800);
border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
border-color: var(--theme-warning-250);
background-color: var(--theme-warning-100);
.payload-toast-close-button {
color: var(--theme-warning-600);
@@ -98,8 +99,8 @@
&.toast-error {
color: var(--theme-error-800);
border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
border-color: var(--theme-error-250);
background-color: var(--theme-error-100);
.payload-toast-close-button {
color: var(--theme-error-600);
@@ -112,8 +113,8 @@
&.toast-success {
color: var(--theme-success-800);
border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
border-color: var(--theme-success-250);
background-color: var(--theme-success-100);
.payload-toast-close-button {
color: var(--theme-success-600);
@@ -126,8 +127,8 @@
&.toast-info {
color: var(--theme-elevation-800);
border-color: var(--theme-elevation-150);
background-color: var(--theme-elevation-50);
border-color: var(--theme-elevation-250);
background-color: var(--theme-elevation-100);
.payload-toast-close-button {
color: var(--theme-elevation-600);

View File

@@ -149,8 +149,10 @@ export const Auth: React.FC<Props> = (props) => {
{(showPasswordFields || requirePassword) && (
<div className={`${baseClass}__changing-password`}>
<PasswordField
autoComplete="new-password"
field={{
name: 'password',
_path: 'password',
admin: {
disabled,
},

View File

@@ -98,14 +98,18 @@ export const DefaultEditView: React.FC = () => {
if (globalSlug) classes.push(`global-edit--${globalSlug}`)
if (collectionSlug) classes.push(`collection-edit--${collectionSlug}`)
const [schemaPath, setSchemaPath] = React.useState(entitySlug)
const [schemaPath, setSchemaPath] = React.useState(() => {
if (operation === 'create' && auth && !auth.disableLocalStrategy) {
return `_${entitySlug}.auth`
}
return entitySlug
})
const [validateBeforeSubmit, setValidateBeforeSubmit] = useState(() => {
if (
operation === 'create' &&
collectionConfig.auth &&
!collectionConfig.auth.disableLocalStrategy
)
if (operation === 'create' && auth && !auth.disableLocalStrategy) {
return true
}
return false
})

View File

@@ -13,7 +13,7 @@
&__header {
display: flex;
align-items: center;
align-items: flex-end;
flex-wrap: wrap;
gap: base(0.8);
@@ -27,7 +27,7 @@
.pill {
position: relative;
margin: 0;
margin: 0 0 base(0.2);
}
}

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env node --no-deprecation
#!/usr/bin/env -S node --no-deprecation
import path from 'node:path'
import { fileURLToPath, pathToFileURL } from 'node:url'

View File

@@ -1,6 +1,6 @@
{
"name": "payload",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
"keywords": [
"admin panel",

View File

@@ -44,11 +44,11 @@ export const ensureUsernameOrEmail = <TSlug extends CollectionSlug>({
missingFields = true
}
// prevent clearing email if no username
if ('email' in data && !data.email && !originalDoc.username) {
if ('email' in data && !data.email && !originalDoc.username && !data?.username) {
missingFields = true
}
// prevent clearing username if no email
if ('username' in data && !data.username && !originalDoc.email) {
if ('username' in data && !data.username && !originalDoc.email && !data?.email) {
missingFields = true
}
}

View File

@@ -67,7 +67,7 @@ export function addPayloadComponentToImportMap({
imports[importIdentifier] = {
path:
componentPath.startsWith('.') || componentPath.startsWith('/')
? path.join(baseDir, componentPath.slice(1))
? path.posix.join(baseDir.replace(/\\/g, '/'), componentPath.slice(1))
: componentPath,
specifier: exportName,
}

View File

@@ -61,6 +61,8 @@ export { setsAreEqual } from '../utilities/setsAreEqual.js'
export { default as toKebabCase } from '../utilities/toKebabCase.js'
export { unflatten } from '../utilities/unflatten.js'
export { wait } from '../utilities/wait.js'
export { default as wordBoundariesRegex } from '../utilities/wordBoundariesRegex.js'

View File

@@ -962,7 +962,9 @@ export type SingleRelationshipFieldClient = {
export type RelationshipField = PolymorphicRelationshipField | SingleRelationshipField
export type RelationshipFieldClient = PolymorphicRelationshipFieldClient
export type RelationshipFieldClient =
| PolymorphicRelationshipFieldClient
| SingleRelationshipFieldClient
export type ValueWithRelation = {
relationTo: CollectionSlug

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-cloud-storage",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The official cloud storage plugin for Payload CMS",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-cloud",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The official Payload Cloud plugin",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-form-builder",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Form builder plugin for Payload CMS",
"keywords": [
"payload",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-nested-docs",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The official Nested Docs plugin for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-redirects",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Redirects plugin for Payload",
"keywords": [
"payload",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-relationship-object-ids",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "A Payload plugin to store all relationship IDs as ObjectIDs",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-search",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Search plugin for Payload",
"keywords": [
"payload",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-seo",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "SEO plugin for Payload",
"keywords": [
"payload",

View File

@@ -61,7 +61,7 @@ export const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props)
...docInfo,
doc: { ...getData() },
locale: typeof locale === 'object' ? locale?.code : locale,
} satisfies Parameters<GenerateDescription>[0]),
} satisfies Omit<Parameters<GenerateDescription>[0], 'req'>),
credentials: 'include',
headers: {
'Content-Type': 'application/json',

View File

@@ -57,7 +57,7 @@ export const MetaImageComponent: React.FC<MetaImageProps> = (props) => {
...docInfo,
doc: { ...getData() },
locale: typeof locale === 'object' ? locale?.code : locale,
} satisfies Parameters<GenerateImage>[0]),
} satisfies Omit<Parameters<GenerateImage>[0], 'req'>),
credentials: 'include',
headers: {
'Content-Type': 'application/json',

View File

@@ -62,7 +62,7 @@ export const MetaTitleComponent: React.FC<MetaTitleProps> = (props) => {
...docInfo,
doc: { ...getData() },
locale: typeof locale === 'object' ? locale?.code : locale,
} satisfies Parameters<GenerateTitle>[0]),
} satisfies Omit<Parameters<GenerateTitle>[0], 'req'>),
credentials: 'include',
headers: {
'Content-Type': 'application/json',

View File

@@ -49,7 +49,7 @@ export const PreviewComponent: React.FC<PreviewProps> = ({
...docInfo,
doc: { ...getData() },
locale: typeof locale === 'object' ? locale?.code : locale,
} satisfies Parameters<GenerateURL>[0]),
} satisfies Omit<Parameters<GenerateURL>[0], 'req'>),
credentials: 'include',
headers: {
'Content-Type': 'application/json',

View File

@@ -134,11 +134,12 @@ export const seoPlugin =
{
handler: async (req) => {
await addDataAndFileToRequest(req)
req.t
const result = pluginConfig.generateTitle
? await pluginConfig.generateTitle(
req.data as unknown as Parameters<GenerateTitle>[0],
)
? await pluginConfig.generateTitle({
...req.data,
req,
} as unknown as Parameters<GenerateTitle>[0])
: ''
return new Response(JSON.stringify({ result }), { status: 200 })
},
@@ -148,10 +149,12 @@ export const seoPlugin =
{
handler: async (req) => {
await addDataAndFileToRequest(req)
const result = pluginConfig.generateDescription
? await pluginConfig.generateDescription(
req.data as unknown as Parameters<GenerateDescription>[0],
)
? await pluginConfig.generateDescription({
...req.data,
req,
} as unknown as Parameters<GenerateDescription>[0])
: ''
return new Response(JSON.stringify({ result }), { status: 200 })
},
@@ -161,8 +164,12 @@ export const seoPlugin =
{
handler: async (req) => {
await addDataAndFileToRequest(req)
const result = pluginConfig.generateURL
? await pluginConfig.generateURL(req.data as unknown as Parameters<GenerateURL>[0])
? await pluginConfig.generateURL({
...req.data,
req,
} as unknown as Parameters<GenerateURL>[0])
: ''
return new Response(JSON.stringify({ result }), { status: 200 })
},
@@ -172,10 +179,12 @@ export const seoPlugin =
{
handler: async (req) => {
await addDataAndFileToRequest(req)
const result = pluginConfig.generateImage
? await pluginConfig.generateImage(
req.data as unknown as Parameters<GenerateImage>[0],
)
? await pluginConfig.generateImage({
...req.data,
req,
} as unknown as Parameters<GenerateImage>[0])
: ''
return new Response(result, { status: 200 })
},

View File

@@ -1,23 +1,24 @@
import type { DocumentInfoContext } from '@payloadcms/ui'
import type { Field, TextField, TextareaField, UploadField } from 'payload'
import type { Field, PayloadRequest, TextField, TextareaField, UploadField } from 'payload'
export type GenerateTitle<T = any> = (
args: { doc: T; locale?: string } & DocumentInfoContext,
args: { doc: T; locale?: string; req: PayloadRequest } & DocumentInfoContext,
) => Promise<string> | string
export type GenerateDescription<T = any> = (
args: {
doc: T
locale?: string
req: PayloadRequest
} & DocumentInfoContext,
) => Promise<string> | string
export type GenerateImage<T = any> = (
args: { doc: T; locale?: string } & DocumentInfoContext,
args: { doc: T; locale?: string; req: PayloadRequest } & DocumentInfoContext,
) => Promise<string> | string
export type GenerateURL<T = any> = (
args: { doc: T; locale?: string } & DocumentInfoContext,
args: { doc: T; locale?: string; req: PayloadRequest } & DocumentInfoContext,
) => Promise<string> | string
export type SEOPluginConfig = {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/plugin-stripe",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Stripe plugin for Payload",
"keywords": [
"payload",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/richtext-lexical",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The officially supported Lexical richtext adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -8,7 +8,7 @@
position: absolute;
order: 3;
left: unset;
inset-inline-end: base(0.5);
inset-inline-end: base(0.8);
top: 50%;
transform: translateY(-50%);
color: var(--theme-elevation-600);
@@ -16,8 +16,8 @@
border: none;
svg {
width: base(0.75);
height: base(0.75);
width: base(0.8);
height: base(0.8);
}
&:hover {
@@ -33,10 +33,11 @@
.toast-title {
line-height: base(1);
margin-right: base(1);
}
.payload-toast-item {
padding: base(0.5);
padding: base(0.8);
color: var(--theme-elevation-800);
font-style: normal;
font-weight: 600;
@@ -69,8 +70,8 @@
}
.toast-icon {
width: base(1);
height: base(1);
width: base(0.8);
height: base(0.8);
margin: 0;
display: flex;
align-items: center;
@@ -84,8 +85,8 @@
&.toast-warning {
color: var(--theme-warning-800);
border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
border-color: var(--theme-warning-250);
background-color: var(--theme-warning-100);
.payload-toast-close-button {
color: var(--theme-warning-600);
@@ -98,8 +99,8 @@
&.toast-error {
color: var(--theme-error-800);
border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
border-color: var(--theme-error-250);
background-color: var(--theme-error-100);
.payload-toast-close-button {
color: var(--theme-error-600);
@@ -112,8 +113,8 @@
&.toast-success {
color: var(--theme-success-800);
border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
border-color: var(--theme-success-250);
background-color: var(--theme-success-100);
.payload-toast-close-button {
color: var(--theme-success-600);
@@ -126,8 +127,8 @@
&.toast-info {
color: var(--theme-elevation-800);
border-color: var(--theme-elevation-150);
background-color: var(--theme-elevation-50);
border-color: var(--theme-elevation-250);
background-color: var(--theme-elevation-100);
.payload-toast-close-button {
color: var(--theme-elevation-600);

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/richtext-slate",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "The officially supported Slate richtext adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -8,7 +8,7 @@
position: absolute;
order: 3;
left: unset;
inset-inline-end: base(0.5);
inset-inline-end: base(0.8);
top: 50%;
transform: translateY(-50%);
color: var(--theme-elevation-600);
@@ -16,8 +16,8 @@
border: none;
svg {
width: base(0.75);
height: base(0.75);
width: base(0.8);
height: base(0.8);
}
&:hover {
@@ -33,10 +33,11 @@
.toast-title {
line-height: base(1);
margin-right: base(1);
}
.payload-toast-item {
padding: base(0.5);
padding: base(0.8);
color: var(--theme-elevation-800);
font-style: normal;
font-weight: 600;
@@ -69,8 +70,8 @@
}
.toast-icon {
width: base(1);
height: base(1);
width: base(0.8);
height: base(0.8);
margin: 0;
display: flex;
align-items: center;
@@ -84,8 +85,8 @@
&.toast-warning {
color: var(--theme-warning-800);
border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
border-color: var(--theme-warning-250);
background-color: var(--theme-warning-100);
.payload-toast-close-button {
color: var(--theme-warning-600);
@@ -98,8 +99,8 @@
&.toast-error {
color: var(--theme-error-800);
border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
border-color: var(--theme-error-250);
background-color: var(--theme-error-100);
.payload-toast-close-button {
color: var(--theme-error-600);
@@ -112,8 +113,8 @@
&.toast-success {
color: var(--theme-success-800);
border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
border-color: var(--theme-success-250);
background-color: var(--theme-success-100);
.payload-toast-close-button {
color: var(--theme-success-600);
@@ -126,8 +127,8 @@
&.toast-info {
color: var(--theme-elevation-800);
border-color: var(--theme-elevation-150);
background-color: var(--theme-elevation-50);
border-color: var(--theme-elevation-250);
background-color: var(--theme-elevation-100);
.payload-toast-close-button {
color: var(--theme-elevation-600);

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-azure",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for Azure Blob Storage",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-gcs",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for Google Cloud Storage",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-s3",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for Amazon S3",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-uploadthing",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for uploadthing",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/storage-vercel-blob",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"description": "Payload storage adapter for Vercel Blob Storage",
"homepage": "https://payloadcms.com",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/translations",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/ui",
"version": "3.0.0-beta.81",
"version": "3.0.0-beta.84",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",

View File

@@ -224,7 +224,7 @@ export const Autosave: React.FC<Props> = ({
if (autosaveTimeout) clearTimeout(autosaveTimeout)
if (abortController.signal) {
try {
abortController.abort()
abortController.abort('Autosave closed early.')
} catch (error) {
// swallow error
}

View File

@@ -13,13 +13,20 @@ const handleDragOver = (e: DragEvent) => {
const baseClass = 'dropzone'
export type Props = {
className?: string
mimeTypes?: string[]
onChange: (e: FileList) => void
onPasteUrlClick?: () => void
readonly className?: string
readonly mimeTypes?: string[]
readonly multipleFiles?: boolean
readonly onChange: (e: FileList) => void
readonly onPasteUrlClick?: () => void
}
export const Dropzone: React.FC<Props> = ({ className, mimeTypes, onChange, onPasteUrlClick }) => {
export const Dropzone: React.FC<Props> = ({
className,
mimeTypes,
multipleFiles,
onChange,
onPasteUrlClick,
}) => {
const dropRef = React.useRef<HTMLDivElement>(null)
const [dragging, setDragging] = React.useState(false)
const inputRef = React.useRef(null)
@@ -111,17 +118,21 @@ export const Dropzone: React.FC<Props> = ({ className, mimeTypes, onChange, onPa
>
{t('upload:selectFile')}
</Button>
<Button
buttonStyle="secondary"
className={`${baseClass}__file-button`}
onClick={onPasteUrlClick}
size="medium"
>
{t('upload:pasteURL')}
</Button>
{typeof onPasteUrlClick === 'function' && (
<Button
buttonStyle="secondary"
className={`${baseClass}__file-button`}
onClick={onPasteUrlClick}
size="medium"
>
{t('upload:pasteURL')}
</Button>
)}
<input
accept={mimeTypes?.join(',')}
aria-hidden="true"
className={`${baseClass}__hidden-input`}
multiple={multipleFiles}
onChange={handleFileSelection}
ref={inputRef}
type="file"

View File

@@ -1,16 +1,17 @@
'use client'
import { CloseMenuIcon, MenuIcon } from '@payloadcms/ui'
import React from 'react'
import { ChevronIcon } from '../../icons/Chevron/index.js'
import { CloseMenuIcon } from '../../icons/CloseMenu/index.js'
import { MenuIcon } from '../../icons/Menu/index.js'
import { useTranslation } from '../../providers/Translation/index.js'
import './index.scss'
const baseClass = 'hamburger'
export const Hamburger: React.FC<{
closeIcon?: 'collapse' | 'x'
isActive?: boolean
readonly closeIcon?: 'collapse' | 'x'
readonly isActive?: boolean
}> = (props) => {
const { t } = useTranslation()
const { closeIcon = 'x', isActive = false } = props

View File

@@ -1,11 +1,12 @@
@import '../../scss/styles';
.id-label {
font-size: base(0.75);
font-size: base(0.8);
line-height: base(1.2);
font-weight: normal;
color: var(--theme-elevation-600);
background: var(--theme-elevation-100);
padding: 0 base(0.6);
padding: base(0.2) base(0.4);
border-radius: $style-radius-m;
display: inline-flex;
}

View File

@@ -9,11 +9,10 @@ import AnimateHeightImport from 'react-animate-height'
const AnimateHeight = (AnimateHeightImport.default ||
AnimateHeightImport) as typeof AnimateHeightImport.default
import { useListInfo } from '@payloadcms/ui'
import { useUseTitleField } from '../../hooks/useUseAsTitle.js'
import { ChevronIcon } from '../../icons/Chevron/index.js'
import { SearchIcon } from '../../icons/Search/index.js'
import { useListInfo } from '../../providers/ListInfo/index.js'
import { useListQuery } from '../../providers/ListQuery/index.js'
import { useSearchParams } from '../../providers/SearchParams/index.js'
import { useTranslation } from '../../providers/Translation/index.js'
@@ -32,13 +31,13 @@ import './index.scss'
const baseClass = 'list-controls'
export type ListControlsProps = {
collectionConfig: ClientCollectionConfig
enableColumns?: boolean
enableSort?: boolean
fields: ClientField[]
handleSearchChange?: (search: string) => void
handleSortChange?: (sort: string) => void
handleWhereChange?: (where: Where) => void
readonly collectionConfig: ClientCollectionConfig
readonly enableColumns?: boolean
readonly enableSort?: boolean
readonly fields: ClientField[]
readonly handleSearchChange?: (search: string) => void
readonly handleSortChange?: (sort: string) => void
readonly handleWhereChange?: (where: Where) => void
}
/**

View File

@@ -1,11 +1,11 @@
'use client'
import type { DropdownIndicatorProps } from 'react-select'
import { ChevronIcon } from '@payloadcms/ui'
import React, { type JSX } from 'react'
import type { Option as OptionType } from '../types.js'
import { ChevronIcon } from '../../../icons/Chevron/index.js'
import './index.scss'
const baseClass = 'dropdown-indicator'

View File

@@ -1,7 +1,7 @@
@import '../../scss/styles.scss';
.render-title {
display: inline-flex;
display: inline-block;
&__id {
vertical-align: middle;
position: relative;

View File

@@ -8,10 +8,9 @@ import { useTranslation } from '../../providers/Translation/index.js'
import { StepNavProvider, useStepNav } from './context.js'
import './index.scss'
export { SetStepNav } from './SetStepNav.js'
import { PayloadIcon } from '@payloadcms/ui'
import type { StepNavItem } from './types.js'
import { PayloadIcon } from '../../graphics/Icon/index.js'
import { RenderComponent } from '../../providers/Config/RenderComponent.js'
const baseClass = 'step-nav'

View File

@@ -1,9 +1,9 @@
'use client'
import type { DateFieldClient, DefaultCellComponentProps } from 'payload'
import { useConfig } from '@payloadcms/ui'
import React from 'react'
import { useConfig } from '../../../../../providers/Config/index.js'
import { useTranslation } from '../../../../../providers/Translation/index.js'
import { formatDate } from '../../../../../utilities/formatDate.js'

View File

@@ -6,12 +6,12 @@ import type {
StaticLabel,
} from 'payload'
import { DefaultCell } from '@payloadcms/ui'
import React from 'react'
import type { ColumnPreferences } from '../../providers/ListInfo/index.js'
import type { Column } from '../Table/index.js'
import { DefaultCell } from '../../elements/Table/DefaultCell/index.js'
import { FieldLabel } from '../../fields/FieldLabel/index.js'
import { flattenFieldMap } from '../../utilities/flattenFieldMap.js'
import { SelectAll } from '../SelectAll/index.js'

View File

@@ -1,16 +1,17 @@
'use client'
import type { FormState, SanitizedCollectionConfig, UploadEdits } from 'payload'
import { useForm, useUploadEdits } from '@payloadcms/ui'
import { isImage, reduceFieldsToValues } from 'payload/shared'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { toast } from 'sonner'
import { FieldError } from '../../fields/FieldError/index.js'
import { fieldBaseClass } from '../../fields/shared/index.js'
import { useForm } from '../../forms/Form/index.js'
import { useField } from '../../forms/useField/index.js'
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js'
import { useTranslation } from '../../providers/Translation/index.js'
import { useUploadEdits } from '../../providers/UploadEdits/index.js'
import { Button } from '../Button/index.js'
import { Drawer, DrawerToggler } from '../Drawer/index.js'
import { Dropzone } from '../Dropzone/index.js'
@@ -33,10 +34,10 @@ const validate = (value) => {
}
type UploadActionsArgs = {
customActions?: React.ReactNode[]
enableAdjustments: boolean
enablePreviewSizes: boolean
mimeType: string
readonly customActions?: React.ReactNode[]
readonly enableAdjustments: boolean
readonly enablePreviewSizes: boolean
readonly mimeType: string
}
export const UploadActions = ({
@@ -77,11 +78,11 @@ export const UploadActions = ({
}
export type UploadProps = {
collectionSlug: string
customActions?: React.ReactNode[]
initialState?: FormState
onChange?: (file?: File) => void
uploadConfig: SanitizedCollectionConfig['upload']
readonly collectionSlug: string
readonly customActions?: React.ReactNode[]
readonly initialState?: FormState
readonly onChange?: (file?: File) => void
readonly uploadConfig: SanitizedCollectionConfig['upload']
}
export const Upload: React.FC<UploadProps> = (props) => {
@@ -108,15 +109,7 @@ export const Upload: React.FC<UploadProps> = (props) => {
const handleFileChange = useCallback(
(newFile: File) => {
if (newFile instanceof File) {
const fileReader = new FileReader()
fileReader.onload = (e) => {
const imgSrc = e.target?.result
if (typeof imgSrc === 'string') {
setFileSrc(imgSrc)
}
}
fileReader.readAsDataURL(newFile)
setFileSrc(URL.createObjectURL(newFile))
}
setValue(newFile)
@@ -201,6 +194,9 @@ export const Upload: React.FC<UploadProps> = (props) => {
useEffect(() => {
setDoc(reduceFieldsToValues(initialState || {}, true))
if (initialState?.file?.value instanceof File) {
setFileSrc(URL.createObjectURL(initialState.file.value))
}
setReplacingFile(false)
}, [initialState])
@@ -265,7 +261,9 @@ export const Upload: React.FC<UploadProps> = (props) => {
<div className={`${baseClass}__add-file-wrap`}>
<button
className={`${baseClass}__add-file`}
onClick={handleUrlSubmit}
onClick={() => {
void handleUrlSubmit()
}}
type="button"
>
{t('upload:addFile')}

View File

@@ -32,6 +32,7 @@ export { Collapsible } from '../../elements/Collapsible/index.js'
export { CopyToClipboard } from '../../elements/CopyToClipboard/index.js'
export { DeleteMany } from '../../elements/DeleteMany/index.js'
export { DocumentControls } from '../../elements/DocumentControls/index.js'
export { Dropzone } from '../../elements/Dropzone/index.js'
export { useDocumentDrawer } from '../../elements/DocumentDrawer/index.js'
export { DocumentFields } from '../../elements/DocumentFields/index.js'
export { Drawer, DrawerToggler, formatDrawerSlug } from '../../elements/Drawer/index.js'

View File

@@ -1,7 +1,6 @@
'use client'
import type { PasswordFieldValidation, PayloadRequest } from 'payload'
import { useConfig, useLocale, useTranslation } from '@payloadcms/ui'
import { password } from 'payload/shared'
import React, { useCallback } from 'react'
@@ -9,6 +8,9 @@ import type { PasswordFieldProps } from './types.js'
import { useField } from '../../forms/useField/index.js'
import { withCondition } from '../../forms/withCondition/index.js'
import { useConfig } from '../../providers/Config/index.js'
import { useLocale } from '../../providers/Locale/index.js'
import { useTranslation } from '../../providers/Translation/index.js'
import { isFieldRTL } from '../shared/index.js'
import './index.scss'
import { PasswordInput } from './input.js'

View File

@@ -2,10 +2,11 @@
import type { ClientField, FieldPermissions } from 'payload'
import { HiddenField, useFieldComponents } from '@payloadcms/ui'
import React from 'react'
import { HiddenField } from '../../fields/Hidden/index.js'
import { RenderComponent } from '../../providers/Config/RenderComponent.js'
import { useFieldComponents } from '../../providers/FieldComponents/index.js'
import { useOperation } from '../../providers/Operation/index.js'
import { FieldPropsProvider, useFieldProps } from '../FieldPropsProvider/index.js'

View File

@@ -2,20 +2,20 @@
import { usePathname } from 'next/navigation.js'
import React from 'react'
import { useAuth } from '../../providers/Auth/index.js'
import { RenderComponent } from '../../providers/Config/RenderComponent.js'
import { useConfig } from '../../providers/Config/index.js'
import { formatAdminURL } from '../../utilities/formatAdminURL.js'
import { GravatarAccountIcon } from './Gravatar/index.js'
import { useAuth } from '@payloadcms/ui'
import { DefaultAccountIcon } from './Default/index.js'
import { GravatarAccountIcon } from './Gravatar/index.js'
export const Account = () => {
const {
config: {
admin: {
avatar,
routes: { account: accountRoute },
components: { Avatar: CustomAvatar },
routes: { account: accountRoute },
},
routes: { admin: adminRoute },
},

View File

@@ -26,6 +26,6 @@ export const ChevronIcon: React.FC<{
width={20}
xmlns="http://www.w3.org/2000/svg"
>
<path className="stroke" d="M6 9L10 13L14 9" strokeLinecap="square" />
<path className="stroke" d="M6 8L10 12.5L14 8" strokeLinecap="square" />
</svg>
)

View File

@@ -13,7 +13,8 @@ export const LogOutIcon: React.FC = () => (
>
<path
className="stroke"
d="M8 16H5.33333C4.97971 16 4.64057 15.8595 4.39052 15.6095C4.14048 15.3594 4 15.0203 4 14.6667V5.33333C4 4.97971 4.14048 4.64057 4.39052 4.39052C4.64057 4.14048 4.97971 4 5.33333 4H8M12.6667 13.3333L16 10M16 10L12.6667 6.66667M16 10H8"
d="M12 16H14.6667C15.0203 16 15.3594 15.8595 15.6095 15.6095C15.8595 15.3594 16 15.0203 16 14.6667V5.33333C16 4.97971 15.8595 4.64057 15.6095 4.39052C15.3594 4.14048 15.0203 4 14.6667 4H12M7.33333 13.3333L4 10M4 10L7.33333 6.66667M4 10H12"
strokeLinecap="square"
/>
</svg>
)

View File

@@ -1,9 +1,10 @@
'use client'
import type { MappedComponent } from 'payload'
import { useConfig } from '@payloadcms/ui'
import React, { createContext, useContext, useEffect, useState } from 'react'
import { useConfig } from '../../providers/Config/index.js'
export { SetViewActions } from './SetViewActions/index.js'
type ActionsContextType = {
@@ -18,7 +19,9 @@ const ActionsContext = createContext<ActionsContextType>({
export const useActions = () => useContext(ActionsContext)
export const ActionsProvider = ({ children }) => {
export const ActionsProvider: React.FC<{
readonly children: React.ReactNode
}> = ({ children }) => {
const [viewActions, setViewActions] = useState([])
const [adminActions, setAdminActions] = useState([])

View File

@@ -263,6 +263,11 @@ export function AuthProvider({
}
}, [debouncedLocationChange, refreshCookie, id])
// When initialUser changes, reset in state
useEffect(() => {
setUser(initialUser)
}, [initialUser])
useEffect(() => {
setLastLocationChange(Date.now())
}, [pathname])

View File

@@ -8,7 +8,7 @@
position: absolute;
order: 3;
left: unset;
inset-inline-end: base(0.5);
inset-inline-end: base(0.8);
top: 50%;
transform: translateY(-50%);
color: var(--theme-elevation-600);
@@ -16,8 +16,8 @@
border: none;
svg {
width: base(0.75);
height: base(0.75);
width: base(0.8);
height: base(0.8);
}
&:hover {
@@ -33,10 +33,11 @@
.toast-title {
line-height: base(1);
margin-right: base(1);
}
.payload-toast-item {
padding: base(0.5);
padding: base(0.8);
color: var(--theme-elevation-800);
font-style: normal;
font-weight: 600;
@@ -69,8 +70,8 @@
}
.toast-icon {
width: base(1);
height: base(1);
width: base(0.8);
height: base(0.8);
margin: 0;
display: flex;
align-items: center;
@@ -84,8 +85,8 @@
&.toast-warning {
color: var(--theme-warning-800);
border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
border-color: var(--theme-warning-250);
background-color: var(--theme-warning-100);
.payload-toast-close-button {
color: var(--theme-warning-600);
@@ -98,8 +99,8 @@
&.toast-error {
color: var(--theme-error-800);
border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
border-color: var(--theme-error-250);
background-color: var(--theme-error-100);
.payload-toast-close-button {
color: var(--theme-error-600);
@@ -112,8 +113,8 @@
&.toast-success {
color: var(--theme-success-800);
border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
border-color: var(--theme-success-250);
background-color: var(--theme-success-100);
.payload-toast-close-button {
color: var(--theme-success-600);
@@ -126,8 +127,8 @@
&.toast-info {
color: var(--theme-elevation-800);
border-color: var(--theme-elevation-150);
background-color: var(--theme-elevation-50);
border-color: var(--theme-elevation-250);
background-color: var(--theme-elevation-100);
.payload-toast-close-button {
color: var(--theme-elevation-600);

View File

@@ -1,6 +1,6 @@
import type { Data, FormState } from 'payload'
import { unflatten as flatleyUnflatten } from '../../../payload/src/utilities/unflatten.js'
import { unflatten as flatleyUnflatten } from 'payload/shared'
type ReturnType = {
data: Data

9
pnpm-lock.yaml generated
View File

@@ -30,6 +30,9 @@ importers:
'@next/bundle-analyzer':
specifier: 15.0.0-canary.104
version: 15.0.0-canary.104
'@payloadcms/db-postgres':
specifier: workspace:*
version: link:packages/db-postgres
'@payloadcms/eslint-config':
specifier: workspace:*
version: link:packages/eslint-config
@@ -99,6 +102,9 @@ importers:
dotenv:
specifier: 16.4.5
version: 16.4.5
drizzle-kit:
specifier: 0.23.2-df9e596
version: 0.23.2-df9e596
drizzle-orm:
specifier: 0.32.1
version: 0.32.1(@libsql/client@0.6.2)(@types/pg@8.10.2)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0)
@@ -1672,6 +1678,9 @@ importers:
dotenv:
specifier: 16.4.5
version: 16.4.5
drizzle-kit:
specifier: 0.23.2-df9e596
version: 0.23.2-df9e596
eslint-plugin-playwright:
specifier: 1.6.2
version: 1.6.2(eslint-plugin-jest@28.6.0(@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@9.6.0)(typescript@5.5.4))(eslint@9.6.0)(typescript@5.5.4))(eslint@9.6.0)(jest@29.7.0(@types/node@20.12.5)(babel-plugin-macros@3.1.0))(typescript@5.5.4))(eslint@9.6.0)

View File

@@ -120,7 +120,7 @@ describe('auth', () => {
await ensureCompilationIsDone({ page, serverURL })
})
describe('authenticated users', () => {
describe('passwords', () => {
beforeAll(() => {
url = new AdminUrlUtil(serverURL, slug)
})
@@ -155,6 +155,29 @@ describe('auth', () => {
await expect(page.locator('#field-email')).toHaveValue(emailBeforeSave)
})
test('should prevent new user creation without confirm password', async () => {
await page.goto(url.create)
await page.locator('#field-email').fill('dev2@payloadcms.com')
await page.locator('#field-password').fill('password')
// should fail to save without confirm password
await page.locator('#action-save').click()
await expect(
page.locator('.field-type.confirm-password .tooltip--show', {
hasText: exactText('This field is required.'),
}),
).toBeVisible()
// should succeed with matching confirm password
await page.locator('#field-confirm-password').fill('password')
await saveDocAndAssert(page, '#action-save')
})
})
describe('authenticated users', () => {
beforeAll(() => {
url = new AdminUrlUtil(serverURL, slug)
})
test('should have up-to-date user in `useAuth` hook', async () => {
await page.goto(url.account)
await page.waitForURL(url.account)

View File

@@ -5,11 +5,14 @@ import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import open from 'open'
import { loadEnv } from 'payload/node'
import { getNextJSRootDir } from './helpers/getNextJSRootDir.js'
import { runInit } from './runInit.js'
import { createTestHooks } from './testHooks.js'
loadEnv()
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)

View File

@@ -73,6 +73,7 @@
"qs-esm": "7.0.2",
"server-only": "^0.0.1",
"slate": "0.91.4",
"drizzle-kit": "0.23.2-df9e596",
"tempy": "^1.0.1",
"ts-essentials": "7.0.3",
"typescript": "5.5.4",