diff --git a/package.json b/package.json index 8bbca1fb5..eeb4d13d3 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "@types/fs-extra": "^11.0.2", "@types/jest": "29.5.12", "@types/minimist": "1.2.2", - "@types/node": "20.5.7", + "@types/node": "20.11.28", "@types/prompts": "^2.4.5", "@types/qs": "6.9.7", "@types/react": "18.2.15", diff --git a/packages/next/src/views/Edit/Default/Auth/APIKey.tsx b/packages/next/src/views/Edit/Default/Auth/APIKey.tsx index 133e549eb..f84a5b0ea 100644 --- a/packages/next/src/views/Edit/Default/Auth/APIKey.tsx +++ b/packages/next/src/views/Edit/Default/Auth/APIKey.tsx @@ -6,6 +6,7 @@ import { GenerateConfirmation, Label, fieldBaseClass, + useConfig, useField, useFormFields, useTranslation, @@ -21,6 +22,7 @@ const APIKey: React.FC<{ readOnly?: boolean }> = ({ readOnly }) => { const [initialAPIKey, setInitialAPIKey] = useState(null) const [highlightedField, setHighlightedField] = useState(false) const { t } = useTranslation() + const config = useConfig() const apiKey = useFormFields(([fields]) => fields[path]) @@ -31,7 +33,12 @@ const APIKey: React.FC<{ readOnly?: boolean }> = ({ readOnly }) => { data: {}, maxLength: 48, minLength: 24, - req: { t } as PayloadRequest, + req: { + payload: { + config, + }, + t, + } as PayloadRequest, siblingData: {}, }) diff --git a/packages/next/src/views/Edit/Default/index.tsx b/packages/next/src/views/Edit/Default/index.tsx index 7ccab1e05..b9a995826 100644 --- a/packages/next/src/views/Edit/Default/index.tsx +++ b/packages/next/src/views/Edit/Default/index.tsx @@ -66,6 +66,7 @@ export const DefaultEditView: React.FC = () => { const { reportUpdate } = useDocumentEvents() const { + admin: { user: userSlug }, collections, globals, routes: { admin: adminRoute, api: apiRoute }, @@ -108,9 +109,9 @@ export const DefaultEditView: React.FC = () => { updatedAt: json?.result?.updatedAt || new Date().toISOString(), }) - // If we're editing the doc of the logged in user, + // If we're editing the doc of the logged-in user, // Refresh the cookie to get new permissions - if (user && collectionSlug === user?.collection && id === user?.id) { + if (user && collectionSlug === userSlug && id === user.id) { void refreshCookieAsync() } @@ -135,8 +136,7 @@ export const DefaultEditView: React.FC = () => { id, entitySlug, collectionSlug, - user?.collection, - user?.id, + user, getVersions, getDocPermissions, isEditing, diff --git a/packages/payload/src/auth/operations/me.ts b/packages/payload/src/auth/operations/me.ts index 2681927e1..727cf80cb 100644 --- a/packages/payload/src/auth/operations/me.ts +++ b/packages/payload/src/auth/operations/me.ts @@ -2,13 +2,13 @@ import jwt from 'jsonwebtoken' import type { Collection } from '../../collections/config/types.js' import type { PayloadRequest } from '../../types/index.js' -import type { User } from '../types.js' +import type { ClientUser, User } from '../types.js' -export type Result = { +export type MeOperationResult = { collection?: string exp?: number token?: string - user?: User + user?: ClientUser } export type Arguments = { @@ -21,8 +21,8 @@ export const meOperation = async ({ collection, currentToken, req, -}: Arguments): Promise => { - let result: Result = { +}: Arguments): Promise => { + let result: MeOperationResult = { user: null, } diff --git a/packages/payload/src/auth/types.ts b/packages/payload/src/auth/types.ts index 81b3a1f82..bb7f04c3e 100644 --- a/packages/payload/src/auth/types.ts +++ b/packages/payload/src/auth/types.ts @@ -62,12 +62,18 @@ export type Permissions = { } export type User = { - [key: string]: unknown + [key: string]: any // This NEEDS to be an any, otherwise it breaks the Omit for ClientUser below collection: string email: string id: string } +/** + * `collection` is not available one the client. It's only available on the server (req.user) + * On the client, you can access the collection via config.admin.user. Config can be accessed using the useConfig() hook + */ +export type ClientUser = Omit + type GenerateVerifyEmailHTML = (args: { req: PayloadRequest token: string diff --git a/packages/payload/src/collections/config/types.ts b/packages/payload/src/collections/config/types.ts index 7176b12eb..bfb5eeb4d 100644 --- a/packages/payload/src/collections/config/types.ts +++ b/packages/payload/src/collections/config/types.ts @@ -7,7 +7,7 @@ import type { CustomSaveButtonProps, CustomSaveDraftButtonProps, } from '../../admin/types.js' -import type { Auth, IncomingAuthType, User } from '../../auth/types.js' +import type { Auth, ClientUser, IncomingAuthType } from '../../auth/types.js' import type { Access, EditConfig, @@ -270,7 +270,7 @@ export type CollectionAdminOptions = { /** * Exclude the collection from the admin nav and routes */ - hidden?: ((args: { user: User }) => boolean) | boolean + hidden?: ((args: { user: ClientUser }) => boolean) | boolean /** * Hide the API URL within the Edit view */ diff --git a/packages/payload/src/exports/types.ts b/packages/payload/src/exports/types.ts index d30136eec..62acd9a75 100644 --- a/packages/payload/src/exports/types.ts +++ b/packages/payload/src/exports/types.ts @@ -3,6 +3,7 @@ export type * from '../admin/types.js' export type * from '../uploads/types.js' export type { DocumentPermissions, FieldPermissions } from '../auth/index.js' +export type { MeOperationResult } from '../auth/operations/me.js' export type { CollapsedPreferences, diff --git a/packages/richtext-lexical/src/field/features/relationship/utils/EnabledRelationshipsCondition.tsx b/packages/richtext-lexical/src/field/features/relationship/utils/EnabledRelationshipsCondition.tsx index 36a992169..a1556efef 100644 --- a/packages/richtext-lexical/src/field/features/relationship/utils/EnabledRelationshipsCondition.tsx +++ b/packages/richtext-lexical/src/field/features/relationship/utils/EnabledRelationshipsCondition.tsx @@ -1,4 +1,4 @@ -import type { User } from 'payload/auth' +import type { ClientUser } from 'payload/auth' import type { SanitizedCollectionConfig } from 'payload/types' import { useAuth, useConfig } from '@payloadcms/ui' @@ -6,7 +6,7 @@ import * as React from 'react' type options = { uploads: boolean - user: User + user: ClientUser } type FilteredCollectionsT = ( diff --git a/packages/richtext-slate/src/field/elements/EnabledRelationshipsCondition.tsx b/packages/richtext-slate/src/field/elements/EnabledRelationshipsCondition.tsx index 4f11446a9..d80acbcf8 100644 --- a/packages/richtext-slate/src/field/elements/EnabledRelationshipsCondition.tsx +++ b/packages/richtext-slate/src/field/elements/EnabledRelationshipsCondition.tsx @@ -1,6 +1,6 @@ 'use client' -import type { User } from 'payload/auth' +import type { ClientUser } from 'payload/auth' import type { SanitizedCollectionConfig } from 'payload/types' import { useAuth, useConfig } from '@payloadcms/ui/providers' @@ -8,7 +8,7 @@ import * as React from 'react' type options = { uploads: boolean - user: User + user: ClientUser } type FilteredCollectionsT = ( diff --git a/packages/translations/src/utilities/getTranslation.ts b/packages/translations/src/utilities/getTranslation.ts index b63aa759c..102c2f11b 100644 --- a/packages/translations/src/utilities/getTranslation.ts +++ b/packages/translations/src/utilities/getTranslation.ts @@ -5,8 +5,9 @@ import type { I18n } from '../types.js' export const getTranslation = ( label: JSX.Element | Record | string, i18n: Pick, -): string => { - if (typeof label === 'object') { +): JSX.Element | string => { + // If it's a Record, look for translation. If string or React Element, pass through + if (typeof label === 'object' && !Object.prototype.hasOwnProperty.call(label, '$$typeof')) { if (label[i18n.language]) { return label[i18n.language] } @@ -22,5 +23,6 @@ export const getTranslation = ( return fallbackLang && label[fallbackLang] ? fallbackLang : label[Object.keys(label)[0]] } - return label + // If it's a React Element or string, then we should just pass it through + return label as JSX.Element | string } diff --git a/packages/ui/src/forms/Label/index.tsx b/packages/ui/src/forms/Label/index.tsx index 35d8f5f8c..a6e7f4567 100644 --- a/packages/ui/src/forms/Label/index.tsx +++ b/packages/ui/src/forms/Label/index.tsx @@ -11,17 +11,17 @@ import { useForm } from '../Form/context.js' import './index.scss' const Label: React.FC = (props) => { - const { htmlFor: htmlForFromProps, label, required = false } = props + const { htmlFor: htmlForFromProps, label: labelFromProps, required = false } = props const { uuid } = useForm() const { path } = useFieldProps() const htmlFor = htmlForFromProps || generateFieldID(path, uuid) const { i18n } = useTranslation() - if (label) { + if (labelFromProps) { return ( ) diff --git a/packages/ui/src/providers/Auth/index.tsx b/packages/ui/src/providers/Auth/index.tsx index eea3ebb01..8f425e6be 100644 --- a/packages/ui/src/providers/Auth/index.tsx +++ b/packages/ui/src/providers/Auth/index.tsx @@ -1,5 +1,6 @@ 'use client' -import type { Permissions, User } from 'payload/auth' +import type { ClientUser, Permissions } from 'payload/auth' +import type { MeOperationResult } from 'payload/types.js' import * as facelessUIImport from '@faceless-ui/modal' import { usePathname, useRouter } from 'next/navigation.js' @@ -24,7 +25,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children const { useModal } = facelessUIImport const { searchParams } = useSearchParams() - const [user, setUser] = useState() + const [user, setUser] = useState() const [tokenInMemory, setTokenInMemory] = useState() const [tokenExpiration, setTokenExpiration] = useState() const pathname = usePathname() @@ -94,6 +95,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children if (request.status === 200) { const json = await request.json() setUser(json.user) + setTokenAndExpiration(json) } else { setUser(null) @@ -117,7 +119,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children ) const refreshCookieAsync = useCallback( - async (skipSetUser?: boolean): Promise => { + async (skipSetUser?: boolean): Promise => { try { const request = await requests.post(`${serverURL}${api}/${userSlug}/refresh-token`, { headers: { @@ -187,10 +189,11 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) if (request.status === 200) { - const json = await request.json() + const json: MeOperationResult = await request.json() if (json?.user) { setUser(json.user) + if (json?.token) { setTokenAndExpiration(json) } @@ -317,4 +320,4 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children ) } -export const useAuth = (): AuthContext => useContext(Context) as AuthContext +export const useAuth = (): AuthContext => useContext(Context) as AuthContext diff --git a/packages/ui/src/providers/Auth/types.ts b/packages/ui/src/providers/Auth/types.ts index 071a0d1c5..8f1f04202 100644 --- a/packages/ui/src/providers/Auth/types.ts +++ b/packages/ui/src/providers/Auth/types.ts @@ -1,11 +1,11 @@ -import type { Permissions, User } from 'payload/auth' +import type { ClientUser, Permissions } from 'payload/auth' -export type AuthContext = { +export type AuthContext = { fetchFullUser: () => Promise logOut: () => void permissions?: Permissions refreshCookie: (forceRefresh?: boolean) => void - refreshCookieAsync: () => Promise + refreshCookieAsync: () => Promise refreshPermissions: () => Promise setPermissions: (permissions: Permissions) => void setUser: (user: T) => void diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6d55c2553..8ebed3816 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -86,8 +86,8 @@ importers: specifier: 1.2.2 version: 1.2.2 '@types/node': - specifier: 20.5.7 - version: 20.5.7 + specifier: 20.11.28 + version: 20.11.28 '@types/prompts': specifier: ^2.4.5 version: 2.4.9 @@ -171,7 +171,7 @@ importers: version: 8.0.3 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.5.7)(ts-node@10.9.1) + version: 29.7.0(@types/node@20.11.28)(ts-node@10.9.1) jest-environment-jsdom: specifier: 29.7.0 version: 29.7.0 @@ -264,7 +264,7 @@ importers: version: 1.0.1 ts-node: specifier: 10.9.1 - version: 10.9.1(@swc/core@1.4.2)(@types/node@20.5.7)(typescript@5.4.2) + version: 10.9.1(@swc/core@1.4.2)(@types/node@20.11.28)(typescript@5.4.2) tsx: specifier: ^4.7.1 version: 4.7.1 @@ -3799,14 +3799,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.6.2 + '@types/node': 16.18.85 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.6.2)(ts-node@10.9.1) + jest-config: 29.7.0(@types/node@16.18.85)(ts-node@10.9.1) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -3840,7 +3840,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.6.2 + '@types/node': 16.18.85 jest-mock: 29.7.0 /@jest/expect-utils@29.7.0: @@ -3864,7 +3864,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.6.2 + '@types/node': 16.18.85 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -3977,7 +3977,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.6.2 + '@types/node': 16.18.85 '@types/yargs': 17.0.32 chalk: 4.1.2 @@ -5627,7 +5627,7 @@ packages: chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 - jest: 29.7.0(@types/node@20.5.7)(ts-node@10.9.1) + jest: 29.7.0(@types/node@20.11.28)(ts-node@10.9.1) lodash: 4.17.21 redent: 3.0.0 dev: true @@ -5750,7 +5750,7 @@ packages: /@types/concat-stream@2.0.3: resolution: {integrity: sha512-3qe4oQAPNwVNwK4C9c8u+VJqv9kez+2MR4qJpoPFfXtgxxif1QbFusvXzK0/Wra2VX07smostI2VMmJNSpZjuQ==} dependencies: - '@types/node': 20.6.2 + '@types/node': 16.18.85 dev: true /@types/connect@3.4.38: @@ -5766,7 +5766,7 @@ packages: '@types/conventional-commits-parser': 5.0.0 '@types/conventional-recommended-bump': 9.0.3 '@types/git-raw-commits': 2.0.4 - '@types/node': 20.6.2 + '@types/node': 16.18.85 '@types/normalize-package-data': 2.4.4 dev: true @@ -5791,7 +5791,7 @@ packages: '@types/conventional-changelog-core': 4.2.7 '@types/conventional-changelog-writer': 4.0.10 '@types/conventional-commits-parser': 5.0.0 - '@types/node': 20.6.2 + '@types/node': 16.18.85 dev: true /@types/conventional-commits-parser@5.0.0: @@ -5880,7 +5880,7 @@ packages: resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.6.2 + '@types/node': 16.18.85 dev: true /@types/fs-extra@9.0.13: @@ -5899,7 +5899,7 @@ packages: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.6.2 + '@types/node': 16.18.85 /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -5969,7 +5969,7 @@ packages: /@types/jsdom@20.0.1: resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} dependencies: - '@types/node': 20.6.2 + '@types/node': 16.18.85 '@types/tough-cookie': 4.0.5 parse5: 7.1.2 dev: true @@ -5984,7 +5984,7 @@ packages: /@types/jsonfile@6.1.4: resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} dependencies: - '@types/node': 20.6.2 + '@types/node': 16.18.85 dev: true /@types/jsonwebtoken@8.5.9: @@ -6064,14 +6064,14 @@ packages: resolution: {integrity: sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A==} dev: true - /@types/node@20.11.22: - resolution: {integrity: sha512-/G+IxWxma6V3E+pqK1tSl2Fo1kl41pK1yeCyDsgkF9WlVAme4j5ISYM2zR11bgLFJGLN5sVK40T4RJNuiZbEjA==} + /@types/node@20.11.28: + resolution: {integrity: sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==} dependencies: undici-types: 5.26.5 - dev: true /@types/node@20.5.7: resolution: {integrity: sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==} + dev: true /@types/node@20.6.2: resolution: {integrity: sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==} @@ -6237,7 +6237,7 @@ packages: resolution: {integrity: sha512-ZA8U81/gldY+rR5zl/7HSHrG2KDfEb3lzG6uCUDhW1DTQE9yC/VBQ45fXnXq8f3CgInfhZmjtdu/WOUlrXRQUg==} dependencies: '@types/glob': 7.2.0 - '@types/node': 20.6.2 + '@types/node': 16.18.85 dev: true /@types/stack-utils@2.0.3: @@ -8125,7 +8125,7 @@ packages: - ts-node dev: true - /create-jest@29.7.0(@types/node@20.5.7)(ts-node@10.9.1): + /create-jest@29.7.0(@types/node@20.11.28)(ts-node@10.9.1): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -8134,7 +8134,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.5.7)(ts-node@10.9.1) + jest-config: 29.7.0(@types/node@20.11.28)(ts-node@10.9.1) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -9325,7 +9325,7 @@ packages: '@typescript-eslint/eslint-plugin': 7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2) '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.4.2) eslint: 8.57.0 - jest: 29.7.0(@types/node@20.5.7)(ts-node@10.9.1) + jest: 29.7.0(@types/node@20.11.28)(ts-node@10.9.1) transitivePeerDependencies: - supports-color - typescript @@ -11472,7 +11472,7 @@ packages: - ts-node dev: true - /jest-cli@29.7.0(@types/node@20.5.7)(ts-node@10.9.1): + /jest-cli@29.7.0(@types/node@20.11.28)(ts-node@10.9.1): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -11486,10 +11486,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.5.7)(ts-node@10.9.1) + create-jest: 29.7.0(@types/node@20.11.28)(ts-node@10.9.1) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.5.7)(ts-node@10.9.1) + jest-config: 29.7.0(@types/node@20.11.28)(ts-node@10.9.1) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -11499,6 +11499,46 @@ packages: - supports-color - ts-node + /jest-config@29.7.0(@types/node@16.18.85)(ts-node@10.9.1): + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.24.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 16.18.85 + babel-jest: 29.7.0(@babel/core@7.24.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.1(@swc/core@1.4.2)(@types/node@20.11.28)(typescript@5.4.2) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + /jest-config@29.7.0(@types/node@18.11.3)(ts-node@10.9.1): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -11534,13 +11574,13 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.1(@swc/core@1.4.2)(@types/node@20.5.7)(typescript@5.4.2) + ts-node: 10.9.1(@swc/core@1.4.2)(@types/node@20.11.28)(typescript@5.4.2) transitivePeerDependencies: - babel-plugin-macros - supports-color dev: true - /jest-config@29.7.0(@types/node@20.5.7)(ts-node@10.9.1): + /jest-config@29.7.0(@types/node@20.11.28)(ts-node@10.9.1): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -11555,7 +11595,7 @@ packages: '@babel/core': 7.24.0 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.5.7 + '@types/node': 20.11.28 babel-jest: 29.7.0(@babel/core@7.24.0) chalk: 4.1.2 ci-info: 3.9.0 @@ -11575,47 +11615,7 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.1(@swc/core@1.4.2)(@types/node@20.5.7)(typescript@5.4.2) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - /jest-config@29.7.0(@types/node@20.6.2)(ts-node@10.9.1): - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.24.0 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.6.2 - babel-jest: 29.7.0(@babel/core@7.24.0) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - ts-node: 10.9.1(@swc/core@1.4.2)(@types/node@20.5.7)(typescript@5.4.2) + ts-node: 10.9.1(@swc/core@1.4.2)(@types/node@20.11.28)(typescript@5.4.2) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -11668,7 +11668,7 @@ packages: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 20.6.2 + '@types/node': 16.18.85 jest-mock: 29.7.0 jest-util: 29.7.0 jsdom: 20.0.3 @@ -11761,7 +11761,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.6.2 + '@types/node': 16.18.85 jest-util: 29.7.0 /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -11960,7 +11960,7 @@ packages: - ts-node dev: true - /jest@29.7.0(@types/node@20.5.7)(ts-node@10.9.1): + /jest@29.7.0(@types/node@20.11.28)(ts-node@10.9.1): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -11973,7 +11973,7 @@ packages: '@jest/core': 29.7.0(ts-node@10.9.1) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.5.7)(ts-node@10.9.1) + jest-cli: 29.7.0(@types/node@20.11.28)(ts-node@10.9.1) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -13082,7 +13082,7 @@ packages: engines: {node: '>=14'} dependencies: '@types/express': 4.17.21 - '@types/node': 20.11.22 + '@types/node': 20.11.28 accepts: 1.3.8 content-disposition: 0.5.4 depd: 1.1.2 @@ -16591,7 +16591,7 @@ packages: bs-logger: 0.2.6 esbuild: 0.19.12 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.5.7)(ts-node@10.9.1) + jest: 29.7.0(@types/node@20.11.28)(ts-node@10.9.1) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -16633,7 +16633,7 @@ packages: yn: 3.1.1 dev: true - /ts-node@10.9.1(@swc/core@1.4.2)(@types/node@20.5.7)(typescript@5.4.2): + /ts-node@10.9.1(@swc/core@1.4.2)(@types/node@20.11.28)(typescript@5.4.2): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -16653,7 +16653,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.5.7 + '@types/node': 20.11.28 acorn: 8.11.3 acorn-walk: 8.3.2 arg: 4.1.3 @@ -16902,7 +16902,6 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true /unfetch@4.2.0: resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} diff --git a/test/auth/config.ts b/test/auth/config.ts index 44e14ac21..a48ce8761 100644 --- a/test/auth/config.ts +++ b/test/auth/config.ts @@ -17,6 +17,9 @@ export default buildConfigWithDefaults({ }, collections: [ { + admin: { + useAsTitle: 'custom', + }, slug, auth: { cookies: { @@ -198,6 +201,16 @@ export default buildConfigWithDefaults({ }, fields: [], }, + { + slug: 'relationsCollection', + fields: [ + { + name: 'rel', + type: 'relationship', + relationTo: 'users', + }, + ], + }, ], onInit: async (payload) => { await payload.create({ diff --git a/test/auth/e2e.spec.ts b/test/auth/e2e.spec.ts index 8b2b78a65..0ea953078 100644 --- a/test/auth/e2e.spec.ts +++ b/test/auth/e2e.spec.ts @@ -4,7 +4,8 @@ import { expect, test } from '@playwright/test' import path from 'path' import { fileURLToPath } from 'url' -import payload from '../../packages/payload/src/index.js' +import type { Payload } from '../../packages/payload/src/index.js' + import { initPageConsoleErrorCatch, login, saveDocAndAssert } from '../helpers.js' import { AdminUrlUtil } from '../helpers/adminUrlUtil.js' import { initPayloadE2E } from '../helpers/initPayloadE2E.js' @@ -12,6 +13,7 @@ import config from './config.js' import { apiKeysSlug, slug } from './shared.js' const filename = fileURLToPath(import.meta.url) const dirname = path.dirname(filename) +let payload: Payload /** * TODO: Auth @@ -33,7 +35,8 @@ describe('auth', () => { let apiURL: string beforeAll(async ({ browser }) => { - ;({ serverURL } = await initPayloadE2E({ config, dirname })) + ;({ serverURL, payload } = await initPayloadE2E({ config, dirname })) + apiURL = `${serverURL}/api` url = new AdminUrlUtil(serverURL, slug) const context = await browser.newContext() diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 000000000..7d4ceddd6 --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,49 @@ +{ + "compilerOptions": { + "noEmit": false /* Do not emit outputs. */, + "emitDeclarationOnly": true, + "rootDir": "..", /* Specify the root folder within your source files. */ + "declaration": true, + "declarationMap": true, + "target": "esnext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "allowJs": true, + "checkJs": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "jsx": "preserve", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": false, + "types": [ + "jest", + "node", + "@types/jest" + ], + "incremental": true, + "isolatedModules": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + + } + }, + "exclude": ["dist", "build", "node_modules", ".eslintrc.js", "dist/**/*.js", "**/dist/**/*.js"], + "include": [ + "./**/*.ts", + "../packages/**/src/**/*.ts", + "../packages/**/src/**/*.tsx" + ], + "references": [], +} +