Compare commits

..

51 Commits

Author SHA1 Message Date
Elliot DeNolf
2a8bd4c775 chore(release): v3.0.0-beta.96 [skip ci] 2024-08-29 11:25:10 -04:00
James Mikrut
ac10bad723 fix(db-postgres): nested localized arrays (#7962)
## Description

Fixes a bug with nested arrays within either localized blocks or arrays.
2024-08-29 15:01:53 +00:00
Elliot DeNolf
142616e6ad chore(eslint): curly [skip-lint] (#7959)
Now enforcing curly brackets on all if statements. Includes auto-fixer.


```ts
//  Bad
if (foo) foo++;

//  Good
if (foo) {
  foo++;
}
```




Note: this did not lint the `drizzle` package or any `db-*` packages.
This will be done in the future.
2024-08-29 10:15:36 -04:00
Jarrod Flesch
dd3d985091 chore: upload field style fix (#7942) 2024-08-29 00:11:56 -04:00
Jarrod Flesch
de3d7c95e7 fix: prevents duplicate active nav indicators (#7943) 2024-08-29 00:11:42 -04:00
Elliot DeNolf
570422ff9a chore(db-mongodb): adjust default exports (#7945) 2024-08-29 04:09:44 +00:00
Elliot DeNolf
53c41bdfd8 chore(cpa): unused vars (#7944) 2024-08-29 03:59:44 +00:00
Elliot DeNolf
e5c34ead16 chore: plugin lint fixes (#7947) 2024-08-29 03:59:16 +00:00
Elliot DeNolf
6e561b11ca chore(graphql): adjust default exports (#7946) 2024-08-29 03:51:03 +00:00
Jarrod Flesch
f7146362df chore: brings back tests from has many PR (#7917) 2024-08-28 22:44:58 -04:00
Elliot DeNolf
ec9d1cda2d chore(eslint): lint:fix on all packages (#7941)
- Run `lint:fix` on all packages to fix anything that may have slipped
through without being autofixed
- A few manual fixes as well.
2024-08-29 02:35:17 +00:00
Elliot DeNolf
657326b528 chore(eslint): remove unused .eslintignore files [skip ci] 2024-08-28 22:12:19 -04:00
James Mikrut
538b7ee616 feat!: auto-removes localized property from localized fields within other localized fields (#7933)
## Description

Payload localization works on a field-by-field basis. As you can nest
fields within other fields, you could potentially nest a localized field
within a localized field—but this would be redundant and unnecessary.
There would be no reason to define a localized field within a localized
parent field, given that the entire data structure from the parent field
onward would be localized.

Up until this point, Payload would _allow_ you to nest a localized field
within another localized field, and this might have worked in MongoDB
but it will throw errors in Postgres.

Now, Payload will automatically remove the `localized: true` property
from sub-fields within `sanitizeFields` if a parent field is localized.

This could potentially be a breaking change if you have a configuration
with MongoDB that nests localized fields within localized fields.

## Migrating

You probably only need to migrate if you are using MongoDB, as there,
you may not have noticed any problems. But in Postgres or SQLite, this
would have caused issues so it's unlikely that you've made it too far
without experiencing issues due to a nested localized fields config.

In the event you would like to keep existing data in this fashion, we
have added a `compatibility.allowLocalizedWithinLocalized` flag to the
Payload config, which you can set to `true`, and Payload will then
disable this new sanitization step.

Set this compatibility flag to `true` only if you have an existing
Payload MongoDB database from pre-3.0, and you have nested localized
fields that you would like to maintain without migrating.
2024-08-29 01:56:17 +00:00
Elliot DeNolf
828f5d866d build(scripts): add lint scripts to all, turbo lint tasks [skip ci] 2024-08-28 21:55:51 -04:00
Alessio Gravili
e375f6e727 feat: significantly reduce payload install size by removing unnecessary monaco-editor dependency (#7939)
This reduces the total install size of `payload` from 115 MB to 34 MB. 

We never used monaco-editor within payload - we were only using
`@monaco-editor/react` which is a lot smaller.

Since we expose its types to the end user, we have to add it to our
`dependencies`, not `devDependencies`.

Before:
https://npmgraph.js.org/?q=payload@3.0.0-canary.1a675ae#select=exact%3Apayload%403.0.0-canary.1a675ae&zoom=w

After:
https://npmgraph.js.org/?q=payload%403.0.0-canary.cdb9474#zoom=h&select=exact%3Apayload%403.0.0-canary.cdb9474
2024-08-28 23:24:42 +00:00
Paul
cc9b877e88 fix: improve validation errors for unique fields (#7937) 2024-08-28 16:10:54 -06:00
Alessio Gravili
dc12047723 feat: reduce package size and amount of dependencies by upgrading json-schema-to-typescript (#7938)
Closes https://github.com/payloadcms/payload/issues/7934
2024-08-28 21:59:32 +00:00
Jarrod Flesch
12fb691e4f chore: upload dropzone style changes (#7932) 2024-08-28 15:49:14 -04:00
Alessio Gravili
0962850086 fix: incorrect config.upload types (#7874)
Fixes https://github.com/payloadcms/payload/issues/7698

Now exporting `FetchAPIFileUploadOptions` from payload, as that type is
now used in `config.upload`.
2024-08-28 15:39:51 -04:00
Elliot DeNolf
78c8bb81a1 chore(release): v3.0.0-beta.95 [skip ci] 2024-08-28 14:49:15 -04:00
Elliot DeNolf
419b274bb1 chore: move ui and translations into deps from peerDeps (#7929)
Move `ui` and `translations` from peerDeps into deps for a few packages.
Users should not have to install these directly unless they are making
customizations.
2024-08-28 14:47:02 -04:00
Alessio Gravili
ef818fd5c8 fix(ui): admin.dependencies components not added to client config (#7928) 2024-08-28 13:56:52 -04:00
Germán Jabloñski
0aaf3af1ea fix(richtext-lexical): enabledCollections and disabledCollections props in RelationshipFeature (#7926)
fixes https://github.com/payloadcms/payload/issues/7379

The enabledCollections and disabledCollections properties of the
RelationshipFeature were not being sent to the client and therefore did
not have the expected effect.

Now those 2 properties are sent to the client via the
`clientFeatureProps` property.
2024-08-28 13:45:10 -04:00
James Mikrut
18b0806b5b fix(db-postgres, db-sqlite): hasMany text, number, poly relationship, blocks, arrays within localized fields (#7900)
## Description

In Postgres, localized blocks or arrays that contain other array / block
/ relationship fields were not properly storing locales in the database.

Now they are! Need to check a few things yet:

- Ensure test coverage is sufficient
- Test localized array, with non-localized array inside of it
- Test localized block with relationship field within it
- Ensure `_rels` table gets the `locale` column added if a single
non-localized relationship exists within a localized array / block

Fixes step 6 as identified in #7805
2024-08-28 17:43:12 +00:00
Jacob Fletcher
3d9051ad34 test: extracts reorderColumns e2e util for reuse (#7923) 2024-08-28 12:20:47 -04:00
Jarrod Flesch
e4ef47b938 chore(examples): multi tenant single domain fixes (#7922) 2024-08-28 11:34:22 -04:00
Alessio Gravili
c7e7dc71d3 fix(richtext-lexical): ensure html converter text is escaped (#7919) 2024-08-28 14:31:06 +00:00
Jarrod Flesch
375671c162 fix: active nav item set incorrectly in child routes (#7918) 2024-08-28 10:00:13 -04:00
Elliot DeNolf
23b495b145 build: update turborepo npm scripts (#7899)
Updating all turborepo npm scripts for this rather inconvenient breaking
change: https://github.com/vercel/turborepo/pull/8137
2024-08-27 22:04:05 -04:00
Paul
27d743e2a8 fix: depth not being respected by upload has many (#7897) 2024-08-28 00:50:29 +00:00
Elliot DeNolf
8c9ff3d54b revert(scripts): publish script progress prefix 2024-08-27 19:53:15 -04:00
Elliot DeNolf
5c447252e7 chore(release): v3.0.0-beta.94 [skip ci] 2024-08-27 19:47:37 -04:00
Jarrod Flesch
a76be81368 fix: upload has many field updates (#7894)
## Description

Implements fixes and style changes for the upload field component.

Fixes https://github.com/payloadcms/payload/issues/7819

![CleanShot 2024-08-27 at 16 22
33](https://github.com/user-attachments/assets/fa27251c-20b8-45ad-9109-55dee2e19e2f)

![CleanShot 2024-08-27 at 16 22
49](https://github.com/user-attachments/assets/de2d24f9-b2f5-4b72-abbe-24a6c56a4c21)


- [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

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

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation

---------

Co-authored-by: Paul Popus <paul@nouance.io>
2024-08-27 19:07:18 -04:00
Paul
5d97d57e70 feat(templates): add new slug component to the website (#7895)
https://github.com/user-attachments/assets/1ba125d3-9c65-4bab-98df-fb80c70eeb71
2024-08-27 22:26:56 +00:00
Alessio Gravili
de7ff1f8c6 fix(richtext-lexical): html converters can populate relationships infinitely (#7890)
Fixes https://github.com/payloadcms/payload/issues/7743
2024-08-27 15:24:50 -04:00
James Mikrut
3d714d3e72 fix: locale selector + autosave race condition (#7891)
## Description

Fixes a race condition where you could switch locales and have autosave
trigger with old locale data.

By adding the `key` to the `Document` component, we will ensure that the
entire `Document` will be un-mounted and re-mounted between locale
switches.
2024-08-27 14:56:28 -04:00
Elliot DeNolf
2bbb02b9c0 chore(scripts): add package count to publish script [skip ci] 2024-08-27 14:41:47 -04:00
Elliot DeNolf
0533e7f5db chore(release): v3.0.0-beta.93 [skip ci] 2024-08-27 14:16:30 -04:00
Paul
23c5ef428d fix: bugs in versions UI with perPage, pagination and diffs not showing for tabs. publish button no longer double saves when using keyboard (#7889)
Fixes:
- issue with publish button double saving on keyboard command
- versions diffs not showing if fields are tabs
https://github.com/payloadcms/payload/issues/7860
- navigation on versions not working for perPage and pagination
2024-08-27 17:45:30 +00:00
Alessio Gravili
f046a04510 fix(richtext-lexical): dependency checker suggesting incorrect version (#7888)
Fixes this:
https://discord.com/channels/967097582721572934/1278031296970625190/1278031652089757818
2024-08-27 17:17:19 +00:00
Elliot DeNolf
4cda7d2363 chore(release): v3.0.0-beta.92 [skip ci] 2024-08-27 09:44:02 -04:00
Elliot DeNolf
ea48cfbfe9 feat: implement info command (#7882)
Implements `info` command similar to Next.js.

`pnpm payload info` will output info in this format:

```
Binaries:
  Node: 18.20.2
  npm: 10.5.0
  Yarn: 1.22.19
  pnpm: 9.7.0
Relevant Packages:
  payload: 3.0.0-beta.91
  next: 15.0.0-canary.104
  @payloadcms/db-mongodb: 3.0.0-beta.91
  @payloadcms/db-postgres: 3.0.0-beta.91
  @payloadcms/email-nodemailer: 3.0.0-beta.91
  @payloadcms/graphql: 3.0.0-beta.91
  @payloadcms/next/utilities: 3.0.0-beta.91
  @payloadcms/plugin-cloud: 3.0.0-beta.91
  @payloadcms/richtext-lexical: 3.0.0-beta.91
  @payloadcms/richtext-slate: 3.0.0-beta.91
  @payloadcms/translations: 3.0.0-beta.91
  @payloadcms/ui/shared: 3.0.0-beta.91
  react: 19.0.0-rc-06d0b89e-20240801
  react-dom: 19.0.0-rc-06d0b89e-20240801
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:13:04 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6020
  Available memory (MB): 32768
  Available CPU cores: 12
 ```
2024-08-27 01:41:39 +00:00
Paul
1aeb912762 fix(templates): website live preview and code block (#7881) 2024-08-26 23:42:45 +00:00
Paul
ce2cb35d71 fix(plugin-seo): remove dependency on import from payload/next package (#7879) 2024-08-26 22:40:38 +00:00
Paul
d3ec68ac2f fix: error when closing the live preview popup window (#7878) 2024-08-26 22:33:56 +00:00
Paul
05bf52aac3 fix(templates): website bug fixes for slug generation and form builder and adds support for strictNullChecks: true (#7877) 2024-08-26 22:10:09 +00:00
Jacob Fletcher
fed7f2fa5b fix: sanitizes modifyResponseHeaders from client config (#7876) 2024-08-26 21:50:29 +00:00
James Mikrut
686b0865b2 fix: exports richtext-slate useSlatePlugin (#7875)
## Description

exports `useSlatePlugin` for `richtext-slate`
2024-08-26 17:21:25 -04:00
Alessio Gravili
dfb4c8eb4c feat: add nextjs and react version checks to dependency checker (#7868) 2024-08-26 17:19:14 -04:00
Alessio Gravili
ad7a387e19 feat(richtext-lexical): more lenient url validation, URL-encode invalid urls on save (#7870)
Fixes https://github.com/payloadcms/payload/issues/7477

This simplifies validation to the point where it only errors on spaces.
Actual validation is then used in beforeChange, which then automatically
url encodes the input if it doesn't pass
2024-08-26 15:33:29 -04:00
Elliot DeNolf
d05be016ce ci(scripts): emoji release notes 2024-08-23 16:25:50 -04:00
582 changed files with 17732 additions and 3823 deletions

View File

@@ -196,6 +196,48 @@ import { MyFieldComponent } from 'my-external-package/client'
which is a valid way to access MyFieldComponent that can be resolved by the consuming project.
### Custom Components from unknown locations
By default, any component paths from known locations are added to the import map. However, if you need to add any components from unknown locations to the import map, you can do so by adding them to the `admin.dependencies` array in your Payload Config. This is mostly only relevant for plugin authors and not for regular Payload users.
Example:
```ts
export default {
// ...
admin: {
// ...
dependencies: {
myTestComponent: { // myTestComponent is the key - can be anything
path: '/components/TestComponent.js#TestComponent',
type: 'component',
clientProps: {
test: 'hello',
},
},
},
}
}
```
This way, `TestComponent` is added to the import map, no matter if it's referenced in a known location or not. On the client, you can then use the component like this:
```tsx
'use client'
import { RenderComponent, useConfig } from '@payloadcms/ui'
import React from 'react'
export const CustomView = () => {
const { config } = useConfig()
return (
<div>
<RenderComponent mappedComponent={config.admin.dependencies?.myTestComponent} />
</div>
)
}
```
## Root Components
Root Components are those that effect the [Admin Panel](./overview) generally, such as the logo or the main nav.

View File

@@ -71,6 +71,7 @@ The following options are available:
| **`db`** \* | The Database Adapter which will be used by Payload. [More details](../database/overview). |
| **`serverURL`** | A string used to define the absolute URL of your app. This includes the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port. |
| **`collections`** | An array of Collections for Payload to manage. [More details](./collections). |
| **`compatibility`** | Compatibility flags for earlier versions of Payload. [More details](#compatibility-flags). |
| **`globals`** | An array of Globals for Payload to manage. [More details](./globals). |
| **`cors`** | Cross-origin resource sharing (CORS) is a mechanism that accept incoming requests from given domains. You can also customize the `Access-Control-Allow-Headers` header. [More details](#cors). |
| **`localization`** | Opt-in to translate your content into multiple locales. [More details](./localization). |
@@ -253,3 +254,13 @@ import type { Config, SanitizedConfig } from 'payload'
The Payload Config only lives on the server and is not allowed to contain any client-side code. That way, you can load up the Payload Config in any server environment or standalone script, without having to use Bundlers or Node.js loaders to handle importing client-only modules (e.g. scss files or React Components) without any errors.
Behind the curtains, the Next.js-based Admin Panel generates a ClientConfig, which strips away any server-only code and enriches the config with React Components.
## Compatibility flags
The Payload Config can accept compatibility flags for running the newest versions but with older databases. You should only use these flags if you need to, and should confirm that you need to prior to enabling these flags.
`allowLocalizedWithinLocalized`
Payload localization works on a field-by-field basis. As you can nest fields within other fields, you could potentially nest a localized field within a localized field—but this would be redundant and unnecessary. There would be no reason to define a localized field within a localized parent field, given that the entire data structure from the parent field onward would be localized.
By default, Payload will remove the `localized: true` property from sub-fields if a parent field is localized. Set this compatibility flag to `true` only if you have an existing Payload MongoDB database from pre-3.0, and you have nested localized fields that you would like to maintain without migrating.

View File

@@ -40,6 +40,7 @@ export const rootEslintConfig = [
{
ignores: [
...defaultESLintIgnores,
'packages/eslint-*/**',
'test/live-preview/next-app',
'packages/**/*.spec.ts',
'templates/**',

View File

@@ -5,6 +5,8 @@ import config from '@payload-config'
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
import { importMap } from '../importMap.js'
type Args = {
params: {
segments: string[]
@@ -17,6 +19,7 @@ type Args = {
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
generatePageMetadata({ config, params, searchParams })
const NotFound = ({ params, searchParams }: Args) => NotFoundPage({ config, params, searchParams })
const NotFound = ({ params, searchParams }: Args) =>
NotFoundPage({ config, importMap, params, searchParams })
export default NotFound

View File

@@ -5,6 +5,8 @@ import config from '@payload-config'
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
import { importMap } from '../importMap.js'
type Args = {
params: {
segments: string[]
@@ -17,6 +19,7 @@ type Args = {
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
generatePageMetadata({ config, params, searchParams })
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
const Page = ({ params, searchParams }: Args) =>
RootPage({ config, importMap, params, searchParams })
export default Page

View File

@@ -0,0 +1,7 @@
import { TenantFieldComponent as TenantFieldComponent_0 } from '@/fields/TenantField/components/Field'
import { TenantSelectorRSC as TenantSelectorRSC_1 } from '@/components/TenantSelector'
export const importMap = {
'@/fields/TenantField/components/Field#TenantFieldComponent': TenantFieldComponent_0,
'@/components/TenantSelector#TenantSelectorRSC': TenantSelectorRSC_1,
}

View File

@@ -1,18 +1,21 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
import configPromise from "@payload-config";
import "@payloadcms/next/css";
import { RootLayout } from "@payloadcms/next/layouts";
import configPromise from '@payload-config'
import '@payloadcms/next/css'
import { RootLayout } from '@payloadcms/next/layouts'
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import React from "react";
import React from 'react'
import "./custom.scss";
import { importMap } from './admin/importMap.js'
import './custom.scss'
type Args = {
children: React.ReactNode;
};
children: React.ReactNode
}
const Layout = ({ children }: Args) => (
<RootLayout config={configPromise}>{children}</RootLayout>
);
<RootLayout config={configPromise} importMap={importMap}>
{children}
</RootLayout>
)
export default Layout;
export default Layout

View File

@@ -1,6 +1,6 @@
import type { Access } from 'payload'
import type { User } from '../../../../payload-types'
import type { User } from '../../../payload-types'
import { isSuperAdmin } from '../../../access/isSuperAdmin'
import { getTenantAdminTenantAccessIDs } from '../../../utilities/getTenantAccessIDs'

View File

@@ -1,6 +1,6 @@
import type { CollectionConfig } from 'payload'
import type { User } from '../../../payload-types'
import type { User } from '../../payload-types'
import { getTenantAdminTenantAccessIDs } from '../../utilities/getTenantAccessIDs'
import { createAccess } from './access/create'
@@ -37,32 +37,6 @@ const Users: CollectionConfig = {
{
name: 'tenant',
type: 'relationship',
filterOptions: ({ user }) => {
if (!user) {
// Would like to query where exists true on id
// but that is not working
return {
id: {
like: '',
},
}
}
if (user?.roles?.includes('super-admin')) {
// Would like to query where exists true on id
// but that is not working
return {
id: {
like: '',
},
}
}
const adminTenantAccessIDs = getTenantAdminTenantAccessIDs(user as User)
return {
id: {
in: adminTenantAccessIDs,
},
}
},
index: true,
relationTo: 'tenants',
required: true,

View File

@@ -2,17 +2,18 @@
import type { Option } from '@payloadcms/ui/elements/ReactSelect'
import type { OptionObject } from 'payload'
import { getTenantAdminTenantAccessIDs } from '@/utilities/getTenantAccessIDs'
import { SelectInput, useAuth } from '@payloadcms/ui'
import * as qs from 'qs-esm'
import React from 'react'
import type { Tenant, User } from '../../../payload-types.js'
import type { Tenant, User } from '../../payload-types'
import './index.scss'
export const TenantSelector = ({ initialCookie }: { initialCookie?: string }) => {
const { user } = useAuth<User>()
const [options, setOptions] = React.useState<OptionObject[]>([])
const [value, setValue] = React.useState<string | undefined>(initialCookie)
const isSuperAdmin = user?.roles?.includes('super-admin')
const tenantIDs =
@@ -28,18 +29,6 @@ export const TenantSelector = ({ initialCookie }: { initialCookie?: string }) =>
document.cookie = name + '=' + (value || '') + expires + '; path=/'
}
React.useEffect(() => {
const fetchTenants = async () => {
const res = await fetch(`/api/tenants?depth=0&limit=100&sort=name`, {
credentials: 'include',
}).then((res) => res.json())
setOptions(res.docs.map((doc: Tenant) => ({ label: doc.name, value: doc.id })))
}
void fetchTenants()
}, [])
const handleChange = React.useCallback((option: Option | Option[]) => {
if (!option) {
setCookie('payload-tenant', undefined)
@@ -50,7 +39,44 @@ export const TenantSelector = ({ initialCookie }: { initialCookie?: string }) =>
}
}, [])
if (isSuperAdmin || tenantIDs.length > 1) {
React.useEffect(() => {
const fetchTenants = async () => {
const adminOfTenants = getTenantAdminTenantAccessIDs(user ?? null)
const queryString = qs.stringify(
{
depth: 0,
limit: 100,
sort: 'name',
where: {
id: {
in: adminOfTenants,
},
},
},
{
addQueryPrefix: true,
},
)
const res = await fetch(`/api/tenants${queryString}`, {
credentials: 'include',
}).then((res) => res.json())
const optionsToSet = res.docs.map((doc: Tenant) => ({ label: doc.name, value: doc.id }))
if (optionsToSet.length === 1) {
setCookie('payload-tenant', optionsToSet[0].value)
}
setOptions(optionsToSet)
}
if (user) {
void fetchTenants()
}
}, [user])
if ((isSuperAdmin || tenantIDs.length > 1) && options.length > 1) {
return (
<div className="tenant-selector">
<SelectInput
@@ -59,7 +85,7 @@ export const TenantSelector = ({ initialCookie }: { initialCookie?: string }) =>
onChange={handleChange}
options={options}
path="setTenant"
value={value}
value={options.find((opt) => opt.value === initialCookie)?.value}
/>
</div>
)

View File

@@ -0,0 +1,34 @@
'use client'
import { RelationshipField, useField } from '@payloadcms/ui'
import React from 'react'
type Props = {
initialValue?: string
path: string
readOnly: boolean
}
export function TenantFieldComponentClient({ initialValue, path, readOnly }: Props) {
const { formInitializing, setValue } = useField({ path })
const hasSetInitialValue = React.useRef(false)
React.useEffect(() => {
if (!hasSetInitialValue.current && !formInitializing && initialValue) {
setValue(initialValue)
hasSetInitialValue.current = true
}
}, [initialValue, setValue, formInitializing])
return (
<RelationshipField
field={{
name: path,
type: 'relationship',
_path: path,
label: 'Tenant',
relationTo: 'tenants',
required: true,
}}
readOnly={readOnly}
/>
)
}

View File

@@ -1,26 +1,32 @@
'use client'
import { RelationshipField, useAuth, useFieldProps } from '@payloadcms/ui'
import type { Payload } from 'payload'
import { cookies as getCookies, headers as getHeaders } from 'next/headers'
import React from 'react'
import type { User } from '../../../../payload-types.js'
import { TenantFieldComponentClient } from './Field.client'
export const TenantFieldComponent = () => {
const { user } = useAuth<User>()
const { path, readOnly } = useFieldProps()
export const TenantFieldComponent: React.FC<{
path: string
payload: Payload
readOnly: boolean
}> = async (args) => {
const cookies = getCookies()
const headers = getHeaders()
const { user } = await args.payload.auth({ headers })
if (user) {
if ((user.tenants && user.tenants.length > 1) || user?.roles?.includes('super-admin')) {
return (
<RelationshipField
label="Tenant"
name={path}
path={path}
readOnly={readOnly}
relationTo="tenants"
required
/>
)
}
if (
user &&
((Array.isArray(user.tenants) && user.tenants.length > 1) ||
user?.roles?.includes('super-admin'))
) {
return (
<TenantFieldComponentClient
initialValue={cookies.get('payload-tenant')?.value || undefined}
path={args.path}
readOnly={args.readOnly}
/>
)
}
return null
}

View File

@@ -2,7 +2,6 @@ import type { Field } from 'payload'
import { isSuperAdmin } from '../../access/isSuperAdmin'
import { tenantFieldUpdate } from './access/update'
import { TenantFieldComponent } from './components/Field'
import { autofillTenant } from './hooks/autofillTenant'
export const tenantField: Field = {
@@ -17,7 +16,7 @@ export const tenantField: Field = {
},
admin: {
components: {
Field: TenantFieldComponent,
Field: '@/fields/TenantField/components/Field#TenantFieldComponent',
},
position: 'sidebar',
},

View File

@@ -17,6 +17,9 @@ export interface Config {
'payload-preferences': PayloadPreference;
'payload-migrations': PayloadMigration;
};
db: {
defaultIDType: string;
};
globals: {};
locale: null;
user: User & {
@@ -26,15 +29,20 @@ export interface Config {
export interface UserAuthOperations {
forgotPassword: {
email: string;
password: string;
};
login: {
password: string;
email: string;
password: string;
};
registerFirstUser: {
email: string;
password: string;
};
unlock: {
email: string;
password: string;
};
}
/**
* This interface was referenced by `Config`'s JSON-Schema

View File

@@ -7,7 +7,6 @@ import { fileURLToPath } from 'url'
import { Pages } from './collections/Pages'
import { Tenants } from './collections/Tenants'
import Users from './collections/Users'
import { TenantSelectorRSC } from './components/TenantSelector'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
@@ -15,7 +14,7 @@ const dirname = path.dirname(filename)
export default buildConfig({
admin: {
components: {
afterNavLinks: [TenantSelectorRSC],
afterNavLinks: ['@/components/TenantSelector#TenantSelectorRSC'],
},
user: 'users',
},

View File

@@ -1,4 +1,4 @@
import type { User } from '../../payload-types'
import type { User } from '../payload-types'
export const getTenantAccessIDs = (user: User | null): string[] => {
if (!user) return []

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,7 @@ export default withBundleAnalyzer(
env: {
PAYLOAD_CORE_DEV: 'true',
ROOT_DIR: path.resolve(dirname),
PAYLOAD_DISABLE_DEPENDENCY_CHECKER: 'true',
PAYLOAD_CI_DEPENDENCY_CHECKER: 'true',
},
async redirects() {
return [

View File

@@ -1,6 +1,6 @@
{
"name": "payload-monorepo",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"private": true,
"type": "module",
"scripts": {
@@ -10,46 +10,46 @@
"build:app": "next build",
"build:app:analyze": "cross-env ANALYZE=true next build",
"build:clean": "pnpm clean:build",
"build:core": "turbo build --filter \"!@payloadcms/plugin-*\"",
"build:core:force": "pnpm clean:build && turbo build --filter \"!@payloadcms/plugin-*\" --no-cache --force",
"build:core": "turbo build --filter \"!@payloadcms/plugin-*\" --filter \"!@payloadcms/storage-*\"",
"build:core:force": "pnpm clean:build && pnpm build:core --no-cache --force",
"build:create-payload-app": "turbo build --filter create-payload-app",
"build:db-mongodb": "turbo build --filter db-mongodb",
"build:db-postgres": "turbo build --filter db-postgres",
"build:db-sqlite": "turbo build --filter db-sqlite",
"build:db-vercel-postgres": "turbo build --filter db-vercel-postgres",
"build:drizzle": "turbo build --filter drizzle",
"build:email-nodemailer": "turbo build --filter email-nodemailer",
"build:email-resend": "turbo build --filter email-resend",
"build:eslint-config": "turbo build --filter eslint-config",
"build:db-mongodb": "turbo build --filter \"@payloadcms/db-mongodb\"",
"build:db-postgres": "turbo build --filter \"@payloadcms/db-postgres\"",
"build:db-sqlite": "turbo build --filter \"@payloadcms/db-sqlite\"",
"build:db-vercel-postgres": "turbo build --filter \"@payloadcms/db-vercel-postgres\"",
"build:drizzle": "turbo build --filter \"@payloadcms/drizzle\"",
"build:email-nodemailer": "turbo build --filter \"@payloadcms/email-nodemailer\"",
"build:email-resend": "turbo build --filter \"@payloadcms/email-resend\"",
"build:eslint-config": "turbo build --filter \"@payloadcms/eslint-config\"",
"build:essentials:force": "pnpm clean:build && turbo build --filter=\"payload...\" --filter=\"@payloadcms/ui\" --filter=\"@payloadcms/next\" --filter=\"@payloadcms/db-mongodb\" --filter=\"@payloadcms/db-postgres\" --filter=\"@payloadcms/richtext-lexical\" --filter=\"@payloadcms/translations\" --filter=\"@payloadcms/plugin-cloud\" --filter=\"@payloadcms/graphql\" --no-cache --force",
"build:force": "pnpm run build:core:force",
"build:graphql": "turbo build --filter graphql",
"build:live-preview": "turbo build --filter live-preview",
"build:live-preview-react": "turbo build --filter live-preview-react",
"build:live-preview-vue": "turbo build --filter live-preview-vue",
"build:graphql": "turbo build --filter \"@payloadcms/graphql\"",
"build:live-preview": "turbo build --filter \"@payloadcms/live-preview\"",
"build:live-preview-react": "turbo build --filter \"@payloadcms/live-preview-react\"",
"build:live-preview-vue": "turbo build --filter \"@payloadcms/live-preview-vue\"",
"build:next": "turbo build --filter \"@payloadcms/next\"",
"build:payload": "turbo build --filter payload",
"build:plugin-cloud": "turbo build --filter plugin-cloud",
"build:plugin-cloud-storage": "turbo build --filter plugin-cloud-storage",
"build:plugin-form-builder": "turbo build --filter plugin-form-builder",
"build:plugin-nested-docs": "turbo build --filter plugin-nested-docs",
"build:plugin-redirects": "turbo build --filter plugin-redirects",
"build:plugin-relationship-object-ids": "turbo build --filter plugin-relationship-object-ids",
"build:plugin-search": "turbo build --filter plugin-search",
"build:plugin-sentry": "turbo build --filter plugin-sentry",
"build:plugin-seo": "turbo build --filter plugin-seo",
"build:plugin-stripe": "turbo build --filter plugin-stripe",
"build:plugin-cloud": "turbo build --filter \"@payloadcms/plugin-cloud\"",
"build:plugin-cloud-storage": "turbo build --filter \"@payloadcms/plugin-cloud-storage\"",
"build:plugin-form-builder": "turbo build --filter \"@payloadcms/plugin-form-builder\"",
"build:plugin-nested-docs": "turbo build --filter \"@payloadcms/plugin-nested-docs\"",
"build:plugin-redirects": "turbo build --filter \"@payloadcms/plugin-redirects\"",
"build:plugin-relationship-object-ids": "turbo build --filter \"@payloadcms/plugin-relationship-object-ids\"",
"build:plugin-search": "turbo build --filter \"@payloadcms/plugin-search\"",
"build:plugin-sentry": "turbo build --filter \"@payloadcms/plugin-sentry\"",
"build:plugin-seo": "turbo build --filter \"@payloadcms/plugin-seo\"",
"build:plugin-stripe": "turbo build --filter \"@payloadcms/plugin-stripe\"",
"build:plugins": "turbo build --filter \"@payloadcms/plugin-*\"",
"build:richtext-lexical": "turbo build --filter richtext-lexical",
"build:richtext-slate": "turbo build --filter richtext-slate",
"build:storage-azure": "turbo build --filter storage-azure",
"build:storage-gcs": "turbo build --filter storage-gcs",
"build:storage-s3": "turbo build --filter storage-s3",
"build:storage-uploadthing": "turbo build --filter storage-uploadthing",
"build:storage-vercel-blob": "turbo build --filter storage-vercel-blob",
"build:richtext-lexical": "turbo build --filter \"@payloadcms/richtext-lexical\"",
"build:richtext-slate": "turbo build --filter \"@payloadcms/richtext-slate\"",
"build:storage-azure": "turbo build --filter \"@payloadcms/storage-azure\"",
"build:storage-gcs": "turbo build --filter \"@payloadcms/storage-gcs\"",
"build:storage-s3": "turbo build --filter \"@payloadcms/storage-s3\"",
"build:storage-uploadthing": "turbo build --filter \"@payloadcms/storage-uploadthing\"",
"build:storage-vercel-blob": "turbo build --filter \"@payloadcms/storage-vercel-blob\"",
"build:tests": "pnpm --filter payload-test-suite run typecheck",
"build:translations": "turbo build --filter translations",
"build:ui": "turbo build --filter ui",
"build:translations": "turbo build --filter \"@payloadcms/translations\"",
"build:ui": "turbo build --filter \"@payloadcms/ui\"",
"clean": "turbo clean",
"clean:all": "node ./scripts/delete-recursively.js '@node_modules' 'media/*' '**/dist/' '**/.cache/*' '**/.next/*' '**/.turbo/*' '**/tsconfig.tsbuildinfo' '**/payload*.tgz' '**/meta_*.json'",
"clean:build": "node ./scripts/delete-recursively.js 'media/' '**/dist/' '**/.cache/' '**/.next/' '**/.turbo/' '**/tsconfig.tsbuildinfo' '**/payload*.tgz' '**/meta_*.json'",
@@ -64,10 +64,10 @@
"docker:restart": "pnpm docker:stop --remove-orphans && pnpm docker:start",
"docker:start": "docker compose -f packages/plugin-cloud-storage/docker-compose.yml up -d",
"docker:stop": "docker compose -f packages/plugin-cloud-storage/docker-compose.yml down",
"fix": "eslint \"packages/**/*.ts\" --fix",
"force:build": "pnpm run build:core:force",
"lint": "eslint \"packages/**/*.ts\"",
"lint": "turbo run lint --concurrency 1 --continue",
"lint-staged": "lint-staged",
"lint:fix": "turbo run lint:fix --concurrency 1 --continue",
"obliterate-playwright-cache-macos": "rm -rf ~/Library/Caches/ms-playwright && find /System/Volumes/Data/private/var/folders -type d -name 'playwright*' -exec rm -rf {} +",
"prepare": "husky",
"reinstall": "pnpm clean:all && pnpm install",
@@ -159,7 +159,7 @@
"swc-plugin-transform-remove-imports": "1.15.0",
"tempy": "1.0.1",
"tsx": "4.17.0",
"turbo": "^2.0.14",
"turbo": "^2.1.0",
"typescript": "5.5.4"
},
"peerDependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "create-payload-app",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
@@ -42,6 +42,8 @@
"build": "pnpm pack-template-files && pnpm typecheck && pnpm build:swc",
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
"clean": "rimraf {dist,*.tsbuildinfo}",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"pack-template-files": "node --no-deprecation --import @swc-node/register/esm-register src/scripts/pack-template-files.ts",
"prepublishOnly": "pnpm clean && pnpm build",
"test": "jest",

View File

@@ -14,6 +14,7 @@ import { getValidTemplates } from './templates.js'
describe('createProject', () => {
let projectDir: string
beforeAll(() => {
// eslint-disable-next-line no-console
console.log = jest.fn()
})
@@ -57,7 +58,7 @@ describe('createProject', () => {
const packageJson = fse.readJsonSync(packageJsonPath)
// Check package name and description
expect(packageJson.name).toEqual(projectName)
expect(packageJson.name).toStrictEqual(projectName)
})
describe('creates project from template', () => {
@@ -115,10 +116,6 @@ describe('createProject', () => {
})
)?.[0]
if (!payloadConfigPath) {
throw new Error(`Could not find payload.config.ts inside ${projectDir}`)
}
const content = fse.readFileSync(payloadConfigPath, 'utf-8')
// Check payload.config.ts

View File

@@ -2,7 +2,6 @@ import type { CompilerOptions } from 'typescript'
import * as p from '@clack/prompts'
import { parse, stringify } from 'comment-json'
import execa from 'execa'
import fs from 'fs'
import fse from 'fs-extra'
import globby from 'globby'
@@ -53,8 +52,7 @@ export async function initNext(args: InitNextArgs): Promise<InitNextResult> {
nextAppDetails.nextAppDir = createdAppDir
}
const { hasTopLevelLayout, isPayloadInstalled, isSrcDir, nextAppDir, nextConfigType } =
nextAppDetails
const { hasTopLevelLayout, isSrcDir, nextAppDir, nextConfigType } = nextAppDetails
if (!nextConfigType) {
return {
@@ -169,7 +167,9 @@ async function installAndConfigurePayload(
}
const logDebug = (message: string) => {
if (debug) origDebug(message)
if (debug) {
origDebug(message)
}
}
if (!fs.existsSync(projectDir)) {
@@ -210,7 +210,7 @@ async function installAndConfigurePayload(
)
// This is a little clunky and needs to account for isSrcDir
copyRecursiveSync(templateSrcDir, path.dirname(nextConfigPath), debug)
copyRecursiveSync(templateSrcDir, path.dirname(nextConfigPath))
// Wrap next.config.js with withPayload
await wrapNextConfig({ nextConfigPath, nextConfigType })

View File

@@ -4,13 +4,19 @@ import slugify from '@sindresorhus/slugify'
import type { CliArgs } from '../types.js'
export async function parseProjectName(args: CliArgs): Promise<string> {
if (args['--name']) return slugify(args['--name'])
if (args._[0]) return slugify(args._[0])
if (args['--name']) {
return slugify(args['--name'])
}
if (args._[0]) {
return slugify(args._[0])
}
const projectName = await p.text({
message: 'Project name?',
validate: (value) => {
if (!value) return 'Please enter a project name.'
if (!value) {
return 'Please enter a project name.'
}
},
})
if (p.isCancel(projectName)) {

View File

@@ -9,7 +9,9 @@ export async function parseTemplate(
if (args['--template']) {
const templateName = args['--template']
const template = validTemplates.find((t) => t.name === templateName)
if (!template) throw new Error('Invalid template given')
if (!template) {
throw new Error('Invalid template given')
}
return template
}

View File

@@ -54,7 +54,9 @@ export async function selectDb(args: CliArgs, projectName: string): Promise<DbDe
value: dbChoice.value,
})),
})
if (p.isCancel(dbType)) process.exit(0)
if (p.isCancel(dbType)) {
process.exit(0)
}
}
const dbChoice = dbChoiceRecord[dbType]
@@ -73,7 +75,9 @@ export async function selectDb(args: CliArgs, projectName: string): Promise<DbDe
initialValue: initialDbUri,
message: `Enter ${dbChoice.title.split(' ')[0]} connection string`, // strip beta from title
})
if (p.isCancel(dbUri)) process.exit(0)
if (p.isCancel(dbUri)) {
process.exit(0)
}
}
return {

View File

@@ -16,7 +16,9 @@ import { installPackages } from './install-packages.js'
export async function updatePayloadInProject(
appDetails: NextAppDetails,
): Promise<{ message: string; success: boolean }> {
if (!appDetails.nextConfigPath) return { message: 'No Next.js config found', success: false }
if (!appDetails.nextConfigPath) {
return { message: 'No Next.js config found', success: false }
}
const projectDir = path.dirname(appDetails.nextConfigPath)

View File

@@ -42,8 +42,6 @@ export async function parseAndModifyConfigContent(
): Promise<{ modifiedConfigContent: string; success: boolean }> {
content = withPayloadStatement[configType] + '\n' + content
console.log({ configType, content })
if (configType === 'cjs' || configType === 'esm') {
try {
const ast = parseModule(content, { loc: true })

View File

@@ -36,7 +36,9 @@ export async function writeEnvFile(args: {
.split('\n')
.filter((e) => e)
.map((line) => {
if (line.startsWith('#') || !line.includes('=')) return line
if (line.startsWith('#') || !line.includes('=')) {
return line
}
const split = line.split('=')
const key = split[0]

View File

@@ -6,7 +6,7 @@ import path from 'path'
*
* @internal
*/
export function copyRecursiveSync(src: string, dest: string, debug?: boolean) {
export function copyRecursiveSync(src: string, dest: string) {
const exists = fs.existsSync(src)
const stats = exists && fs.statSync(src)
const isDirectory = exists && stats !== false && stats.isDirectory()

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-mongodb",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"description": "The officially supported MongoDB database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {
@@ -30,6 +30,8 @@
"build:swc": "swc ./src -d ./dist --config-file .swcrc-build --strip-leading-paths",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"clean": "rimraf {dist,*.tsbuildinfo}",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},
"dependencies": {

View File

@@ -59,8 +59,10 @@ export const connect: Connect = async function connect(
await this.migrate({ migrations: this.prodMigrations })
}
} catch (err) {
console.log(err)
this.payload.logger.error(`Error: cannot connect to MongoDB. Details: ${err.message}`, err)
this.payload.logger.error({
err,
msg: `Error: cannot connect to MongoDB. Details: ${err.message}`,
})
process.exit(1)
}
}

View File

@@ -2,7 +2,7 @@ import type { CreateGlobal, PayloadRequest } from 'payload'
import type { MongooseAdapter } from './index.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const createGlobal: CreateGlobal = async function createGlobal(

View File

@@ -2,7 +2,7 @@ import type { DeleteOne, Document, PayloadRequest } from 'payload'
import type { MongooseAdapter } from './index.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const deleteOne: DeleteOne = async function deleteOne(

View File

@@ -6,7 +6,7 @@ import { flattenWhereToOperators } from 'payload'
import type { MongooseAdapter } from './index.js'
import { buildSortParam } from './queries/buildSortParam.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const find: Find = async function find(

View File

@@ -4,7 +4,7 @@ import { combineQueries } from 'payload'
import type { MongooseAdapter } from './index.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const findGlobal: FindGlobal = async function findGlobal(

View File

@@ -6,7 +6,7 @@ import { buildVersionGlobalFields, flattenWhereToOperators } from 'payload'
import type { MongooseAdapter } from './index.js'
import { buildSortParam } from './queries/buildSortParam.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const findGlobalVersions: FindGlobalVersions = async function findGlobalVersions(

View File

@@ -3,7 +3,7 @@ import type { Document, FindOne, PayloadRequest } from 'payload'
import type { MongooseAdapter } from './index.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const findOne: FindOne = async function findOne(

View File

@@ -6,7 +6,7 @@ import { flattenWhereToOperators } from 'payload'
import type { MongooseAdapter } from './index.js'
import { buildSortParam } from './queries/buildSortParam.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const findVersions: FindVersions = async function findVersions(

View File

@@ -8,10 +8,10 @@ import { buildVersionCollectionFields, buildVersionGlobalFields } from 'payload'
import type { MongooseAdapter } from './index.js'
import type { CollectionModel } from './types.js'
import buildCollectionSchema from './models/buildCollectionSchema.js'
import { buildCollectionSchema } from './models/buildCollectionSchema.js'
import { buildGlobalModel } from './models/buildGlobalModel.js'
import buildSchema from './models/buildSchema.js'
import getBuildQueryPlugin from './queries/buildQuery.js'
import { buildSchema } from './models/buildSchema.js'
import { getBuildQueryPlugin } from './queries/buildQuery.js'
import { getDBName } from './utilities/getDBName.js'
export const init: Init = function init(this: MongooseAdapter) {

View File

@@ -3,10 +3,10 @@ import type { SanitizedCollectionConfig, SanitizedConfig } from 'payload'
import paginate from 'mongoose-paginate-v2'
import getBuildQueryPlugin from '../queries/buildQuery.js'
import buildSchema from './buildSchema.js'
import { getBuildQueryPlugin } from '../queries/buildQuery.js'
import { buildSchema } from './buildSchema.js'
const buildCollectionSchema = (
export const buildCollectionSchema = (
collection: SanitizedCollectionConfig,
config: SanitizedConfig,
schemaOptions = {},
@@ -44,5 +44,3 @@ const buildCollectionSchema = (
return schema
}
export default buildCollectionSchema

View File

@@ -4,8 +4,8 @@ import mongoose from 'mongoose'
import type { GlobalModel } from '../types.js'
import getBuildQueryPlugin from '../queries/buildQuery.js'
import buildSchema from './buildSchema.js'
import { getBuildQueryPlugin } from '../queries/buildQuery.js'
import { buildSchema } from './buildSchema.js'
export const buildGlobalModel = (config: SanitizedConfig): GlobalModel | null => {
if (config.globals && config.globals.length > 0) {

View File

@@ -111,7 +111,7 @@ const localizeSchema = (
return schema
}
const buildSchema = (
export const buildSchema = (
config: SanitizedConfig,
configFields: Field[],
buildSchemaOptions: BuildSchemaOptions = {},
@@ -669,5 +669,3 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
})
},
}
export default buildSchema

View File

@@ -18,7 +18,10 @@ export type BuildQueryArgs = {
// This plugin asynchronously builds a list of Mongoose query constraints
// which can then be used in subsequent Mongoose queries.
const getBuildQueryPlugin = ({ collectionSlug, versionsFields }: GetBuildQueryPluginArgs = {}) => {
export const getBuildQueryPlugin = ({
collectionSlug,
versionsFields,
}: GetBuildQueryPluginArgs = {}) => {
return function buildQueryPlugin(schema) {
const modifiedSchema = schema
async function buildQuery({
@@ -57,5 +60,3 @@ const getBuildQueryPlugin = ({ collectionSlug, versionsFields }: GetBuildQueryPl
modifiedSchema.statics.buildQuery = buildQuery
}
}
export default getBuildQueryPlugin

View File

@@ -16,7 +16,7 @@ describe('get localized sort property', () => {
},
} as Config)
})
it('passes through a non-localized sort property', async () => {
it('passes through a non-localized sort property', () => {
const result = getLocalizedSortProperty({
config,
fields: [

View File

@@ -6,7 +6,7 @@ import { combineQueries, flattenWhereToOperators } from 'payload'
import type { MongooseAdapter } from './index.js'
import { buildSortParam } from './queries/buildSortParam.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const queryDrafts: QueryDrafts = async function queryDrafts(

View File

@@ -6,6 +6,8 @@ import { v4 as uuid } from 'uuid'
import type { MongooseAdapter } from '../index.js'
// Needs await to fulfill the interface
// eslint-disable-next-line @typescript-eslint/require-await
export const beginTransaction: BeginTransaction = async function beginTransaction(
this: MongooseAdapter,
options: TransactionOptions,

View File

@@ -2,7 +2,7 @@ import type { PayloadRequest, UpdateGlobal } from 'payload'
import type { MongooseAdapter } from './index.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const updateGlobal: UpdateGlobal = async function updateGlobal(

View File

@@ -3,7 +3,7 @@ import type { PayloadRequest, UpdateOne } from 'payload'
import type { MongooseAdapter } from './index.js'
import { handleError } from './utilities/handleError.js'
import sanitizeInternalFields from './utilities/sanitizeInternalFields.js'
import { sanitizeInternalFields } from './utilities/sanitizeInternalFields.js'
import { withSession } from './withSession.js'
export const updateOne: UpdateOne = async function updateOne(

View File

@@ -1,6 +1,6 @@
const internalFields = ['__v']
const sanitizeInternalFields = <T extends Record<string, unknown>>(incomingDoc: T): T =>
export const sanitizeInternalFields = <T extends Record<string, unknown>>(incomingDoc: T): T =>
Object.entries(incomingDoc).reduce((newDoc, [key, val]): T => {
if (key === '_id') {
return {
@@ -18,5 +18,3 @@ const sanitizeInternalFields = <T extends Record<string, unknown>>(incomingDoc:
[key]: val,
}
}, {} as T)
export default sanitizeInternalFields

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-postgres",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"description": "The officially supported Postgres database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {
@@ -40,6 +40,8 @@
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"clean": "rimraf {dist,*.tsbuildinfo}",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prepack": "pnpm clean && pnpm turbo build",
"prepublishOnly": "pnpm clean && pnpm turbo build",
"renamePredefinedMigrations": "node --no-deprecation --import @swc-node/register/esm-register ./scripts/renamePredefinedMigrations.ts"

View File

@@ -1,10 +0,0 @@
.tmp
**/.git
**/.hg
**/.pnp.*
**/.svn
**/.yarn/**
**/build
**/dist/**
**/node_modules
**/temp

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-sqlite",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"description": "The officially supported SQLite database adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {
@@ -39,6 +39,8 @@
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"clean": "rimraf {dist,*.tsbuildinfo}",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prepack": "pnpm clean && pnpm turbo build",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},

View File

@@ -58,9 +58,17 @@ type Args = {
tableName: string
timestamps?: boolean
versions: boolean
/**
* Tracks whether or not this table is built
* from the result of a localized array or block field at some point
*/
withinLocalizedArrayOrBlock?: boolean
}
type Result = {
hasLocalizedManyNumberField: boolean
hasLocalizedManyTextField: boolean
hasLocalizedRelationshipField: boolean
hasManyNumberField: 'index' | boolean
hasManyTextField: 'index' | boolean
relationsToBuild: RelationMap
@@ -81,6 +89,7 @@ export const buildTable = ({
tableName,
timestamps,
versions,
withinLocalizedArrayOrBlock,
}: Args): Result => {
const isRoot = !incomingRootTableName
const rootTableName = incomingRootTableName || tableName
@@ -128,6 +137,7 @@ export const buildTable = ({
rootTableIDColType: rootTableIDColType || idColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
// split the relationsToBuild by localized and non-localized
@@ -478,5 +488,12 @@ export const buildTable = ({
return result
})
return { hasManyNumberField, hasManyTextField, relationsToBuild }
return {
hasLocalizedManyNumberField,
hasLocalizedManyTextField,
hasLocalizedRelationshipField,
hasManyNumberField,
hasManyTextField,
relationsToBuild,
}
}

View File

@@ -52,6 +52,11 @@ type Args = {
rootTableIDColType: IDType
rootTableName: string
versions: boolean
/**
* Tracks whether or not this table is built
* from the result of a localized array or block field at some point
*/
withinLocalizedArrayOrBlock?: boolean
}
type Result = {
@@ -84,6 +89,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
}: Args): Result => {
let hasLocalizedField = false
let hasLocalizedRelationshipField = false
@@ -150,7 +156,11 @@ export const traverseFields = ({
switch (field.type) {
case 'text': {
if (field.hasMany) {
if (field.localized) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
hasLocalizedManyTextField = true
}
@@ -179,7 +189,11 @@ export const traverseFields = ({
case 'number': {
if (field.hasMany) {
if (field.localized) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
hasLocalizedManyNumberField = true
}
@@ -255,7 +269,11 @@ export const traverseFields = ({
parentIdx: (cols) => index(`${selectTableName}_parent_idx`).on(cols.parent),
}
if (field.localized) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
baseColumns.locale = text('locale', { enum: locales }).notNull()
baseExtraConfig.localeIdx = (cols) =>
index(`${selectTableName}_locale_idx`).on(cols.locale)
@@ -337,13 +355,20 @@ export const traverseFields = ({
_parentIDIdx: (cols) => index(`${arrayTableName}_parent_id_idx`).on(cols._parentID),
}
if (field.localized && adapter.payload.config.localization) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
baseColumns._locale = text('_locale', { enum: locales }).notNull()
baseExtraConfig._localeIdx = (cols) =>
index(`${arrayTableName}_locale_idx`).on(cols._locale)
}
const {
hasLocalizedManyNumberField: subHasLocalizedManyNumberField,
hasLocalizedManyTextField: subHasLocalizedManyTextField,
hasLocalizedRelationshipField: subHasLocalizedRelationshipField,
hasManyNumberField: subHasManyNumberField,
hasManyTextField: subHasManyTextField,
relationsToBuild: subRelationsToBuild,
@@ -360,8 +385,21 @@ export const traverseFields = ({
rootTableName,
tableName: arrayTableName,
versions,
withinLocalizedArrayOrBlock: isLocalized,
})
if (subHasLocalizedManyNumberField) {
hasLocalizedManyNumberField = subHasLocalizedManyNumberField
}
if (subHasLocalizedRelationshipField) {
hasLocalizedRelationshipField = subHasLocalizedRelationshipField
}
if (subHasLocalizedManyTextField) {
hasLocalizedManyTextField = subHasLocalizedManyTextField
}
if (subHasManyTextField) {
if (!hasManyTextField || subHasManyTextField === 'index')
hasManyTextField = subHasManyTextField
@@ -453,13 +491,20 @@ export const traverseFields = ({
_pathIdx: (cols) => index(`${blockTableName}_path_idx`).on(cols._path),
}
if (field.localized && adapter.payload.config.localization) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
baseColumns._locale = text('_locale', { enum: locales }).notNull()
baseExtraConfig._localeIdx = (cols) =>
index(`${blockTableName}_locale_idx`).on(cols._locale)
}
const {
hasLocalizedManyNumberField: subHasLocalizedManyNumberField,
hasLocalizedManyTextField: subHasLocalizedManyTextField,
hasLocalizedRelationshipField: subHasLocalizedRelationshipField,
hasManyNumberField: subHasManyNumberField,
hasManyTextField: subHasManyTextField,
relationsToBuild: subRelationsToBuild,
@@ -476,8 +521,21 @@ export const traverseFields = ({
rootTableName,
tableName: blockTableName,
versions,
withinLocalizedArrayOrBlock: isLocalized,
})
if (subHasLocalizedManyNumberField) {
hasLocalizedManyNumberField = subHasLocalizedManyNumberField
}
if (subHasLocalizedRelationshipField) {
hasLocalizedRelationshipField = subHasLocalizedRelationshipField
}
if (subHasLocalizedManyTextField) {
hasLocalizedManyTextField = subHasLocalizedManyTextField
}
if (subHasManyTextField) {
if (!hasManyTextField || subHasManyTextField === 'index')
hasManyTextField = subHasManyTextField
@@ -577,6 +635,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
if (groupHasLocalizedField) hasLocalizedField = true
@@ -618,6 +677,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
if (groupHasLocalizedField) hasLocalizedField = true
@@ -660,6 +720,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
if (tabHasLocalizedField) hasLocalizedField = true
@@ -702,6 +763,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
if (rowHasLocalizedField) hasLocalizedField = true
@@ -753,7 +815,10 @@ export const traverseFields = ({
}
break
}
if (adapter.payload.config.localization && field.localized) {
if (
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
) {
hasLocalizedRelationshipField = true
}

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/db-vercel-postgres",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"description": "Vercel Postgres adapter for Payload",
"homepage": "https://payloadcms.com",
"repository": {
@@ -40,6 +40,8 @@
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"clean": "rimraf {dist,*.tsbuildinfo}",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prepack": "pnpm clean && pnpm turbo build",
"prepublishOnly": "pnpm clean && pnpm turbo build",
"renamePredefinedMigrations": "node --no-deprecation --import @swc-node/register/esm-register ./scripts/renamePredefinedMigrations.ts"

View File

@@ -1,10 +0,0 @@
.tmp
**/.git
**/.hg
**/.pnp.*
**/.svn
**/.yarn/**
**/build
**/dist/**
**/node_modules
**/temp

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/drizzle",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"description": "A library of shared functions used by different payload database adapters",
"homepage": "https://payloadcms.com",
"repository": {
@@ -39,6 +39,8 @@
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"clean": "rimraf {dist,*.tsbuildinfo}",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prepack": "pnpm clean && pnpm turbo build",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},

View File

@@ -12,11 +12,11 @@ type BuildFindQueryArgs = {
tableName: string
}
export type Result = DBQueryConfig<'many', true, any, any> & {
with?: DBQueryConfig<'many', true, any, any> & {
export type Result = {
with?: {
_locales?: DBQueryConfig<'many', true, any, any>
}
}
} & DBQueryConfig<'many', true, any, any>
} & DBQueryConfig<'many', true, any, any>
// Generate the Drizzle query for findMany based on
// a collection field structure

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-restricted-syntax, no-await-in-loop */
import type { PayloadRequest } from 'payload'
import {

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-restricted-syntax, no-await-in-loop */
import type { PayloadRequest } from 'payload'
import {

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-restricted-syntax, no-await-in-loop */
import type { PayloadRequest } from 'payload'
import {

View File

@@ -30,7 +30,7 @@ export async function migrateStatus(this: DrizzleAdapter): Promise<void> {
const existingMigration = existingMigrations.find((m) => m.name === migration.name)
return {
Name: migration.name,
// eslint-disable-next-line perfectionist/sort-objects
Batch: existingMigration?.batch,
Ran: existingMigration ? 'Yes' : 'No',
}

View File

@@ -54,9 +54,17 @@ type Args = {
tableName: string
timestamps?: boolean
versions: boolean
/**
* Tracks whether or not this table is built
* from the result of a localized array or block field at some point
*/
withinLocalizedArrayOrBlock?: boolean
}
type Result = {
hasLocalizedManyNumberField: boolean
hasLocalizedManyTextField: boolean
hasLocalizedRelationshipField: boolean
hasManyNumberField: 'index' | boolean
hasManyTextField: 'index' | boolean
relationsToBuild: RelationMap
@@ -76,6 +84,7 @@ export const buildTable = ({
tableName,
timestamps,
versions,
withinLocalizedArrayOrBlock,
}: Args): Result => {
const isRoot = !incomingRootTableName
const rootTableName = incomingRootTableName || tableName
@@ -122,6 +131,7 @@ export const buildTable = ({
rootTableIDColType: rootTableIDColType || idColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
// split the relationsToBuild by localized and non-localized
@@ -464,5 +474,12 @@ export const buildTable = ({
return result
})
return { hasManyNumberField, hasManyTextField, relationsToBuild }
return {
hasLocalizedManyNumberField,
hasLocalizedManyTextField,
hasLocalizedRelationshipField,
hasManyNumberField,
hasManyTextField,
relationsToBuild,
}
}

View File

@@ -58,6 +58,11 @@ type Args = {
rootTableIDColType: string
rootTableName: string
versions: boolean
/**
* Tracks whether or not this table is built
* from the result of a localized array or block field at some point
*/
withinLocalizedArrayOrBlock?: boolean
}
type Result = {
@@ -89,6 +94,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
}: Args): Result => {
const throwValidationError = true
let hasLocalizedField = false
@@ -156,7 +162,11 @@ export const traverseFields = ({
switch (field.type) {
case 'text': {
if (field.hasMany) {
if (field.localized) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
hasLocalizedManyTextField = true
}
@@ -185,7 +195,11 @@ export const traverseFields = ({
case 'number': {
if (field.hasMany) {
if (field.localized) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
hasLocalizedManyNumberField = true
}
@@ -276,7 +290,11 @@ export const traverseFields = ({
parentIdx: (cols) => index(`${selectTableName}_parent_idx`).on(cols.parent),
}
if (field.localized) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
baseColumns.locale = adapter.enums.enum__locales('locale').notNull()
baseExtraConfig.localeIdx = (cols) =>
index(`${selectTableName}_locale_idx`).on(cols.locale)
@@ -354,13 +372,20 @@ export const traverseFields = ({
_parentIDIdx: (cols) => index(`${arrayTableName}_parent_id_idx`).on(cols._parentID),
}
if (field.localized && adapter.payload.config.localization) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
baseColumns._locale = adapter.enums.enum__locales('_locale').notNull()
baseExtraConfig._localeIdx = (cols) =>
index(`${arrayTableName}_locale_idx`).on(cols._locale)
}
const {
hasLocalizedManyNumberField: subHasLocalizedManyNumberField,
hasLocalizedManyTextField: subHasLocalizedManyTextField,
hasLocalizedRelationshipField: subHasLocalizedRelationshipField,
hasManyNumberField: subHasManyNumberField,
hasManyTextField: subHasManyTextField,
relationsToBuild: subRelationsToBuild,
@@ -377,8 +402,21 @@ export const traverseFields = ({
rootTableName,
tableName: arrayTableName,
versions,
withinLocalizedArrayOrBlock: isLocalized,
})
if (subHasLocalizedManyNumberField) {
hasLocalizedManyNumberField = subHasLocalizedManyNumberField
}
if (subHasLocalizedRelationshipField) {
hasLocalizedRelationshipField = subHasLocalizedRelationshipField
}
if (subHasLocalizedManyTextField) {
hasLocalizedManyTextField = subHasLocalizedManyTextField
}
if (subHasManyTextField) {
if (!hasManyTextField || subHasManyTextField === 'index')
hasManyTextField = subHasManyTextField
@@ -466,13 +504,20 @@ export const traverseFields = ({
_pathIdx: (cols) => index(`${blockTableName}_path_idx`).on(cols._path),
}
if (field.localized && adapter.payload.config.localization) {
const isLocalized =
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
if (isLocalized) {
baseColumns._locale = adapter.enums.enum__locales('_locale').notNull()
baseExtraConfig._localeIdx = (cols) =>
index(`${blockTableName}_locale_idx`).on(cols._locale)
}
const {
hasLocalizedManyNumberField: subHasLocalizedManyNumberField,
hasLocalizedManyTextField: subHasLocalizedManyTextField,
hasLocalizedRelationshipField: subHasLocalizedRelationshipField,
hasManyNumberField: subHasManyNumberField,
hasManyTextField: subHasManyTextField,
relationsToBuild: subRelationsToBuild,
@@ -489,8 +534,21 @@ export const traverseFields = ({
rootTableName,
tableName: blockTableName,
versions,
withinLocalizedArrayOrBlock: isLocalized,
})
if (subHasLocalizedManyNumberField) {
hasLocalizedManyNumberField = subHasLocalizedManyNumberField
}
if (subHasLocalizedRelationshipField) {
hasLocalizedRelationshipField = subHasLocalizedRelationshipField
}
if (subHasLocalizedManyTextField) {
hasLocalizedManyTextField = subHasLocalizedManyTextField
}
if (subHasManyTextField) {
if (!hasManyTextField || subHasManyTextField === 'index')
hasManyTextField = subHasManyTextField
@@ -589,6 +647,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
if (groupHasLocalizedField) hasLocalizedField = true
@@ -629,6 +688,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
if (groupHasLocalizedField) hasLocalizedField = true
@@ -670,6 +730,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
if (tabHasLocalizedField) hasLocalizedField = true
@@ -711,6 +772,7 @@ export const traverseFields = ({
rootTableIDColType,
rootTableName,
versions,
withinLocalizedArrayOrBlock,
})
if (rowHasLocalizedField) hasLocalizedField = true
@@ -761,7 +823,11 @@ export const traverseFields = ({
}
break
}
if (adapter.payload.config.localization && field.localized) {
if (
Boolean(field.localized && adapter.payload.config.localization) ||
withinLocalizedArrayOrBlock
) {
hasLocalizedRelationshipField = true
}

View File

@@ -28,11 +28,10 @@ export async function buildAndOrConditions({
const completedConditions = []
// Loop over all AND / OR operations and add them to the AND / OR query param
// Operations should come through as an array
// eslint-disable-next-line no-restricted-syntax
for (const condition of where) {
// If the operation is properly formatted as an object
if (typeof condition === 'object') {
// eslint-disable-next-line no-await-in-loop
const result = await parseParams({
adapter,
fields,

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-await-in-loop */
import type { SQL } from 'drizzle-orm'
import type { Field, Operator, Where } from 'payload'

View File

@@ -5,6 +5,7 @@ import type { ChainedMethods } from '../find/chainMethods.js'
import type {
DrizzleAdapter,
DrizzleTransaction,
GenericColumn,
GenericPgColumn,
TransactionPg,
TransactionSQLite,
@@ -12,7 +13,6 @@ import type {
import type { BuildQueryJoinAliases } from './buildQuery.js'
import { chainMethods } from '../find/chainMethods.js'
import { type GenericColumn } from '../types.js'
type Args = {
adapter: DrizzleAdapter
@@ -35,7 +35,7 @@ export const selectDistinct = ({
selectFields,
tableName,
where,
}: Args): QueryPromise<Record<string, GenericColumn> & { id: number | string }[]> => {
}: Args): QueryPromise<{ id: number | string }[] & Record<string, GenericColumn>> => {
if (Object.keys(joins).length > 0) {
if (where) {
chainedMethods.push({ args: [where], method: 'where' })

View File

@@ -35,7 +35,6 @@ export const queryDrafts: QueryDrafts = async function queryDrafts(
return {
...result,
docs: result.docs.map((doc) => {
// eslint-disable-next-line no-param-reassign
doc = {
id: doc.parent,
...doc.version,

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
import type { NumberField } from 'payload'
type Args = {
@@ -6,10 +5,29 @@ type Args = {
locale?: string
numberRows: Record<string, unknown>[]
ref: Record<string, unknown>
withinArrayOrBlockLocale?: string
}
export const transformHasManyNumber = ({ field, locale, numberRows, ref }: Args) => {
const result = numberRows.map(({ number }) => number)
export const transformHasManyNumber = ({
field,
locale,
numberRows,
ref,
withinArrayOrBlockLocale,
}: Args) => {
let result: unknown[]
if (withinArrayOrBlockLocale) {
result = numberRows.reduce((acc, { locale, number }) => {
if (locale === withinArrayOrBlockLocale) {
acc.push(number)
}
return acc
}, [])
} else {
result = numberRows.map(({ number }) => number)
}
if (locale) {
ref[field.name][locale] = result

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
import type { TextField } from 'payload'
type Args = {
@@ -6,10 +5,29 @@ type Args = {
locale?: string
ref: Record<string, unknown>
textRows: Record<string, unknown>[]
withinArrayOrBlockLocale?: string
}
export const transformHasManyText = ({ field, locale, ref, textRows }: Args) => {
const result = textRows.map(({ text }) => text)
export const transformHasManyText = ({
field,
locale,
ref,
textRows,
withinArrayOrBlockLocale,
}: Args) => {
let result: unknown[]
if (withinArrayOrBlockLocale) {
result = textRows.reduce((acc, { locale, text }) => {
if (locale === withinArrayOrBlockLocale) {
acc.push(text)
}
return acc
}, [])
} else {
result = textRows.map(({ text }) => text)
}
if (locale) {
ref[field.name][locale] = result

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
import type { Field, SanitizedConfig, TypeWithID } from 'payload'
import type { DrizzleAdapter } from '../../types.js'

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
import type { RelationshipField, UploadField } from 'payload'
type Args = {
@@ -6,21 +5,31 @@ type Args = {
locale?: string
ref: Record<string, unknown>
relations: Record<string, unknown>[]
withinArrayOrBlockLocale?: string
}
export const transformRelationship = ({ field, locale, ref, relations }: Args) => {
export const transformRelationship = ({
field,
locale,
ref,
relations,
withinArrayOrBlockLocale,
}: Args) => {
let result: unknown
if (!('hasMany' in field) || field.hasMany === false) {
const relation = relations[0]
let relation = relations[0]
if (withinArrayOrBlockLocale) {
relation = relations.find((rel) => rel.locale === withinArrayOrBlockLocale)
}
if (relation) {
// Handle hasOne Poly
if (Array.isArray(field.relationTo)) {
const matchedRelation = Object.entries(relation).find(
([key, val]) =>
val !== null && !['id', 'locale', 'order', 'parent', 'path'].includes(key),
)
const matchedRelation = Object.entries(relation).find(([key, val]) => {
return val !== null && !['id', 'locale', 'order', 'parent', 'path'].includes(key)
})
if (matchedRelation) {
const relationTo = matchedRelation[0].replace('ID', '')
@@ -36,18 +45,26 @@ export const transformRelationship = ({ field, locale, ref, relations }: Args) =
const transformedRelations = []
relations.forEach((relation) => {
let matchedLocale = true
if (withinArrayOrBlockLocale) {
matchedLocale = relation.locale === withinArrayOrBlockLocale
}
// Handle hasMany
if (!Array.isArray(field.relationTo)) {
const relatedData = relation[`${field.relationTo}ID`]
if (relatedData) {
if (relatedData && matchedLocale) {
transformedRelations.push(relatedData)
}
} else {
// Handle hasMany Poly
const matchedRelation = Object.entries(relation).find(
([key, val]) =>
val !== null && !['id', 'locale', 'order', 'parent', 'path'].includes(key),
val !== null &&
!['id', 'locale', 'order', 'parent', 'path'].includes(key) &&
matchedLocale,
)
if (matchedRelation) {

View File

@@ -58,6 +58,10 @@ type TraverseFieldsArgs = {
* All hasMany text fields, as returned by Drizzle, keyed on an object by field path
*/
texts: Record<string, Record<string, unknown>[]>
/**
* Set to a locale if this group of fields is within a localized array or block.
*/
withinArrayOrBlockLocale?: string
}
// Traverse fields recursively, transforming data
@@ -75,6 +79,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
relationships,
table,
texts,
withinArrayOrBlockLocale,
}: TraverseFieldsArgs): T => {
const sanitizedPath = path ? `${path}.` : path
@@ -93,6 +98,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
relationships,
table,
texts,
withinArrayOrBlockLocale,
})
}
@@ -114,6 +120,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
relationships,
table,
texts,
withinArrayOrBlockLocale,
})
}
@@ -157,6 +164,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
relationships,
table: row,
texts,
withinArrayOrBlockLocale: locale,
})
if ('_order' in rowResult) {
@@ -169,7 +177,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
return arrayResult
}, {})
} else {
result[field.name] = fieldData.map((row, i) => {
result[field.name] = fieldData.reduce((acc, row, i) => {
if (row._uuid) {
row.id = row._uuid
delete row._uuid
@@ -179,21 +187,35 @@ export const traverseFields = <T extends Record<string, unknown>>({
delete row._order
}
return traverseFields<T>({
adapter,
blocks,
config,
dataRef: row,
deletions,
fieldPrefix: '',
fields: field.fields,
numbers,
path: `${sanitizedPath}${field.name}.${i}`,
relationships,
table: row,
texts,
})
})
if (
!withinArrayOrBlockLocale ||
(withinArrayOrBlockLocale && withinArrayOrBlockLocale === row._locale)
) {
if (row._locale) {
delete row._locale
}
acc.push(
traverseFields<T>({
adapter,
blocks,
config,
dataRef: row,
deletions,
fieldPrefix: '',
fields: field.fields,
numbers,
path: `${sanitizedPath}${field.name}.${i}`,
relationships,
table: row,
texts,
withinArrayOrBlockLocale,
}),
)
}
return acc
}, [])
}
}
@@ -237,6 +259,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
relationships,
table: row,
texts,
withinArrayOrBlockLocale: locale,
})
delete blockResult._order
@@ -247,7 +270,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
})
})
} else {
result[field.name] = blocks[blockFieldPath].map((row, i) => {
result[field.name] = blocks[blockFieldPath].reduce((acc, row, i) => {
delete row._order
if (row._uuid) {
row.id = row._uuid
@@ -256,24 +279,40 @@ export const traverseFields = <T extends Record<string, unknown>>({
const block = field.blocks.find(({ slug }) => slug === row.blockType)
if (block) {
return traverseFields<T>({
adapter,
blocks,
config,
dataRef: row,
deletions,
fieldPrefix: '',
fields: block.fields,
numbers,
path: `${blockFieldPath}.${i}`,
relationships,
table: row,
texts,
})
if (
!withinArrayOrBlockLocale ||
(withinArrayOrBlockLocale && withinArrayOrBlockLocale === row._locale)
) {
if (row._locale) {
delete row._locale
}
acc.push(
traverseFields<T>({
adapter,
blocks,
config,
dataRef: row,
deletions,
fieldPrefix: '',
fields: block.fields,
numbers,
path: `${blockFieldPath}.${i}`,
relationships,
table: row,
texts,
withinArrayOrBlockLocale,
}),
)
return acc
}
} else {
acc.push({})
}
return {}
})
return acc
}, [])
}
}
@@ -334,6 +373,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
field,
ref: result,
relations: relationPathMatch,
withinArrayOrBlockLocale,
})
}
return result
@@ -368,6 +408,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
field,
ref: result,
textRows: textPathMatch,
withinArrayOrBlockLocale,
})
}
@@ -402,6 +443,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
field,
numberRows: numberPathMatch,
ref: result,
withinArrayOrBlockLocale,
})
}
@@ -466,6 +508,7 @@ export const traverseFields = <T extends Record<string, unknown>>({
relationships,
table,
texts,
withinArrayOrBlockLocale,
})
if ('_order' in ref) {

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
import type { ArrayField } from 'payload'
import type { DrizzleAdapter } from '../../types.js'
@@ -26,6 +25,11 @@ type Args = {
[tableName: string]: Record<string, unknown>[]
}
texts: Record<string, unknown>[]
/**
* Set to a locale code if this set of fields is traversed within a
* localized array or block field
*/
withinArrayOrBlockLocale?: string
}
export const transformArray = ({
@@ -43,6 +47,7 @@ export const transformArray = ({
relationshipsToDelete,
selects,
texts,
withinArrayOrBlockLocale,
}: Args) => {
const newRows: ArrayRowToInsert[] = []
@@ -78,6 +83,10 @@ export const transformArray = ({
newRow.row._locale = locale
}
if (withinArrayOrBlockLocale) {
newRow.row._locale = withinArrayOrBlockLocale
}
traverseFields({
adapter,
arrays: newRow.arrays,
@@ -97,6 +106,7 @@ export const transformArray = ({
row: newRow.row,
selects,
texts,
withinArrayOrBlockLocale,
})
newRows.push(newRow)

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
import type { BlockField } from 'payload'
import toSnakeCase from 'to-snake-case'
@@ -26,6 +25,11 @@ type Args = {
[tableName: string]: Record<string, unknown>[]
}
texts: Record<string, unknown>[]
/**
* Set to a locale code if this set of fields is traversed within a
* localized array or block field
*/
withinArrayOrBlockLocale?: string
}
export const transformBlocks = ({
adapter,
@@ -41,6 +45,7 @@ export const transformBlocks = ({
relationshipsToDelete,
selects,
texts,
withinArrayOrBlockLocale,
}: Args) => {
data.forEach((blockRow, i) => {
if (typeof blockRow.blockType !== 'string') return
@@ -60,6 +65,7 @@ export const transformBlocks = ({
}
if (field.localized && locale) newRow.row._locale = locale
if (withinArrayOrBlockLocale) newRow.row._locale = withinArrayOrBlockLocale
const blockTableName = adapter.tableNameMap.get(`${baseTableName}_blocks_${blockType}`)
@@ -94,6 +100,7 @@ export const transformBlocks = ({
row: newRow.row,
selects,
texts,
withinArrayOrBlockLocale,
})
blocks[blockType].push(newRow)

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
import type { Field } from 'payload'
import type { DrizzleAdapter } from '../../types.js'

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
import { isArrayOfRows } from '../../utilities/isArrayOfRows.js'
type Args = {

View File

@@ -57,6 +57,11 @@ type Args = {
[tableName: string]: Record<string, unknown>[]
}
texts: Record<string, unknown>[]
/**
* Set to a locale code if this set of fields is traversed within a
* localized array or block field
*/
withinArrayOrBlockLocale?: string
}
export const traverseFields = ({
@@ -80,6 +85,7 @@ export const traverseFields = ({
row,
selects,
texts,
withinArrayOrBlockLocale,
}: Args) => {
fields.forEach((field) => {
let columnName = ''
@@ -116,6 +122,7 @@ export const traverseFields = ({
relationshipsToDelete,
selects,
texts,
withinArrayOrBlockLocale: localeKey,
})
arrays[arrayTableName] = arrays[arrayTableName].concat(newRows)
@@ -137,6 +144,7 @@ export const traverseFields = ({
relationshipsToDelete,
selects,
texts,
withinArrayOrBlockLocale,
})
arrays[arrayTableName] = arrays[arrayTableName].concat(newRows)
@@ -168,6 +176,7 @@ export const traverseFields = ({
relationshipsToDelete,
selects,
texts,
withinArrayOrBlockLocale: localeKey,
})
}
})
@@ -186,6 +195,7 @@ export const traverseFields = ({
relationshipsToDelete,
selects,
texts,
withinArrayOrBlockLocale,
})
}
@@ -217,6 +227,7 @@ export const traverseFields = ({
row,
selects,
texts,
withinArrayOrBlockLocale: localeKey,
})
})
} else {
@@ -240,6 +251,7 @@ export const traverseFields = ({
row,
selects,
texts,
withinArrayOrBlockLocale,
})
}
}
@@ -274,6 +286,7 @@ export const traverseFields = ({
row,
selects,
texts,
withinArrayOrBlockLocale: localeKey,
})
})
} else {
@@ -297,6 +310,7 @@ export const traverseFields = ({
row,
selects,
texts,
withinArrayOrBlockLocale,
})
}
}
@@ -321,6 +335,7 @@ export const traverseFields = ({
row,
selects,
texts,
withinArrayOrBlockLocale,
})
}
})
@@ -347,6 +362,7 @@ export const traverseFields = ({
row,
selects,
texts,
withinArrayOrBlockLocale,
})
}
@@ -387,6 +403,7 @@ export const traverseFields = ({
transformRelationship({
baseRow: {
locale: withinArrayOrBlockLocale,
path: relationshipPath,
},
data: fieldData,
@@ -440,6 +457,7 @@ export const traverseFields = ({
} else if (Array.isArray(fieldData)) {
transformTexts({
baseRow: {
locale: withinArrayOrBlockLocale,
path: textPath,
},
data: fieldData,
@@ -471,6 +489,7 @@ export const traverseFields = ({
} else if (Array.isArray(fieldData)) {
transformNumbers({
baseRow: {
locale: withinArrayOrBlockLocale,
path: numberPath,
},
data: fieldData,
@@ -503,6 +522,7 @@ export const traverseFields = ({
const newRows = transformSelects({
id: data._uuid || data.id,
data: data[field.name],
locale: withinArrayOrBlockLocale,
})
selects[selectTableName] = selects[selectTableName].concat(newRows)

View File

@@ -348,20 +348,52 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
// Error Handling
// //////////////////////////////////
} catch (error) {
throw error.code === '23505'
? new ValidationError(
{
id,
errors: [
{
field: adapter.fieldConstraints[tableName][error.constraint],
message: req.t('error:valueMustBeUnique'),
},
],
},
req.t,
)
: error
if (error.code === '23505') {
let fieldName: null | string = null
// We need to try and find the right constraint for the field but if we can't we fallback to a generic message
if (adapter.fieldConstraints?.[tableName]) {
if (adapter.fieldConstraints[tableName]?.[error.constraint]) {
fieldName = adapter.fieldConstraints[tableName]?.[error.constraint]
} else {
const replacement = `${tableName}_`
if (error.constraint.includes(replacement)) {
const replacedConstraint = error.constraint.replace(replacement, '')
if (replacedConstraint && adapter.fieldConstraints[tableName]?.[replacedConstraint])
fieldName = adapter.fieldConstraints[tableName][replacedConstraint]
}
}
}
if (!fieldName) {
// Last case scenario we extract the key and value from the detail on the error
const detail = error.detail
const regex = /Key \(([^)]+)\)=\(([^)]+)\)/
const match = detail.match(regex)
if (match) {
const key = match[1]
fieldName = key
}
}
throw new ValidationError(
{
id,
errors: [
{
field: fieldName,
message: req.t('error:valueMustBeUnique'),
},
],
},
req.t,
)
} else {
throw error
}
}
if (ignoreResult) return data as T

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
import type { ArrayRowToInsert } from '../transform/write/types.js'
import type { DrizzleAdapter, DrizzleTransaction } from '../types.js'

View File

@@ -18,18 +18,18 @@ type BaseArgs = {
tableName: string
}
type CreateArgs = BaseArgs & {
type CreateArgs = {
id?: never
operation: 'create'
upsertTarget?: never
where?: never
}
} & BaseArgs
type UpdateArgs = BaseArgs & {
type UpdateArgs = {
id?: number | string
operation: 'update'
upsertTarget?: GenericColumn
where?: SQL<unknown>
}
} & BaseArgs
export type Args = CreateArgs | UpdateArgs

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-param-reassign */
export type BlocksMap = {
[path: string]: Record<string, unknown>[]
}

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/email-nodemailer",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"description": "Payload Nodemailer Email Adapter",
"homepage": "https://payloadcms.com",
"repository": {
@@ -29,6 +29,8 @@
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"clean": "rimraf {dist,*.tsbuildinfo}",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},
"dependencies": {

View File

@@ -47,7 +47,9 @@ async function buildEmail(emailConfig?: NodemailerAdapterArgs): Promise<{
}> {
if (!emailConfig) {
const transport = await createMockAccount(emailConfig)
if (!transport) throw new InvalidConfiguration('Unable to create Nodemailer test account.')
if (!transport) {
throw new InvalidConfiguration('Unable to create Nodemailer test account.')
}
return {
defaultFromAddress: 'info@payloadcms.com',

View File

@@ -1,7 +1,11 @@
import { jest } from '@jest/globals'
import type { Transporter } from 'nodemailer'
import nodemailer, { Transporter } from 'nodemailer'
import { nodemailerAdapter, NodemailerAdapterArgs } from './index.js'
import { jest } from '@jest/globals'
import nodemailer from 'nodemailer'
import type { NodemailerAdapterArgs } from './index.js'
import { nodemailerAdapter } from './index.js'
const defaultArgs: NodemailerAdapterArgs = {
defaultFromAddress: 'test@test.com',
@@ -9,7 +13,6 @@ const defaultArgs: NodemailerAdapterArgs = {
}
describe('email-nodemailer', () => {
describe('transport verification', () => {
let mockedVerify: jest.Mock<Transporter['verify']>
let mockTransport: Transporter
@@ -18,20 +21,21 @@ describe('email-nodemailer', () => {
mockedVerify = jest.fn<Transporter['verify']>()
mockTransport = nodemailer.createTransport({
name: 'existing-transport',
// eslint-disable-next-line @typescript-eslint/require-await
// eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-misused-promises
send: async (mail) => {
// eslint-disable-next-line no-console
console.log('mock send', mail)
},
version: '0.0.1',
verify: mockedVerify,
version: '0.0.1',
})
})
it('should be invoked when skipVerify = false', async () => {
await nodemailerAdapter({
...defaultArgs,
transport: mockTransport,
skipVerify: false,
transport: mockTransport,
})
expect(mockedVerify.mock.calls).toHaveLength(1)
@@ -40,8 +44,8 @@ describe('email-nodemailer', () => {
it('should be invoked when skipVerify is undefined', async () => {
await nodemailerAdapter({
...defaultArgs,
transport: mockTransport,
skipVerify: false,
transport: mockTransport,
})
expect(mockedVerify.mock.calls).toHaveLength(1)
@@ -50,8 +54,8 @@ describe('email-nodemailer', () => {
it('should not be invoked when skipVerify = true', async () => {
await nodemailerAdapter({
...defaultArgs,
transport: mockTransport,
skipVerify: true,
transport: mockTransport,
})
expect(mockedVerify.mock.calls).toHaveLength(0)

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/email-resend",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"description": "Payload Resend Email Adapter",
"homepage": "https://payloadcms.com",
"repository": {
@@ -28,6 +28,8 @@
"build:swc": "swc ./src -d ./dist --config-file .swcrc-build --strip-leading-paths",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"clean": "rimraf {dist,*.tsbuildinfo}",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prepublishOnly": "pnpm clean && pnpm turbo build",
"test": "jest"
},

View File

@@ -14,6 +14,7 @@ import { deepMerge } from './deepMerge.js'
const baseRules = {
// This rule makes no sense when overriding class methods. This is used a lot in richtext-lexical.
'class-methods-use-this': 'off',
curly: ['warn', 'all'],
'arrow-body-style': 0,
'import-x/prefer-default-export': 'off',
'no-restricted-exports': ['warn', { restrictDefaultExports: { direct: true } }],

View File

@@ -1,6 +1,6 @@
{
"name": "@payloadcms/graphql",
"version": "3.0.0-beta.91",
"version": "3.0.0-beta.96",
"homepage": "https://payloadcms.com",
"repository": {
"type": "git",
@@ -38,6 +38,8 @@
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
"build:types": "tsc --emitDeclarationOnly --outDir dist",
"clean": "rimraf {dist,*.tsbuildinfo}",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prepublishOnly": "pnpm clean && pnpm turbo build"
},
"dependencies": {

View File

@@ -8,12 +8,12 @@ import {
fieldExtensionsEstimator,
simpleEstimator,
} from './packages/graphql-query-complexity/index.js'
import accessResolver from './resolvers/auth/access.js'
import buildFallbackLocaleInputType from './schema/buildFallbackLocaleInputType.js'
import buildLocaleInputType from './schema/buildLocaleInputType.js'
import buildPoliciesType from './schema/buildPoliciesType.js'
import initCollections from './schema/initCollections.js'
import initGlobals from './schema/initGlobals.js'
import { accessResolver } from './resolvers/auth/access.js'
import { buildFallbackLocaleInputType } from './schema/buildFallbackLocaleInputType.js'
import { buildLocaleInputType } from './schema/buildLocaleInputType.js'
import { buildPoliciesType } from './schema/buildPoliciesType.js'
import { initCollections } from './schema/initCollections.js'
import { initGlobals } from './schema/initGlobals.js'
import { wrapCustomFields } from './utilities/wrapCustomResolver.js'
export function configToSchema(config: SanitizedConfig): {

View File

@@ -122,7 +122,7 @@ export function getComplexity(options: {
return visitor.complexity
}
export default class QueryComplexity {
export class QueryComplexity {
OperationDefinition: Record<string, any>
complexity: number
context: ValidationContext

View File

@@ -2,7 +2,7 @@ import type { ValidationContext } from 'graphql'
import type { QueryComplexityOptions } from './QueryComplexity.js'
import QueryComplexity from './QueryComplexity.js'
import { QueryComplexity } from './QueryComplexity.js'
export function createComplexityRule(
options: QueryComplexityOptions,

View File

@@ -4,7 +4,7 @@ import { accessOperation, isolateObjectProperty } from 'payload'
import type { Context } from '../types.js'
import formatName from '../../utilities/formatName.js'
import { formatName } from '../../utilities/formatName.js'
const formatConfigNames = (results, configs) => {
const formattedResults = { ...results }
@@ -17,7 +17,7 @@ const formatConfigNames = (results, configs) => {
return formattedResults
}
function accessResolver(config: SanitizedConfig) {
export function accessResolver(config: SanitizedConfig) {
async function resolver(_, args, context: Context) {
const options = {
req: isolateObjectProperty<any>(context.req, 'transactionID'),
@@ -34,5 +34,3 @@ function accessResolver(config: SanitizedConfig) {
return resolver
}
export default accessResolver

View File

@@ -4,7 +4,7 @@ import { forgotPasswordOperation, isolateObjectProperty } from 'payload'
import type { Context } from '../types.js'
function forgotPasswordResolver(collection: Collection): any {
export function forgotPassword(collection: Collection): any {
async function resolver(_, args, context: Context) {
const options = {
collection,
@@ -23,5 +23,3 @@ function forgotPasswordResolver(collection: Collection): any {
return resolver
}
export default forgotPasswordResolver

View File

@@ -2,7 +2,7 @@ import { initOperation, isolateObjectProperty } from 'payload'
import type { Context } from '../types.js'
function initResolver(collection: string) {
export function init(collection: string) {
async function resolver(_, args, context: Context) {
const options = {
collection,
@@ -14,5 +14,3 @@ function initResolver(collection: string) {
return resolver
}
export default initResolver

View File

@@ -4,7 +4,7 @@ import { generatePayloadCookie, isolateObjectProperty, loginOperation } from 'pa
import type { Context } from '../types.js'
function loginResolver(collection: Collection): any {
export function login(collection: Collection): any {
async function resolver(_, args, context: Context) {
const options = {
collection,
@@ -35,5 +35,3 @@ function loginResolver(collection: Collection): any {
return resolver
}
export default loginResolver

View File

@@ -4,7 +4,7 @@ import { generateExpiredPayloadCookie, isolateObjectProperty, logoutOperation }
import type { Context } from '../types.js'
function logoutResolver(collection: Collection): any {
export function logout(collection: Collection): any {
async function resolver(_, args, context: Context) {
const options = {
collection,
@@ -22,5 +22,3 @@ function logoutResolver(collection: Collection): any {
return resolver
}
export default logoutResolver

View File

@@ -4,7 +4,7 @@ import { extractJWT, isolateObjectProperty, meOperation } from 'payload'
import type { Context } from '../types.js'
function meResolver(collection: Collection): any {
export function me(collection: Collection): any {
async function resolver(_, args, context: Context) {
const currentToken = extractJWT(context.req)
@@ -26,5 +26,3 @@ function meResolver(collection: Collection): any {
return resolver
}
export default meResolver

View File

@@ -4,7 +4,7 @@ import { generatePayloadCookie, isolateObjectProperty, refreshOperation } from '
import type { Context } from '../types.js'
function refreshResolver(collection: Collection): any {
export function refresh(collection: Collection): any {
async function resolver(_, __, context: Context) {
const options = {
collection,
@@ -29,5 +29,3 @@ function refreshResolver(collection: Collection): any {
return resolver
}
export default refreshResolver

View File

@@ -4,10 +4,14 @@ import { generatePayloadCookie, isolateObjectProperty, resetPasswordOperation }
import type { Context } from '../types.js'
function resetPasswordResolver(collection: Collection): any {
export function resetPassword(collection: Collection): any {
async function resolver(_, args, context: Context) {
if (args.locale) context.req.locale = args.locale
if (args.fallbackLocale) context.req.fallbackLocale = args.fallbackLocale
if (args.locale) {
context.req.locale = args.locale
}
if (args.fallbackLocale) {
context.req.fallbackLocale = args.fallbackLocale
}
const options = {
api: 'GraphQL',
@@ -34,5 +38,3 @@ function resetPasswordResolver(collection: Collection): any {
return resolver
}
export default resetPasswordResolver

View File

@@ -4,7 +4,7 @@ import { isolateObjectProperty, unlockOperation } from 'payload'
import type { Context } from '../types.js'
function unlockResolver(collection: Collection) {
export function unlock(collection: Collection) {
async function resolver(_, args, context: Context) {
const options = {
collection,
@@ -18,5 +18,3 @@ function unlockResolver(collection: Collection) {
return resolver
}
export default unlockResolver

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