diff --git a/.idea/runConfigurations/Playwright_test.xml b/.idea/runConfigurations/Playwright_test.xml new file mode 100644 index 000000000..4b0bde7fe --- /dev/null +++ b/.idea/runConfigurations/Playwright_test.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 62690615a..0cda09abb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -40,25 +40,5 @@ "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" } - }, - "workbench.colorCustomizations": { - "activityBar.activeBackground": "#8cb5b6", - "activityBar.background": "#8cb5b6", - "activityBar.foreground": "#15202b", - "activityBar.inactiveForeground": "#15202b99", - "activityBarBadge.background": "#9c639b", - "activityBarBadge.foreground": "#e7e7e7", - "commandCenter.border": "#15202b99", - "sash.hoverBorder": "#8cb5b6", - "statusBar.background": "#6da1a2", - "statusBar.foreground": "#15202b", - "statusBarItem.hoverBackground": "#568586", - "statusBarItem.remoteBackground": "#6da1a2", - "statusBarItem.remoteForeground": "#15202b", - "titleBar.activeBackground": "#6da1a2", - "titleBar.activeForeground": "#15202b", - "titleBar.inactiveBackground": "#6da1a299", - "titleBar.inactiveForeground": "#15202b99" - }, - "peacock.color": "#6da1a2" + } } diff --git a/next.config.mjs b/next.config.mjs index 572c6d706..57cb05b07 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,6 +1,7 @@ -import withPayload from './packages/next/src/withPayload.js' import bundleAnalyzer from '@next/bundle-analyzer' +import withPayload from './packages/next/src/withPayload.js' + const withBundleAnalyzer = bundleAnalyzer({ enabled: process.env.ANALYZE === 'true', }) @@ -8,14 +9,6 @@ const withBundleAnalyzer = bundleAnalyzer({ export default withBundleAnalyzer( withPayload({ reactStrictMode: false, - webpack: (webpackConfig) => { - webpackConfig.resolve.extensionAlias = { - '.js': ['.ts', '.tsx', '.js', '.jsx'], - '.mjs': ['.mts', '.mjs'], - '.cjs': ['.cts', '.cjs'], - } - return webpackConfig - }, async redirects() { return [ { @@ -25,5 +18,13 @@ export default withBundleAnalyzer( }, ] }, + webpack: (webpackConfig) => { + webpackConfig.resolve.extensionAlias = { + '.cjs': ['.cts', '.cjs'], + '.js': ['.ts', '.tsx', '.js', '.jsx'], + '.mjs': ['.mts', '.mjs'], + } + return webpackConfig + }, }), ) diff --git a/package.json b/package.json index 3fbb22693..c2f85862b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "payload-monorepo", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "private": true, "type": "module", "workspaces:": [ @@ -40,14 +40,14 @@ "clean:build": "find . \\( -type d \\( -name dist -o -name .cache -o -name .next -o -name .turbo \\) -o -type f -name tsconfig.tsbuildinfo \\) -not -path '*/node_modules/*' -exec rm -rf {} +", "clean:all": "find . \\( -type d \\( -name node_modules -o -name dist -o -name .cache -o -name .next -o -name .turbo \\) -o -type f -name tsconfig.tsbuildinfo \\) -exec rm -rf {} +", "dev": "cross-env node --no-deprecation ./test/dev.js", - "dev:generate-graphql-schema": "NODE_OPTIONS=--no-deprecation tsx ./test/generateGraphQLSchema.ts", - "dev:generate-types": "NODE_OPTIONS=--no-deprecation tsx ./test/generateTypes.ts", + "dev:generate-graphql-schema": "cross-env NODE_OPTIONS=--no-deprecation tsx ./test/generateGraphQLSchema.ts", + "dev:generate-types": "cross-env NODE_OPTIONS=--no-deprecation tsx ./test/generateTypes.ts", "dev:postgres": "pnpm --filter payload run dev:postgres", "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", - "generate:types": "PAYLOAD_CONFIG_PATH=./test/_community/config.ts ts-node ./packages/payload/bin.js", + "generate:types": "PAYLOAD_CONFIG_PATH=./test/_community/config.ts node --no-deprecation ./packages/payload/bin.js generate:types", "lint": "eslint \"packages/**/*.ts\"", "lint-staged": "lint-staged", "prepare": "husky install", @@ -122,6 +122,8 @@ "nodemon": "3.0.3", "pino": "8.15.0", "pino-pretty": "10.2.0", + "playwright": "file:playwright-1.43.0-next.tgz", + "playwright-core": "file:playwright-core-1.43.0-next.tgz", "prettier": "^3.0.3", "prompts": "2.4.2", "qs": "6.11.2", @@ -169,7 +171,9 @@ "graphql": "^16.8.1", "react": "$react", "react-dom": "$react-dom", - "typescript": "$typescript" + "typescript": "$typescript", + "playwright": "file:playwright-1.43.0-next.tgz", + "playwright-core": "file:playwright-core-1.43.0-next.tgz" }, "allowedDeprecatedVersions": { "uuid": "3.4.0", diff --git a/packages/db-mongodb/package.json b/packages/db-mongodb/package.json index fef817771..1a3a735fd 100644 --- a/packages/db-mongodb/package.json +++ b/packages/db-mongodb/package.json @@ -1,6 +1,6 @@ { "name": "@payloadcms/db-mongodb", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "description": "The officially supported MongoDB database adapter for Payload - Update 2", "repository": "https://github.com/payloadcms/payload", "license": "MIT", diff --git a/packages/db-postgres/package.json b/packages/db-postgres/package.json index 055ce611e..786277a02 100644 --- a/packages/db-postgres/package.json +++ b/packages/db-postgres/package.json @@ -1,6 +1,6 @@ { "name": "@payloadcms/db-postgres", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "description": "The officially supported Postgres database adapter for Payload", "repository": "https://github.com/payloadcms/payload", "license": "MIT", diff --git a/packages/db-postgres/src/connect.ts b/packages/db-postgres/src/connect.ts index b5ff92c8e..15a0e9679 100644 --- a/packages/db-postgres/src/connect.ts +++ b/packages/db-postgres/src/connect.ts @@ -4,7 +4,7 @@ import type { Connect } from 'payload/database' import { eq, sql } from 'drizzle-orm' import { drizzle } from 'drizzle-orm/node-postgres' import { numeric, timestamp, varchar } from 'drizzle-orm/pg-core' -import { Pool } from 'pg' +import pg from 'pg' import prompts from 'prompts' import type { PostgresAdapter } from './types.js' @@ -61,7 +61,7 @@ export const connect: Connect = async function connect( } try { - this.pool = new Pool(this.poolOptions) + this.pool = new pg.Pool(this.poolOptions) await connectWithReconnect({ adapter: this, payload: this.payload }) const logger = this.logger || false diff --git a/packages/db-postgres/src/utilities/parseError.ts b/packages/db-postgres/src/utilities/parseError.ts index 54c6f63cc..88abbcd2e 100644 --- a/packages/db-postgres/src/utilities/parseError.ts +++ b/packages/db-postgres/src/utilities/parseError.ts @@ -1,4 +1,5 @@ -import { DatabaseError } from 'pg' +import pg from 'pg' +const { DatabaseError } = pg /** * Format error message with hint if available diff --git a/packages/graphql/package.json b/packages/graphql/package.json index cd78d4730..4de0760fa 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -1,6 +1,6 @@ { "name": "@payloadcms/graphql", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "main": "./src/index.ts", "types": "./src/index.d.ts", "type": "module", diff --git a/packages/graphql/src/schema/fieldToWhereInputSchemaMap.ts b/packages/graphql/src/schema/fieldToWhereInputSchemaMap.ts index 99d95af0c..f36b4e5ca 100644 --- a/packages/graphql/src/schema/fieldToWhereInputSchemaMap.ts +++ b/packages/graphql/src/schema/fieldToWhereInputSchemaMap.ts @@ -1,5 +1,5 @@ import { GraphQLEnumType, GraphQLInputObjectType } from 'graphql' -import GraphQLJSON from 'graphql-type-json' +import GraphQLJSONImport from 'graphql-type-json' import type { ArrayField, @@ -28,6 +28,9 @@ import formatName from '../utilities/formatName.js' import recursivelyBuildNestedPaths from './recursivelyBuildNestedPaths.js' import { withOperators } from './withOperators.js' +const GraphQLJSON = (GraphQLJSONImport || + GraphQLJSONImport.default) as unknown as typeof GraphQLJSONImport.default + type Args = { nestedFieldName?: string parentName: string @@ -96,7 +99,7 @@ const fieldToSchemaMap = ({ nestedFieldName, parentName }: Args): any => ({ ), }), }, - value: { type: GraphQLJSON.default }, + value: { type: GraphQLJSON }, }, }), } diff --git a/packages/next/package.json b/packages/next/package.json index 02962bbe8..f83725d76 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@payloadcms/next", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "main": "./src/index.ts", "types": "./src/index.d.ts", "type": "module", diff --git a/packages/next/src/utilities/getDataAndFile.ts b/packages/next/src/utilities/getDataAndFile.ts index 1bffd0172..181cd7e99 100644 --- a/packages/next/src/utilities/getDataAndFile.ts +++ b/packages/next/src/utilities/getDataAndFile.ts @@ -15,7 +15,7 @@ export const getDataAndFile: GetDataAndFile = async ({ collection, config, reque let file: CustomPayloadRequest['file'] = undefined if (['PATCH', 'POST', 'PUT'].includes(request.method.toUpperCase()) && request.body) { - const [contentType] = request.headers.get('Content-Type').split(';') + const [contentType] = (request.headers.get('Content-Type') || '').split(';') if (contentType === 'application/json') { data = await request.json() diff --git a/packages/next/src/views/Account/index.tsx b/packages/next/src/views/Account/index.tsx index 1b5a846a2..1cc812487 100644 --- a/packages/next/src/views/Account/index.tsx +++ b/packages/next/src/views/Account/index.tsx @@ -3,6 +3,7 @@ import type { Data, DocumentPreferences, ServerSideEditViewProps } from 'payload import { DocumentHeader, DocumentInfoProvider, + FormQueryParamsProvider, HydrateClientUser, RenderCustomComponent, buildStateFromSchema, @@ -22,6 +23,7 @@ export { generateAccountMetadata } from './meta.js' export const Account: React.FC = async ({ initPageResult, searchParams }) => { const { permissions, + locale, req: { i18n, payload, @@ -118,13 +120,22 @@ export const Account: React.FC = async ({ initPageResult, search i18n={i18n} /> - + + + ) } diff --git a/packages/payload/bin.js b/packages/payload/bin.js index 1a895327c..a83c55283 100755 --- a/packages/payload/bin.js +++ b/packages/payload/bin.js @@ -1,18 +1,13 @@ -#!/usr/bin/env ts-node -/* eslint-disable @typescript-eslint/no-var-requires */ +#!/usr/bin/env node import { register } from 'node:module' import path from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' -// import * as tsNode from 'ts-node' -import bin from './dist/bin/index.js' -import { loadEnv } from './dist/bin/loadEnv.js' -import { findConfig } from './dist/config/find.js' +import { bin } from './dist/bin/index.js' // Allow disabling SWC for debugging if (process.env.DISABLE_SWC !== 'true') { - // const oldURL = pathToFileURL('./').toString() const filename = fileURLToPath(import.meta.url) const dirname = path.dirname(filename) const url = pathToFileURL(dirname).toString() + '/' @@ -20,17 +15,4 @@ if (process.env.DISABLE_SWC !== 'true') { register('./dist/bin/register/index.js', url) } -// tsNode.register({}) - -const start = async () => { - loadEnv() - const configPath = findConfig() - - // const sanitized = configPath.replace('.ts', '') - const configPromise = await import(configPath) - const config = await configPromise - - bin(config) -} - -start() +bin() diff --git a/packages/payload/package.json b/packages/payload/package.json index dd0a92176..792ff3fdd 100644 --- a/packages/payload/package.json +++ b/packages/payload/package.json @@ -1,6 +1,6 @@ { "name": "payload", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "description": "Node, React and MongoDB Headless CMS and Application Framework", "license": "MIT", "main": "./src/index.js", @@ -44,15 +44,11 @@ "dependencies": { "@payloadcms/translations": "workspace:*", "@swc-node/core": "^1.13.0", - "@swc-node/register": "^1.9.0", "@swc-node/sourcemap-support": "^0.5.0", - "@swc/register": "^0.1.10", "bson-objectid": "2.0.4", - "colorette": "^2.0.20", "conf": "10.2.0", "console-table-printer": "2.11.2", "dataloader": "2.2.2", - "debug": "^4.3.4", "deepmerge": "4.3.1", "dotenv": "8.6.0", "file-type": "16.5.4", diff --git a/packages/payload/src/bin/index.ts b/packages/payload/src/bin/index.ts index a42bb3bba..bd5ac76b2 100755 --- a/packages/payload/src/bin/index.ts +++ b/packages/payload/src/bin/index.ts @@ -1,18 +1,26 @@ /* eslint-disable no-console */ import minimist from 'minimist' -import type { BinScript, SanitizedConfig } from '../config/types.js' +import type { BinScript } from '../config/types.js' -// import loadConfig from '../config/load.js' +import { findConfig } from '../config/find.js' import { generateTypes } from './generateTypes.js' +import { loadEnv } from './loadEnv.js' import { migrate } from './migrate.js' -// eslint-disable-next-line no-restricted-exports -export default async (config: SanitizedConfig) => { +export const bin = async () => { + loadEnv() + const configPath = findConfig() + const configPromise = await import(configPath) + let config = await configPromise + if (config.default) config = await config.default + const args = minimist(process.argv.slice(2)) - const scriptIndex = args._.findIndex((x) => x === 'build') - const script = scriptIndex === -1 ? args._[0] : args._[scriptIndex] - const userBinScript = config.bin.find(({ key }) => key === script) + const script = (typeof args._[0] === 'string' ? args._[0] : '').toLowerCase() + + const userBinScript = Array.isArray(config.bin) + ? config.bin.find(({ key }) => key === script) + : false if (userBinScript) { try { @@ -27,17 +35,13 @@ export default async (config: SanitizedConfig) => { } if (script.startsWith('migrate')) { - void migrate({ config, parsedArgs: args }).then(() => process.exit(0)) - } else { - switch (script.toLowerCase()) { - case 'generate:types': { - generateTypes(config) - break - } - - default: - console.log(`Unknown script "${script}".`) - break - } + return migrate({ config, parsedArgs: args }).then(() => process.exit(0)) } + + if (script === 'generate:types') { + return generateTypes(config) + } + + console.log(`Unknown script: "${script}".`) + process.exit(1) } diff --git a/packages/plugin-cloud-storage/package.json b/packages/plugin-cloud-storage/package.json index d0a1f8675..0ad6bb694 100644 --- a/packages/plugin-cloud-storage/package.json +++ b/packages/plugin-cloud-storage/package.json @@ -1,7 +1,7 @@ { "name": "@payloadcms/plugin-cloud-storage", "description": "The official cloud storage plugin for Payload CMS", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "main": "dist/index.js", "types": "dist/index.d.ts", "type": "module", diff --git a/packages/plugin-cloud/package.json b/packages/plugin-cloud/package.json index b5b027584..2586dc377 100644 --- a/packages/plugin-cloud/package.json +++ b/packages/plugin-cloud/package.json @@ -1,7 +1,7 @@ { "name": "@payloadcms/plugin-cloud", "description": "The official Payload Cloud plugin", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "main": "dist/index.js", "types": "dist/index.d.ts", "license": "MIT", diff --git a/packages/plugin-cloud/src/types.ts b/packages/plugin-cloud/src/types.ts index 6edd5a122..3a6847581 100644 --- a/packages/plugin-cloud/src/types.ts +++ b/packages/plugin-cloud/src/types.ts @@ -1,7 +1,5 @@ -import type { Response } from 'express' import type { Config } from 'payload/config' -import type { TypeWithID } from 'payload/types' -import type { CollectionConfig, FileData, PayloadRequest } from 'payload/types' +import type { CollectionConfig, FileData, PayloadRequest, TypeWithID } from 'payload/types' export interface File { buffer: Buffer diff --git a/packages/plugin-seo/package.json b/packages/plugin-seo/package.json index cba2b2e70..3b1f90613 100644 --- a/packages/plugin-seo/package.json +++ b/packages/plugin-seo/package.json @@ -1,6 +1,6 @@ { "name": "@payloadcms/plugin-seo", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "homepage:": "https://payloadcms.com", "repository": "git@github.com:payloadcms/plugin-seo.git", "description": "SEO plugin for Payload", diff --git a/packages/richtext-lexical/package.json b/packages/richtext-lexical/package.json index dced2380e..46bfc276b 100644 --- a/packages/richtext-lexical/package.json +++ b/packages/richtext-lexical/package.json @@ -1,6 +1,6 @@ { "name": "@payloadcms/richtext-lexical", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "description": "The officially supported Lexical richtext adapter for Payload", "repository": "https://github.com/payloadcms/payload", "license": "MIT", diff --git a/packages/richtext-lexical/src/cell/index.tsx b/packages/richtext-lexical/src/cell/index.tsx index 2f78ff50b..b7b6e9d12 100644 --- a/packages/richtext-lexical/src/cell/index.tsx +++ b/packages/richtext-lexical/src/cell/index.tsx @@ -5,7 +5,8 @@ import { createHeadlessEditor } from '@lexical/headless' import { useTableCell } from '@payloadcms/ui/elements' import { useFieldPath } from '@payloadcms/ui/forms' import { useClientFunctions } from '@payloadcms/ui/providers' -import { $getRoot } from 'lexical' +import lexicalImport from 'lexical' +const { $getRoot } = lexicalImport import React, { useEffect, useState } from 'react' import type { FeatureProviderClient } from '../field/features/types.js' diff --git a/packages/richtext-lexical/src/field/features/align/feature.client.tsx b/packages/richtext-lexical/src/field/features/align/feature.client.tsx index 03861eb8e..401d7bf3c 100644 --- a/packages/richtext-lexical/src/field/features/align/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/align/feature.client.tsx @@ -1,6 +1,7 @@ 'use client' -import { FORMAT_ELEMENT_COMMAND } from 'lexical' +import lexicalImport from 'lexical' +const { FORMAT_ELEMENT_COMMAND } = lexicalImport import type { FeatureProviderProviderClient } from '../types.js' diff --git a/packages/richtext-lexical/src/field/features/blockquote/feature.client.tsx b/packages/richtext-lexical/src/field/features/blockquote/feature.client.tsx index 95a67878a..7aefb749c 100644 --- a/packages/richtext-lexical/src/field/features/blockquote/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/blockquote/feature.client.tsx @@ -1,8 +1,13 @@ 'use client' -import { $createQuoteNode, QuoteNode } from '@lexical/rich-text' -import { $setBlocksType } from '@lexical/selection' -import { $getSelection } from 'lexical' +import lexicalRichTextImport from '@lexical/rich-text' +const { $createQuoteNode, QuoteNode } = lexicalRichTextImport + +import lexicalSelectionImport from '@lexical/selection' +const { $setBlocksType } = lexicalSelectionImport + +import lexicalImport from 'lexical' +const { $getSelection } = lexicalImport import type { FeatureProviderProviderClient } from '../types.js' diff --git a/packages/richtext-lexical/src/field/features/blockquote/feature.server.ts b/packages/richtext-lexical/src/field/features/blockquote/feature.server.ts index e3b3aa05d..7fdf16ef6 100644 --- a/packages/richtext-lexical/src/field/features/blockquote/feature.server.ts +++ b/packages/richtext-lexical/src/field/features/blockquote/feature.server.ts @@ -1,4 +1,5 @@ -import { QuoteNode, type SerializedQuoteNode } from '@lexical/rich-text' +import lexicalRichTextImport, { type SerializedQuoteNode } from '@lexical/rich-text' +const { QuoteNode } = lexicalRichTextImport import type { HTMLConverter } from '../converters/html/converter/types.js' import type { FeatureProviderProviderServer } from '../types.js' diff --git a/packages/richtext-lexical/src/field/features/blockquote/markdownTransformer.ts b/packages/richtext-lexical/src/field/features/blockquote/markdownTransformer.ts index f5088c729..94f87485e 100644 --- a/packages/richtext-lexical/src/field/features/blockquote/markdownTransformer.ts +++ b/packages/richtext-lexical/src/field/features/blockquote/markdownTransformer.ts @@ -1,7 +1,11 @@ import type { ElementTransformer } from '@lexical/markdown' -import { $createQuoteNode, $isQuoteNode, QuoteNode } from '@lexical/rich-text' -import { $createLineBreakNode } from 'lexical' +import lexicalRichTextImport from '@lexical/rich-text' +const { $createQuoteNode, $isQuoteNode, QuoteNode } = lexicalRichTextImport + +import lexicalImport from 'lexical' +const { $createLineBreakNode } = lexicalImport + export const MarkdownTransformer: ElementTransformer = { type: 'element', dependencies: [QuoteNode], diff --git a/packages/richtext-lexical/src/field/features/blocks/component/BlockContent.tsx b/packages/richtext-lexical/src/field/features/blocks/component/BlockContent.tsx index bef16296d..a2f70d41d 100644 --- a/packages/richtext-lexical/src/field/features/blocks/component/BlockContent.tsx +++ b/packages/richtext-lexical/src/field/features/blocks/component/BlockContent.tsx @@ -3,7 +3,8 @@ import type { ReducedBlock } from '@payloadcms/ui/types' import type { FormState } from 'payload/types' import type { Data } from 'payload/types' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport import { getTranslation } from '@payloadcms/translations' import { RenderFields } from '@payloadcms/ui' import { @@ -17,7 +18,8 @@ import { useTranslation, } from '@payloadcms/ui' import isDeepEqual from 'deep-equal' -import { $getNodeByKey } from 'lexical' +import lexicalImport from 'lexical' +const { $getNodeByKey } = lexicalImport import React, { useCallback } from 'react' import type { SanitizedClientEditorConfig } from '../../../lexical/config/types.js' diff --git a/packages/richtext-lexical/src/field/features/blocks/drawer/index.tsx b/packages/richtext-lexical/src/field/features/blocks/drawer/index.tsx index 67b8e06d4..e7eac4454 100644 --- a/packages/richtext-lexical/src/field/features/blocks/drawer/index.tsx +++ b/packages/richtext-lexical/src/field/features/blocks/drawer/index.tsx @@ -1,14 +1,13 @@ 'use client' -import { useModal } from '@faceless-ui/modal' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import * as facelessUIImport from '@faceless-ui/modal' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport import { BlocksDrawer, formatDrawerSlug, useEditDepth, useTranslation } from '@payloadcms/ui' -import { - $getNodeByKey, - COMMAND_PRIORITY_EDITOR, - type LexicalCommand, - type LexicalEditor, - createCommand, -} from 'lexical' +import lexicalImport from 'lexical' +const { $getNodeByKey, COMMAND_PRIORITY_EDITOR, createCommand } = lexicalImport + +import type { LexicalCommand, LexicalEditor } from 'lexical' + import React, { useCallback, useEffect, useState } from 'react' import type { ClientComponentProps } from '../../types.js' @@ -55,6 +54,8 @@ const insertBlock = ({ } export const BlocksDrawerComponent: React.FC = () => { + const { useModal } = facelessUIImport + const [editor] = useLexicalComposerContext() const { editorConfig, uuid } = useEditorConfigContext() diff --git a/packages/richtext-lexical/src/field/features/blocks/nodes/BlocksNode.tsx b/packages/richtext-lexical/src/field/features/blocks/nodes/BlocksNode.tsx index b71d7b6bd..b6106b775 100644 --- a/packages/richtext-lexical/src/field/features/blocks/nodes/BlocksNode.tsx +++ b/packages/richtext-lexical/src/field/features/blocks/nodes/BlocksNode.tsx @@ -10,7 +10,8 @@ import type { Spread, } from 'lexical' -import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js' +import lexicalDecoratorBlockNodeImport from '@lexical/react/LexicalDecoratorBlockNode.js' +const { DecoratorBlockNode } = lexicalDecoratorBlockNodeImport import ObjectID from 'bson-objectid' import React from 'react' diff --git a/packages/richtext-lexical/src/field/features/blocks/plugin/commands.ts b/packages/richtext-lexical/src/field/features/blocks/plugin/commands.ts index 0f0c98cb4..4c37a297a 100644 --- a/packages/richtext-lexical/src/field/features/blocks/plugin/commands.ts +++ b/packages/richtext-lexical/src/field/features/blocks/plugin/commands.ts @@ -1,6 +1,7 @@ import type { LexicalCommand } from 'lexical' -import { createCommand } from 'lexical' +import lexicalImport from 'lexical' +const { createCommand } = lexicalImport import type { InsertBlockPayload } from './index.js' diff --git a/packages/richtext-lexical/src/field/features/blocks/plugin/index.tsx b/packages/richtext-lexical/src/field/features/blocks/plugin/index.tsx index 242e463a1..052c5a34d 100644 --- a/packages/richtext-lexical/src/field/features/blocks/plugin/index.tsx +++ b/packages/richtext-lexical/src/field/features/blocks/plugin/index.tsx @@ -1,13 +1,17 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { $insertNodeToNearestRoot, mergeRegister } from '@lexical/utils' -import { +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport +import lexicalUtilsImport from '@lexical/utils' +const { $insertNodeToNearestRoot, mergeRegister } = lexicalUtilsImport +import lexicalImport from 'lexical' +const { $getPreviousSelection, $getSelection, $isParagraphNode, $isRangeSelection, COMMAND_PRIORITY_EDITOR, -} from 'lexical' +} = lexicalImport + import React, { useEffect } from 'react' import type { BlockFields } from '../nodes/BlocksNode.js' diff --git a/packages/richtext-lexical/src/field/features/debug/testrecorder/plugin/index.tsx b/packages/richtext-lexical/src/field/features/debug/testrecorder/plugin/index.tsx index aab60b796..99ba56e4f 100644 --- a/packages/richtext-lexical/src/field/features/debug/testrecorder/plugin/index.tsx +++ b/packages/richtext-lexical/src/field/features/debug/testrecorder/plugin/index.tsx @@ -1,8 +1,10 @@ 'use client' import type { BaseSelection, LexicalEditor } from 'lexical' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { $createParagraphNode, $createTextNode, $getRoot } from 'lexical' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport +import lexicalImport from 'lexical' +const { $createParagraphNode, $createTextNode, $getRoot } = lexicalImport import * as React from 'react' import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react' diff --git a/packages/richtext-lexical/src/field/features/debug/treeview/plugin/index.tsx b/packages/richtext-lexical/src/field/features/debug/treeview/plugin/index.tsx index 8ad08261d..6950eae35 100644 --- a/packages/richtext-lexical/src/field/features/debug/treeview/plugin/index.tsx +++ b/packages/richtext-lexical/src/field/features/debug/treeview/plugin/index.tsx @@ -1,6 +1,8 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { TreeView } from '@lexical/react/LexicalTreeView.js' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport +import lexicalTreeViewImport from '@lexical/react/LexicalTreeView.js' +const { TreeView } = lexicalTreeViewImport import * as React from 'react' import './index.scss' diff --git a/packages/richtext-lexical/src/field/features/format/bold/feature.client.tsx b/packages/richtext-lexical/src/field/features/format/bold/feature.client.tsx index 163d21ca2..db01b8287 100644 --- a/packages/richtext-lexical/src/field/features/format/bold/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/format/bold/feature.client.tsx @@ -1,5 +1,6 @@ 'use client' -import { $isRangeSelection, FORMAT_TEXT_COMMAND } from 'lexical' +import lexicalImport from 'lexical' +const { $isRangeSelection, FORMAT_TEXT_COMMAND } = lexicalImport import type { FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/format/inlinecode/feature.client.tsx b/packages/richtext-lexical/src/field/features/format/inlinecode/feature.client.tsx index 2cc6afb2f..fa1ade953 100644 --- a/packages/richtext-lexical/src/field/features/format/inlinecode/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/format/inlinecode/feature.client.tsx @@ -1,6 +1,7 @@ 'use client' -import { $isRangeSelection, FORMAT_TEXT_COMMAND } from 'lexical' +import lexicalImport from 'lexical' +const { $isRangeSelection, FORMAT_TEXT_COMMAND } = lexicalImport import type { FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/format/italic/feature.client.tsx b/packages/richtext-lexical/src/field/features/format/italic/feature.client.tsx index 92c575f39..c9e025a06 100644 --- a/packages/richtext-lexical/src/field/features/format/italic/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/format/italic/feature.client.tsx @@ -1,6 +1,7 @@ 'use client' -import { $isRangeSelection, FORMAT_TEXT_COMMAND } from 'lexical' +import lexicalImport from 'lexical' +const { $isRangeSelection, FORMAT_TEXT_COMMAND } = lexicalImport import type { FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/format/strikethrough/feature.client.tsx b/packages/richtext-lexical/src/field/features/format/strikethrough/feature.client.tsx index 4fae03769..06538b036 100644 --- a/packages/richtext-lexical/src/field/features/format/strikethrough/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/format/strikethrough/feature.client.tsx @@ -1,6 +1,7 @@ 'use client' -import { $isRangeSelection, FORMAT_TEXT_COMMAND } from 'lexical' +import lexicalImport from 'lexical' +const { $isRangeSelection, FORMAT_TEXT_COMMAND } = lexicalImport import type { FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/format/subscript/feature.client.tsx b/packages/richtext-lexical/src/field/features/format/subscript/feature.client.tsx index 055bd0200..08c489155 100644 --- a/packages/richtext-lexical/src/field/features/format/subscript/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/format/subscript/feature.client.tsx @@ -1,6 +1,7 @@ 'use client' -import { $isRangeSelection, FORMAT_TEXT_COMMAND } from 'lexical' +import lexicalImport from 'lexical' +const { $isRangeSelection, FORMAT_TEXT_COMMAND } = lexicalImport import type { FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/format/superscript/feature.client.tsx b/packages/richtext-lexical/src/field/features/format/superscript/feature.client.tsx index 0288ccae9..9c8dd0636 100644 --- a/packages/richtext-lexical/src/field/features/format/superscript/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/format/superscript/feature.client.tsx @@ -1,6 +1,7 @@ 'use client' -import { $isRangeSelection, FORMAT_TEXT_COMMAND } from 'lexical' +import lexicalImport from 'lexical' +const { $isRangeSelection, FORMAT_TEXT_COMMAND } = lexicalImport import type { FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/format/underline/feature.client.tsx b/packages/richtext-lexical/src/field/features/format/underline/feature.client.tsx index d30e3abc3..81feb6a0d 100644 --- a/packages/richtext-lexical/src/field/features/format/underline/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/format/underline/feature.client.tsx @@ -1,6 +1,7 @@ 'use client' -import { $isRangeSelection, FORMAT_TEXT_COMMAND } from 'lexical' +import lexicalImport from 'lexical' +const { $isRangeSelection, FORMAT_TEXT_COMMAND } = lexicalImport import type { FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/heading/feature.client.tsx b/packages/richtext-lexical/src/field/features/heading/feature.client.tsx index 8c13a5e6a..22afb62a4 100644 --- a/packages/richtext-lexical/src/field/features/heading/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/heading/feature.client.tsx @@ -2,10 +2,14 @@ import type { HeadingTagType } from '@lexical/rich-text' -import { HeadingNode } from '@lexical/rich-text' -import { $createHeadingNode } from '@lexical/rich-text' -import { $setBlocksType } from '@lexical/selection' -import { $getSelection } from 'lexical' +import lexicalRichTextImport from '@lexical/rich-text' +const { $createHeadingNode, HeadingNode } = lexicalRichTextImport + +import lexicalSelectionImport from '@lexical/selection' +const { $setBlocksType } = lexicalSelectionImport + +import lexicalImport from 'lexical' +const { $getSelection } = lexicalImport import type { FeatureProviderProviderClient } from '../types.js' import type { HeadingFeatureProps } from './feature.server.js' diff --git a/packages/richtext-lexical/src/field/features/heading/feature.server.ts b/packages/richtext-lexical/src/field/features/heading/feature.server.ts index a04b7ae09..98bb783d9 100644 --- a/packages/richtext-lexical/src/field/features/heading/feature.server.ts +++ b/packages/richtext-lexical/src/field/features/heading/feature.server.ts @@ -1,6 +1,7 @@ -import type { HeadingTagType } from '@lexical/rich-text' +import type { HeadingTagType, SerializedHeadingNode } from '@lexical/rich-text' -import { HeadingNode, type SerializedHeadingNode } from '@lexical/rich-text' +import lexicalRichTextImport from '@lexical/rich-text' +const { HeadingNode } = lexicalRichTextImport import type { HTMLConverter } from '../converters/html/converter/types.js' import type { FeatureProviderProviderServer } from '../types.js' diff --git a/packages/richtext-lexical/src/field/features/heading/markdownTransformer.ts b/packages/richtext-lexical/src/field/features/heading/markdownTransformer.ts index 9ae14e78c..466961865 100644 --- a/packages/richtext-lexical/src/field/features/heading/markdownTransformer.ts +++ b/packages/richtext-lexical/src/field/features/heading/markdownTransformer.ts @@ -1,7 +1,8 @@ import type { ElementTransformer } from '@lexical/markdown' import type { HeadingTagType } from '@lexical/rich-text' -import { $createHeadingNode, $isHeadingNode, HeadingNode } from '@lexical/rich-text' +import lexicalRichTextImport from '@lexical/rich-text' +const { $createHeadingNode, $isHeadingNode, HeadingNode } = lexicalRichTextImport import { createBlockNode } from '../../lexical/utils/markdown/createBlockNode.js' diff --git a/packages/richtext-lexical/src/field/features/indent/feature.client.tsx b/packages/richtext-lexical/src/field/features/indent/feature.client.tsx index aa25bb0fc..17f82b254 100644 --- a/packages/richtext-lexical/src/field/features/indent/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/indent/feature.client.tsx @@ -1,6 +1,7 @@ 'use client' -import { INDENT_CONTENT_COMMAND, OUTDENT_CONTENT_COMMAND } from 'lexical' +import lexicalImport from 'lexical' +const { INDENT_CONTENT_COMMAND, OUTDENT_CONTENT_COMMAND } = lexicalImport import type { FeatureProviderProviderClient } from '../types.js' diff --git a/packages/richtext-lexical/src/field/features/link/feature.client.tsx b/packages/richtext-lexical/src/field/features/link/feature.client.tsx index afc874f58..b893aef72 100644 --- a/packages/richtext-lexical/src/field/features/link/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/link/feature.client.tsx @@ -1,7 +1,10 @@ 'use client' -import { $findMatchingParent } from '@lexical/utils' -import { $getSelection, $isRangeSelection } from 'lexical' +import lexicalUtilsImport from '@lexical/utils' +const { $findMatchingParent } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { $getSelection, $isRangeSelection } = lexicalImport import type { FeatureProviderProviderClient } from '../types.js' import type { ExclusiveLinkCollectionsProps } from './feature.server.js' diff --git a/packages/richtext-lexical/src/field/features/link/nodes/AutoLinkNode.ts b/packages/richtext-lexical/src/field/features/link/nodes/AutoLinkNode.ts index b0228c80c..84ca07cf5 100644 --- a/packages/richtext-lexical/src/field/features/link/nodes/AutoLinkNode.ts +++ b/packages/richtext-lexical/src/field/features/link/nodes/AutoLinkNode.ts @@ -1,10 +1,7 @@ -import { - $applyNodeReplacement, - $isElementNode, - type ElementNode, - type LexicalNode, - type RangeSelection, -} from 'lexical' +import type { ElementNode, LexicalNode, RangeSelection } from 'lexical' + +import lexicalImport from 'lexical' +const { $applyNodeReplacement, $isElementNode } = lexicalImport import type { LinkFields, SerializedAutoLinkNode } from './types.js' diff --git a/packages/richtext-lexical/src/field/features/link/nodes/LinkNode.ts b/packages/richtext-lexical/src/field/features/link/nodes/LinkNode.ts index 40271bb54..7ba74f184 100644 --- a/packages/richtext-lexical/src/field/features/link/nodes/LinkNode.ts +++ b/packages/richtext-lexical/src/field/features/link/nodes/LinkNode.ts @@ -1,21 +1,28 @@ import type { BaseSelection } from 'lexical' -import { addClassNamesToElement, isHTMLAnchorElement } from '@lexical/utils' -import { +import lexicalUtilsImport from '@lexical/utils' +const { addClassNamesToElement, isHTMLAnchorElement } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { $applyNodeReplacement, $createTextNode, $getSelection, $isElementNode, $isRangeSelection, - type DOMConversionMap, - type DOMConversionOutput, - type EditorConfig, ElementNode, - type LexicalCommand, - type LexicalNode, - type NodeKey, - type RangeSelection, createCommand, +} = lexicalImport + +import type { + DOMConversionMap, + DOMConversionOutput, + EditorConfig, + ElementNode as ElementNodeType, + LexicalCommand, + LexicalNode, + NodeKey, + RangeSelection, } from 'lexical' import type { LinkPayload } from '../plugins/floatingLinkEditor/types.js' @@ -143,7 +150,7 @@ export class LinkNode extends ElementNode { return this.getLatest().__fields } - insertNewAfter(selection: RangeSelection, restoreSelection = true): ElementNode | null { + insertNewAfter(selection: RangeSelection, restoreSelection = true): ElementNodeType | null { const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection) if ($isElementNode(element)) { const linkNode = $createLinkNode({ fields: this.__fields }) @@ -284,7 +291,7 @@ export function toggleLink(payload: LinkPayload): void { } } - let prevParent: ElementNode | LinkNode | null = null + let prevParent: ElementNodeType | LinkNode | null = null let linkNode: LinkNode | null = null nodes.forEach((node) => { diff --git a/packages/richtext-lexical/src/field/features/link/plugins/autoLink/index.tsx b/packages/richtext-lexical/src/field/features/link/plugins/autoLink/index.tsx index 0f95a633e..3b7c31efe 100644 --- a/packages/richtext-lexical/src/field/features/link/plugins/autoLink/index.tsx +++ b/packages/richtext-lexical/src/field/features/link/plugins/autoLink/index.tsx @@ -1,9 +1,12 @@ 'use client' -import type { ElementNode, LexicalEditor, LexicalNode } from 'lexical' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { mergeRegister } from '@lexical/utils' -import { +import lexicalUtilsImport from '@lexical/utils' +const { mergeRegister } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { $createTextNode, $getSelection, $isElementNode, @@ -11,8 +14,12 @@ import { $isNodeSelection, $isRangeSelection, $isTextNode, - TextNode, -} from 'lexical' + TextNode: TextNodeValue, +} = lexicalImport + +import type { ElementNode, LexicalEditor, LexicalNode } from 'lexical' + +import { type TextNode } from 'lexical' import { useEffect } from 'react' import type { LinkFields } from '../../nodes/types.js' @@ -391,7 +398,7 @@ function useAutoLink( } return mergeRegister( - editor.registerNodeTransform(TextNode, (textNode: TextNode) => { + editor.registerNodeTransform(TextNodeValue, (textNode: TextNode) => { const parent = textNode.getParentOrThrow() const previous = textNode.getPreviousSibling() if ($isAutoLinkNode(parent)) { diff --git a/packages/richtext-lexical/src/field/features/link/plugins/floatingLinkEditor/LinkEditor/commands.ts b/packages/richtext-lexical/src/field/features/link/plugins/floatingLinkEditor/LinkEditor/commands.ts index 37209622d..29ac5b90f 100644 --- a/packages/richtext-lexical/src/field/features/link/plugins/floatingLinkEditor/LinkEditor/commands.ts +++ b/packages/richtext-lexical/src/field/features/link/plugins/floatingLinkEditor/LinkEditor/commands.ts @@ -1,6 +1,7 @@ import type { LexicalCommand } from 'lexical' -import { createCommand } from 'lexical' +import lexicalImport from 'lexical' +const { createCommand } = lexicalImport import type { LinkPayload } from '../types.js' diff --git a/packages/richtext-lexical/src/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.tsx b/packages/richtext-lexical/src/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.tsx index 0bcc473e7..db4973fa9 100644 --- a/packages/richtext-lexical/src/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.tsx +++ b/packages/richtext-lexical/src/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.tsx @@ -2,19 +2,24 @@ import type { FormState } from 'payload/types' import type { Data } from 'payload/types' -import { useModal } from '@faceless-ui/modal' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { $findMatchingParent, mergeRegister } from '@lexical/utils' +import * as facelessUIImport from '@faceless-ui/modal' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport + +import lexicalUtilsImport from '@lexical/utils' +const { $findMatchingParent, mergeRegister } = lexicalUtilsImport import { getTranslation } from '@payloadcms/translations' import { formatDrawerSlug, useConfig, useEditDepth, useTranslation } from '@payloadcms/ui' -import { +import lexicalImport from 'lexical' +const { $getSelection, $isRangeSelection, COMMAND_PRIORITY_HIGH, COMMAND_PRIORITY_LOW, KEY_ESCAPE_COMMAND, SELECTION_CHANGE_COMMAND, -} from 'lexical' +} = lexicalImport + import React, { useCallback, useEffect, useRef, useState } from 'react' import type { LinkNode } from '../../../nodes/LinkNode.js' @@ -30,6 +35,8 @@ import { $isLinkNode, TOGGLE_LINK_COMMAND } from '../../../nodes/LinkNode.js' import { TOGGLE_LINK_WITH_MODAL_COMMAND } from './commands.js' export function LinkEditor({ anchorElem }: { anchorElem: HTMLElement }): React.ReactNode { + const { useModal } = facelessUIImport + const [editor] = useLexicalComposerContext() const editorRef = useRef(null) diff --git a/packages/richtext-lexical/src/field/features/link/plugins/link/index.tsx b/packages/richtext-lexical/src/field/features/link/plugins/link/index.tsx index fb2262a1c..15e1beabb 100644 --- a/packages/richtext-lexical/src/field/features/link/plugins/link/index.tsx +++ b/packages/richtext-lexical/src/field/features/link/plugins/link/index.tsx @@ -1,13 +1,13 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { mergeRegister } from '@lexical/utils' -import { - $getSelection, - $isElementNode, - $isRangeSelection, - COMMAND_PRIORITY_LOW, - PASTE_COMMAND, -} from 'lexical' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport +import lexicalUtilsImport from '@lexical/utils' +const { mergeRegister } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { $getSelection, $isElementNode, $isRangeSelection, COMMAND_PRIORITY_LOW, PASTE_COMMAND } = + lexicalImport + import { useEffect } from 'react' import type { LinkFields } from '../../nodes/types.js' diff --git a/packages/richtext-lexical/src/field/features/lists/checklist/feature.client.tsx b/packages/richtext-lexical/src/field/features/lists/checklist/feature.client.tsx index aeb6291b6..30b3d16eb 100644 --- a/packages/richtext-lexical/src/field/features/lists/checklist/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/lists/checklist/feature.client.tsx @@ -1,5 +1,6 @@ 'use client' -import { INSERT_CHECK_LIST_COMMAND, ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { INSERT_CHECK_LIST_COMMAND, ListItemNode, ListNode } = lexicalListImport import type { ClientFeature, FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/lists/checklist/feature.server.ts b/packages/richtext-lexical/src/field/features/lists/checklist/feature.server.ts index 45e8fe4aa..28f179ad5 100644 --- a/packages/richtext-lexical/src/field/features/lists/checklist/feature.server.ts +++ b/packages/richtext-lexical/src/field/features/lists/checklist/feature.server.ts @@ -1,4 +1,5 @@ -import { ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { ListItemNode, ListNode } = lexicalListImport import type { FeatureProviderProviderServer } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/lists/checklist/markdownTransformers.ts b/packages/richtext-lexical/src/field/features/lists/checklist/markdownTransformers.ts index 5c40b9f60..d1c2061df 100644 --- a/packages/richtext-lexical/src/field/features/lists/checklist/markdownTransformers.ts +++ b/packages/richtext-lexical/src/field/features/lists/checklist/markdownTransformers.ts @@ -1,6 +1,7 @@ import type { ElementTransformer } from '@lexical/markdown' -import { $isListNode, ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { $isListNode, ListItemNode, ListNode } = lexicalListImport import { listExport, listReplace } from '../common/markdown.js' diff --git a/packages/richtext-lexical/src/field/features/lists/checklist/plugin/index.tsx b/packages/richtext-lexical/src/field/features/lists/checklist/plugin/index.tsx index 5b10eb34b..116c5b913 100644 --- a/packages/richtext-lexical/src/field/features/lists/checklist/plugin/index.tsx +++ b/packages/richtext-lexical/src/field/features/lists/checklist/plugin/index.tsx @@ -1,5 +1,7 @@ 'use client' -import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin.js' +import lexicalCheckListPluginImport from '@lexical/react/LexicalCheckListPlugin.js' +const { CheckListPlugin } = lexicalCheckListPluginImport + import React from 'react' export function LexicalCheckListPlugin() { diff --git a/packages/richtext-lexical/src/field/features/lists/common/markdown.ts b/packages/richtext-lexical/src/field/features/lists/common/markdown.ts index f13afada3..b1c3fbfc2 100644 --- a/packages/richtext-lexical/src/field/features/lists/common/markdown.ts +++ b/packages/richtext-lexical/src/field/features/lists/common/markdown.ts @@ -4,7 +4,8 @@ import type { ListNode, ListType } from '@lexical/list' import type { ElementTransformer } from '@lexical/markdown' import type { ElementNode } from 'lexical' -import { $createListItemNode, $createListNode, $isListItemNode, $isListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { $createListItemNode, $createListNode, $isListItemNode, $isListNode } = lexicalListImport // Amount of spaces that define indentation level const LIST_INDENT_SIZE = 4 diff --git a/packages/richtext-lexical/src/field/features/lists/htmlConverter.ts b/packages/richtext-lexical/src/field/features/lists/htmlConverter.ts index c3495bc59..e70ef4c51 100644 --- a/packages/richtext-lexical/src/field/features/lists/htmlConverter.ts +++ b/packages/richtext-lexical/src/field/features/lists/htmlConverter.ts @@ -1,6 +1,7 @@ import type { SerializedListItemNode, SerializedListNode } from '@lexical/list' -import { ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { ListItemNode, ListNode } = lexicalListImport import type { HTMLConverter } from '../converters/html/converter/types.js' diff --git a/packages/richtext-lexical/src/field/features/lists/orderedlist/feature.client.tsx b/packages/richtext-lexical/src/field/features/lists/orderedlist/feature.client.tsx index 0b6e4c83f..e058bc444 100644 --- a/packages/richtext-lexical/src/field/features/lists/orderedlist/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/lists/orderedlist/feature.client.tsx @@ -1,6 +1,6 @@ 'use client' - -import { INSERT_ORDERED_LIST_COMMAND, ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { INSERT_ORDERED_LIST_COMMAND, ListItemNode, ListNode } = lexicalListImport import type { FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/lists/orderedlist/feature.server.ts b/packages/richtext-lexical/src/field/features/lists/orderedlist/feature.server.ts index 773013a37..d4378cc35 100644 --- a/packages/richtext-lexical/src/field/features/lists/orderedlist/feature.server.ts +++ b/packages/richtext-lexical/src/field/features/lists/orderedlist/feature.server.ts @@ -1,4 +1,5 @@ -import { ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { ListItemNode, ListNode } = lexicalListImport import type { FeatureProviderProviderServer } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/lists/orderedlist/markdownTransformer.ts b/packages/richtext-lexical/src/field/features/lists/orderedlist/markdownTransformer.ts index 5b7a26dde..14bc38941 100644 --- a/packages/richtext-lexical/src/field/features/lists/orderedlist/markdownTransformer.ts +++ b/packages/richtext-lexical/src/field/features/lists/orderedlist/markdownTransformer.ts @@ -1,6 +1,7 @@ import type { ElementTransformer } from '@lexical/markdown' -import { $isListNode, ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { $isListNode, ListItemNode, ListNode } = lexicalListImport import { listExport, listReplace } from '../common/markdown.js' diff --git a/packages/richtext-lexical/src/field/features/lists/plugin/index.tsx b/packages/richtext-lexical/src/field/features/lists/plugin/index.tsx index 5dfbcabbd..3b8b9de65 100644 --- a/packages/richtext-lexical/src/field/features/lists/plugin/index.tsx +++ b/packages/richtext-lexical/src/field/features/lists/plugin/index.tsx @@ -1,5 +1,6 @@ 'use client' -import { ListPlugin } from '@lexical/react/LexicalListPlugin.js' +import lexicalListPluginImport from '@lexical/react/LexicalListPlugin.js' +const { ListPlugin } = lexicalListPluginImport import React from 'react' export function LexicalListPlugin() { diff --git a/packages/richtext-lexical/src/field/features/lists/unorderedlist/feature.client.tsx b/packages/richtext-lexical/src/field/features/lists/unorderedlist/feature.client.tsx index ad02749f0..fa8831638 100644 --- a/packages/richtext-lexical/src/field/features/lists/unorderedlist/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/lists/unorderedlist/feature.client.tsx @@ -1,6 +1,7 @@ 'use client' -import { INSERT_UNORDERED_LIST_COMMAND, ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { INSERT_UNORDERED_LIST_COMMAND, ListItemNode, ListNode } = lexicalListImport import type { FeatureProviderProviderClient } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/lists/unorderedlist/feature.server.ts b/packages/richtext-lexical/src/field/features/lists/unorderedlist/feature.server.ts index ca3c27588..29d176caf 100644 --- a/packages/richtext-lexical/src/field/features/lists/unorderedlist/feature.server.ts +++ b/packages/richtext-lexical/src/field/features/lists/unorderedlist/feature.server.ts @@ -1,4 +1,5 @@ -import { ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { ListItemNode, ListNode } = lexicalListImport import type { FeatureProviderProviderServer } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/lists/unorderedlist/markdownTransformer.ts b/packages/richtext-lexical/src/field/features/lists/unorderedlist/markdownTransformer.ts index 6c3563e4e..76e41679b 100644 --- a/packages/richtext-lexical/src/field/features/lists/unorderedlist/markdownTransformer.ts +++ b/packages/richtext-lexical/src/field/features/lists/unorderedlist/markdownTransformer.ts @@ -1,6 +1,7 @@ import type { ElementTransformer } from '@lexical/markdown' -import { $isListNode, ListItemNode, ListNode } from '@lexical/list' +import lexicalListImport from '@lexical/list' +const { $isListNode, ListItemNode, ListNode } = lexicalListImport import { listExport, listReplace } from '../common/markdown.js' diff --git a/packages/richtext-lexical/src/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/index.tsx b/packages/richtext-lexical/src/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/index.tsx index e2bbdfdf1..eb0404ed2 100644 --- a/packages/richtext-lexical/src/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/index.tsx +++ b/packages/richtext-lexical/src/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/index.tsx @@ -1,7 +1,13 @@ import type { SerializedLexicalNode, Spread } from 'lexical' -import { addClassNamesToElement } from '@lexical/utils' -import { DecoratorNode, type EditorConfig, type LexicalNode, type NodeKey } from 'lexical' +import lexicalUtilsImport from '@lexical/utils' +const { addClassNamesToElement } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { DecoratorNode } = lexicalImport + +import type { EditorConfig, LexicalNode, NodeKey } from 'lexical' + import * as React from 'react' export type UnknownConvertedNodeData = { diff --git a/packages/richtext-lexical/src/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/index.tsx b/packages/richtext-lexical/src/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/index.tsx index e2bbdfdf1..bf12eff92 100644 --- a/packages/richtext-lexical/src/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/index.tsx +++ b/packages/richtext-lexical/src/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/index.tsx @@ -1,7 +1,12 @@ import type { SerializedLexicalNode, Spread } from 'lexical' -import { addClassNamesToElement } from '@lexical/utils' -import { DecoratorNode, type EditorConfig, type LexicalNode, type NodeKey } from 'lexical' +import lexicalUtilsImport from '@lexical/utils' +const { addClassNamesToElement } = lexicalUtilsImport +import lexicalImport from 'lexical' +const { DecoratorNode } = lexicalImport + +import type { EditorConfig, LexicalNode, NodeKey } from 'lexical' + import * as React from 'react' export type UnknownConvertedNodeData = { diff --git a/packages/richtext-lexical/src/field/features/paragraph/feature.client.tsx b/packages/richtext-lexical/src/field/features/paragraph/feature.client.tsx index 8e3f0ccc0..c9550d6d1 100644 --- a/packages/richtext-lexical/src/field/features/paragraph/feature.client.tsx +++ b/packages/richtext-lexical/src/field/features/paragraph/feature.client.tsx @@ -1,7 +1,10 @@ 'use client' -import { $setBlocksType } from '@lexical/selection' -import { $createParagraphNode, $getSelection } from 'lexical' +import lexicalSelectionImport from '@lexical/selection' +const { $setBlocksType } = lexicalSelectionImport + +import lexicalImport from 'lexical' +const { $createParagraphNode, $getSelection } = lexicalImport import type { FeatureProviderProviderClient } from '../types.js' diff --git a/packages/richtext-lexical/src/field/features/relationship/drawer/commands.ts b/packages/richtext-lexical/src/field/features/relationship/drawer/commands.ts index 2d17b4552..13356d578 100644 --- a/packages/richtext-lexical/src/field/features/relationship/drawer/commands.ts +++ b/packages/richtext-lexical/src/field/features/relationship/drawer/commands.ts @@ -1,6 +1,7 @@ import type { LexicalCommand } from 'lexical' -import { createCommand } from 'lexical' +import lexicalImport from 'lexical' +const { createCommand } = lexicalImport export const INSERT_RELATIONSHIP_WITH_DRAWER_COMMAND: LexicalCommand<{ replace: { nodeKey: string } | false diff --git a/packages/richtext-lexical/src/field/features/relationship/drawer/index.tsx b/packages/richtext-lexical/src/field/features/relationship/drawer/index.tsx index c2196f04b..6b0f59951 100644 --- a/packages/richtext-lexical/src/field/features/relationship/drawer/index.tsx +++ b/packages/richtext-lexical/src/field/features/relationship/drawer/index.tsx @@ -1,7 +1,12 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport import { useListDrawer } from '@payloadcms/ui' -import { $getNodeByKey, COMMAND_PRIORITY_EDITOR, type LexicalEditor } from 'lexical' +import lexicalImport from 'lexical' +const { $getNodeByKey, COMMAND_PRIORITY_EDITOR } = lexicalImport + +import type { LexicalEditor } from 'lexical' + import React, { useCallback, useEffect, useState } from 'react' import { $createRelationshipNode } from '../nodes/RelationshipNode.js' diff --git a/packages/richtext-lexical/src/field/features/relationship/nodes/RelationshipNode.tsx b/packages/richtext-lexical/src/field/features/relationship/nodes/RelationshipNode.tsx index 4158751f8..85190e0ef 100644 --- a/packages/richtext-lexical/src/field/features/relationship/nodes/RelationshipNode.tsx +++ b/packages/richtext-lexical/src/field/features/relationship/nodes/RelationshipNode.tsx @@ -10,10 +10,11 @@ import type { Spread, } from 'lexical' -import { - DecoratorBlockNode, - type SerializedDecoratorBlockNode, -} from '@lexical/react/LexicalDecoratorBlockNode.js' +import lexicalDecoratorBlockNodeImport from '@lexical/react/LexicalDecoratorBlockNode.js' +const { DecoratorBlockNode } = lexicalDecoratorBlockNodeImport + +import type { SerializedDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js' + import * as React from 'react' const RelationshipComponent = React.lazy(() => diff --git a/packages/richtext-lexical/src/field/features/relationship/nodes/components/RelationshipComponent.tsx b/packages/richtext-lexical/src/field/features/relationship/nodes/components/RelationshipComponent.tsx index bf61df982..6f2778133 100644 --- a/packages/richtext-lexical/src/field/features/relationship/nodes/components/RelationshipComponent.tsx +++ b/packages/richtext-lexical/src/field/features/relationship/nodes/components/RelationshipComponent.tsx @@ -1,9 +1,14 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection.js' import { getTranslation } from '@payloadcms/translations' import { Button, useConfig, useDocumentDrawer, usePayloadAPI, useTranslation } from '@payloadcms/ui' -import { $getNodeByKey, type ElementFormatType } from 'lexical' +import lexicalImport from 'lexical' +const { $getNodeByKey } = lexicalImport + +import type { ElementFormatType } from 'lexical' + import React, { useCallback, useReducer, useState } from 'react' import type { RelationshipData } from '../RelationshipNode.js' diff --git a/packages/richtext-lexical/src/field/features/relationship/plugins/index.tsx b/packages/richtext-lexical/src/field/features/relationship/plugins/index.tsx index 7a60936a6..2f572c21b 100644 --- a/packages/richtext-lexical/src/field/features/relationship/plugins/index.tsx +++ b/packages/richtext-lexical/src/field/features/relationship/plugins/index.tsx @@ -1,16 +1,21 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { $insertNodeToNearestRoot } from '@lexical/utils' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport +import lexicalUtilsImport from '@lexical/utils' +const { $insertNodeToNearestRoot } = lexicalUtilsImport import { useConfig } from '@payloadcms/ui' -import { +import lexicalImport from 'lexical' +const { $getPreviousSelection, $getSelection, $isParagraphNode, $isRangeSelection, COMMAND_PRIORITY_EDITOR, - type LexicalCommand, createCommand, -} from 'lexical' +} = lexicalImport + +import type { LexicalCommand } from 'lexical' + import { useEffect } from 'react' import React from 'react' diff --git a/packages/richtext-lexical/src/field/features/upload/component/ExtraFieldsDrawer/index.tsx b/packages/richtext-lexical/src/field/features/upload/component/ExtraFieldsDrawer/index.tsx index 94d9ad218..e10c2ab26 100644 --- a/packages/richtext-lexical/src/field/features/upload/component/ExtraFieldsDrawer/index.tsx +++ b/packages/richtext-lexical/src/field/features/upload/component/ExtraFieldsDrawer/index.tsx @@ -1,8 +1,9 @@ 'use client' import type { FormState, SanitizedCollectionConfig } from 'payload/types' -import { useModal } from '@faceless-ui/modal' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import * as facelessUIImport from '@faceless-ui/modal' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport import { getTranslation } from '@payloadcms/translations' import { Drawer, @@ -17,7 +18,9 @@ import { useFieldPath, useTranslation, } from '@payloadcms/ui' -import { $getNodeByKey } from 'lexical' +import lexicalImport from 'lexical' +const { $getNodeByKey } = lexicalImport + import { deepCopyObject } from 'payload/utilities' import React, { useCallback, useEffect, useState } from 'react' import { v4 as uuid } from 'uuid' @@ -37,6 +40,8 @@ export const ExtraFieldsUploadDrawer: React.FC< relatedCollection: SanitizedCollectionConfig } > = (props) => { + const { useModal } = facelessUIImport + const { data: { fields, relationTo, value }, drawerSlug, diff --git a/packages/richtext-lexical/src/field/features/upload/component/index.tsx b/packages/richtext-lexical/src/field/features/upload/component/index.tsx index 36a46c0b2..e812ce48b 100644 --- a/packages/richtext-lexical/src/field/features/upload/component/index.tsx +++ b/packages/richtext-lexical/src/field/features/upload/component/index.tsx @@ -1,7 +1,8 @@ 'use client' import type { SanitizedCollectionConfig } from 'payload/types' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection.js' import { getTranslation } from '@payloadcms/translations' import { @@ -15,7 +16,9 @@ import { useThumbnail, useTranslation, } from '@payloadcms/ui' -import { $getNodeByKey } from 'lexical' +import lexicalImport from 'lexical' +const { $getNodeByKey } = lexicalImport + import React, { useCallback, useReducer, useState } from 'react' import type { ClientComponentProps } from '../../types.js' diff --git a/packages/richtext-lexical/src/field/features/upload/drawer/commands.ts b/packages/richtext-lexical/src/field/features/upload/drawer/commands.ts index a7812064f..956056b21 100644 --- a/packages/richtext-lexical/src/field/features/upload/drawer/commands.ts +++ b/packages/richtext-lexical/src/field/features/upload/drawer/commands.ts @@ -1,7 +1,8 @@ 'use client' import type { LexicalCommand } from 'lexical' -import { createCommand } from 'lexical' +import lexicalImport from 'lexical' +const { createCommand } = lexicalImport export const INSERT_UPLOAD_WITH_DRAWER_COMMAND: LexicalCommand<{ replace: { nodeKey: string } | false diff --git a/packages/richtext-lexical/src/field/features/upload/drawer/index.tsx b/packages/richtext-lexical/src/field/features/upload/drawer/index.tsx index 6beea4371..9d0b51395 100644 --- a/packages/richtext-lexical/src/field/features/upload/drawer/index.tsx +++ b/packages/richtext-lexical/src/field/features/upload/drawer/index.tsx @@ -1,7 +1,12 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport import { useListDrawer } from '@payloadcms/ui' -import { $getNodeByKey, COMMAND_PRIORITY_EDITOR, type LexicalEditor } from 'lexical' +import lexicalImport from 'lexical' +const { $getNodeByKey, COMMAND_PRIORITY_EDITOR } = lexicalImport + +import type { LexicalEditor } from 'lexical' + import React, { useCallback, useEffect, useState } from 'react' import { EnabledRelationshipsCondition } from '../../relationship/utils/EnabledRelationshipsCondition.js' diff --git a/packages/richtext-lexical/src/field/features/upload/nodes/UploadNode.tsx b/packages/richtext-lexical/src/field/features/upload/nodes/UploadNode.tsx index 155746c16..d18b76d86 100644 --- a/packages/richtext-lexical/src/field/features/upload/nodes/UploadNode.tsx +++ b/packages/richtext-lexical/src/field/features/upload/nodes/UploadNode.tsx @@ -1,15 +1,20 @@ import type { SerializedDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js' import type { ElementFormatType, NodeKey } from 'lexical' -import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js' -import { - $applyNodeReplacement, - type DOMConversionMap, - type DOMConversionOutput, - type DOMExportOutput, - type LexicalNode, - type Spread, +import lexicalDecoratorBlockNodeImport from '@lexical/react/LexicalDecoratorBlockNode.js' +const { DecoratorBlockNode } = lexicalDecoratorBlockNodeImport + +import lexicalImport from 'lexical' +const { $applyNodeReplacement } = lexicalImport + +import type { + DOMConversionMap, + DOMConversionOutput, + DOMExportOutput, + LexicalNode, + Spread, } from 'lexical' + import * as React from 'react' const RawUploadComponent = React.lazy(() => diff --git a/packages/richtext-lexical/src/field/features/upload/plugin/index.tsx b/packages/richtext-lexical/src/field/features/upload/plugin/index.tsx index 506bec6f1..5971e8615 100644 --- a/packages/richtext-lexical/src/field/features/upload/plugin/index.tsx +++ b/packages/richtext-lexical/src/field/features/upload/plugin/index.tsx @@ -1,16 +1,21 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { $insertNodeToNearestRoot, mergeRegister } from '@lexical/utils' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport +import lexicalUtilsImport from '@lexical/utils' +const { $insertNodeToNearestRoot, mergeRegister } = lexicalUtilsImport import { useConfig } from '@payloadcms/ui' -import { +import lexicalImport from 'lexical' +const { $getPreviousSelection, $getSelection, $isParagraphNode, $isRangeSelection, COMMAND_PRIORITY_EDITOR, - type LexicalCommand, createCommand, -} from 'lexical' +} = lexicalImport + +import type { LexicalCommand } from 'lexical' + import React, { useEffect } from 'react' import type { RawUploadPayload } from '../nodes/UploadNode.js' diff --git a/packages/richtext-lexical/src/field/lexical/LexicalEditor.tsx b/packages/richtext-lexical/src/field/lexical/LexicalEditor.tsx index 5ec4a9d9c..6bd2e724f 100644 --- a/packages/richtext-lexical/src/field/lexical/LexicalEditor.tsx +++ b/packages/richtext-lexical/src/field/lexical/LexicalEditor.tsx @@ -1,10 +1,20 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport + import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary.js' -import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin.js' -import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin.js' -import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin.js' -import { TabIndentationPlugin } from '@lexical/react/LexicalTabIndentationPlugin.js' +import lexicalHistoryPluginImport from '@lexical/react/LexicalHistoryPlugin.js' +const { HistoryPlugin } = lexicalHistoryPluginImport + +import lexicalOnChangePluginImport from '@lexical/react/LexicalOnChangePlugin.js' +const { OnChangePlugin } = lexicalOnChangePluginImport + +import lexicalRichTextPluginImport from '@lexical/react/LexicalRichTextPlugin.js' +const { RichTextPlugin } = lexicalRichTextPluginImport + +import lexicalTabIndentationPluginImport from '@lexical/react/LexicalTabIndentationPlugin.js' +const { TabIndentationPlugin } = lexicalTabIndentationPluginImport + import * as React from 'react' import { useEffect, useState } from 'react' diff --git a/packages/richtext-lexical/src/field/lexical/LexicalProvider.tsx b/packages/richtext-lexical/src/field/lexical/LexicalProvider.tsx index 03c0e76a0..a530afff1 100644 --- a/packages/richtext-lexical/src/field/lexical/LexicalProvider.tsx +++ b/packages/richtext-lexical/src/field/lexical/LexicalProvider.tsx @@ -3,7 +3,11 @@ import type { FormFieldBase } from '@payloadcms/ui' import type { EditorState, SerializedEditorState } from 'lexical' import type { LexicalEditor } from 'lexical' -import { type InitialConfigType, LexicalComposer } from '@lexical/react/LexicalComposer.js' +import lexicalComposerImport from '@lexical/react/LexicalComposer.js' +const { LexicalComposer } = lexicalComposerImport + +import type { InitialConfigType } from '@lexical/react/LexicalComposer.js' + import * as React from 'react' import type { SanitizedClientEditorConfig } from './config/types.js' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/ToolbarButton/index.tsx b/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/ToolbarButton/index.tsx index ec1ce22d8..f2a980861 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/ToolbarButton/index.tsx +++ b/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/ToolbarButton/index.tsx @@ -1,7 +1,12 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { mergeRegister } from '@lexical/utils' -import { $getSelection } from 'lexical' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport +import lexicalUtilsImport from '@lexical/utils' +const { mergeRegister } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { $getSelection } = lexicalImport + import React, { useCallback, useEffect, useState } from 'react' import type { FloatingToolbarSectionEntry } from '../types.js' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/ToolbarDropdown/DropDown.tsx b/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/ToolbarDropdown/DropDown.tsx index 56a27969c..84d7549e5 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/ToolbarDropdown/DropDown.tsx +++ b/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/ToolbarDropdown/DropDown.tsx @@ -1,7 +1,13 @@ 'use client' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { mergeRegister } from '@lexical/utils' -import { $getSelection } from 'lexical' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport + +import lexicalUtilsImport from '@lexical/utils' +const { mergeRegister } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { $getSelection } = lexicalImport + import { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react' import React from 'react' import { createPortal } from 'react-dom' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/index.tsx b/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/index.tsx index b7f1778d8..49e89975b 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/index.tsx +++ b/packages/richtext-lexical/src/field/lexical/plugins/FloatingSelectToolbar/index.tsx @@ -1,15 +1,21 @@ 'use client' import type { LexicalEditor } from 'lexical' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { mergeRegister } from '@lexical/utils' -import { +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport + +import lexicalUtilsImport from '@lexical/utils' +const { mergeRegister } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { $getSelection, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_LOW, SELECTION_CHANGE_COMMAND, -} from 'lexical' +} = lexicalImport + import { useCallback, useEffect, useRef, useState } from 'react' import * as React from 'react' import { createPortal } from 'react-dom' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/MarkdownShortcut/index.tsx b/packages/richtext-lexical/src/field/lexical/plugins/MarkdownShortcut/index.tsx index 7d7a71433..62c7fce10 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/MarkdownShortcut/index.tsx +++ b/packages/richtext-lexical/src/field/lexical/plugins/MarkdownShortcut/index.tsx @@ -1,5 +1,9 @@ 'use client' -import { MarkdownShortcutPlugin as LexicalMarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin.js' + +import lexicalMarkdownShortcutPluginImport from '@lexical/react/LexicalMarkdownShortcutPlugin.js' +const { MarkdownShortcutPlugin: LexicalMarkdownShortcutPlugin } = + lexicalMarkdownShortcutPluginImport + import * as React from 'react' import { useEditorConfigContext } from '../../config/client/EditorConfigProvider.js' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.tsx b/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.tsx index d2419c62f..a7b2b694e 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.tsx +++ b/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.tsx @@ -2,9 +2,14 @@ import type { LexicalCommand, LexicalEditor, TextNode } from 'lexical' import type { MutableRefObject, ReactPortal } from 'react' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { mergeRegister } from '@lexical/utils' -import { +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport + +import lexicalUtilsImport from '@lexical/utils' +const { mergeRegister } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { $getSelection, $isRangeSelection, COMMAND_PRIORITY_LOW, @@ -14,7 +19,8 @@ import { KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, createCommand, -} from 'lexical' +} = lexicalImport + import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react' import type { MenuTextMatch } from '../useMenuTriggerMatch.js' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index.tsx b/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index.tsx index 569e622c6..ff28141db 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index.tsx +++ b/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index.tsx @@ -7,15 +7,16 @@ import type { TextNode, } from 'lexical' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { mergeRegister } from '@lexical/utils' -import { - $getSelection, - $isRangeSelection, - $isTextNode, - COMMAND_PRIORITY_LOW, - createCommand, -} from 'lexical' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport + +import lexicalUtilsImport from '@lexical/utils' +const { mergeRegister } = lexicalUtilsImport + +import lexicalImport from 'lexical' +const { $getSelection, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_LOW, createCommand } = + lexicalImport + import { useCallback, useEffect, useState } from 'react' import * as React from 'react' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/index.tsx b/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/index.tsx index f0f48eb2d..7b65e04de 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/index.tsx +++ b/packages/richtext-lexical/src/field/lexical/plugins/SlashMenu/index.tsx @@ -1,7 +1,9 @@ 'use client' import type { TextNode } from 'lexical' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport + import { useTranslation } from '@payloadcms/ui' import { useCallback, useMemo, useState } from 'react' import * as React from 'react' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/handles/AddBlockHandlePlugin/index.tsx b/packages/richtext-lexical/src/field/lexical/plugins/handles/AddBlockHandlePlugin/index.tsx index bf2bb7d3b..9c758c99f 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/handles/AddBlockHandlePlugin/index.tsx +++ b/packages/richtext-lexical/src/field/lexical/plugins/handles/AddBlockHandlePlugin/index.tsx @@ -1,9 +1,11 @@ 'use client' -import type { ParagraphNode } from 'lexical' +import type { LexicalEditor, LexicalNode, ParagraphNode } from 'lexical' + +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport +import lexicalImport from 'lexical' +const { $createParagraphNode, $getNodeByKey } = lexicalImport -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' -import { $createParagraphNode } from 'lexical' -import { $getNodeByKey, type LexicalEditor, type LexicalNode } from 'lexical' import * as React from 'react' import { useCallback, useEffect, useRef, useState } from 'react' import { createPortal } from 'react-dom' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/handles/DraggableBlockPlugin/getNodeCloseToPoint.ts b/packages/richtext-lexical/src/field/lexical/plugins/handles/DraggableBlockPlugin/getNodeCloseToPoint.ts index b625e1b64..5ad760e1d 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/handles/DraggableBlockPlugin/getNodeCloseToPoint.ts +++ b/packages/richtext-lexical/src/field/lexical/plugins/handles/DraggableBlockPlugin/getNodeCloseToPoint.ts @@ -1,6 +1,7 @@ import type { LexicalEditor, LexicalNode } from 'lexical' -import { $getNodeByKey } from 'lexical' +import lexicalImport from 'lexical' +const { $getNodeByKey } = lexicalImport import { Point } from '../../../utils/point.js' import { Rect } from '../../../utils/rect.js' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/handles/DraggableBlockPlugin/index.tsx b/packages/richtext-lexical/src/field/lexical/plugins/handles/DraggableBlockPlugin/index.tsx index 98fd563f3..f1ac8fbc8 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/handles/DraggableBlockPlugin/index.tsx +++ b/packages/richtext-lexical/src/field/lexical/plugins/handles/DraggableBlockPlugin/index.tsx @@ -2,9 +2,12 @@ import type { LexicalEditor } from 'lexical' import type { DragEvent as ReactDragEvent } from 'react' -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js' +import lexicalComposerContextImport from '@lexical/react/LexicalComposerContext.js' +const { useLexicalComposerContext } = lexicalComposerContextImport + import { eventFiles } from '@lexical/rich-text' -import { $getNearestNodeFromDOMNode, $getNodeByKey } from 'lexical' +import lexicalImport from 'lexical' +const { $getNearestNodeFromDOMNode, $getNodeByKey } = lexicalImport import * as React from 'react' import { useCallback, useEffect, useRef, useState } from 'react' import { createPortal } from 'react-dom' diff --git a/packages/richtext-lexical/src/field/lexical/plugins/handles/utils/getTopLevelNodeKeys.ts b/packages/richtext-lexical/src/field/lexical/plugins/handles/utils/getTopLevelNodeKeys.ts index f9b5218b4..8b45f5d09 100644 --- a/packages/richtext-lexical/src/field/lexical/plugins/handles/utils/getTopLevelNodeKeys.ts +++ b/packages/richtext-lexical/src/field/lexical/plugins/handles/utils/getTopLevelNodeKeys.ts @@ -1,6 +1,7 @@ import type { LexicalEditor } from 'lexical' -import { $getRoot } from 'lexical' +import lexicalImport from 'lexical' +const { $getRoot } = lexicalImport export function getTopLevelNodeKeys(editor: LexicalEditor): string[] { return editor.getEditorState().read(() => $getRoot().getChildrenKeys()) diff --git a/packages/richtext-lexical/src/field/lexical/ui/ContentEditable.tsx b/packages/richtext-lexical/src/field/lexical/ui/ContentEditable.tsx index 5ab64ac1b..af1311d8e 100644 --- a/packages/richtext-lexical/src/field/lexical/ui/ContentEditable.tsx +++ b/packages/richtext-lexical/src/field/lexical/ui/ContentEditable.tsx @@ -1,4 +1,6 @@ -import { ContentEditable } from '@lexical/react/LexicalContentEditable.js' +import lexicalContentEditableImport from '@lexical/react/LexicalContentEditable.js' +const { ContentEditable } = lexicalContentEditableImport + import * as React from 'react' import './ContentEditable.scss' diff --git a/packages/richtext-lexical/src/field/lexical/utils/cloneDeep.ts b/packages/richtext-lexical/src/field/lexical/utils/cloneDeep.ts index 601025c30..27fd76752 100644 --- a/packages/richtext-lexical/src/field/lexical/utils/cloneDeep.ts +++ b/packages/richtext-lexical/src/field/lexical/utils/cloneDeep.ts @@ -37,6 +37,10 @@ export function cloneDeep(object: T, cache: WeakMap = new WeakMap() // Handle Array and Object if (typeof object === 'object' && object !== null) { + if ('$$typeof' in object && typeof object.$$typeof === 'symbol') { + return object + } + const clonedObject: any = Array.isArray(object) ? [] : Object.create(Object.getPrototypeOf(object)) diff --git a/packages/richtext-lexical/src/field/lexical/utils/getSelectedNode.ts b/packages/richtext-lexical/src/field/lexical/utils/getSelectedNode.ts index 21bcdbb35..e88d1f8d2 100644 --- a/packages/richtext-lexical/src/field/lexical/utils/getSelectedNode.ts +++ b/packages/richtext-lexical/src/field/lexical/utils/getSelectedNode.ts @@ -1,5 +1,7 @@ -import { $isAtNodeEnd } from '@lexical/selection' -import { type ElementNode, type RangeSelection, type TextNode } from 'lexical' +import lexicalSelectionImport from '@lexical/selection' +const { $isAtNodeEnd } = lexicalSelectionImport + +import type { ElementNode, RangeSelection, TextNode } from 'lexical' export function getSelectedNode(selection: RangeSelection): ElementNode | TextNode { const { anchor } = selection diff --git a/packages/richtext-slate/package.json b/packages/richtext-slate/package.json index 266176546..0ff1c41bc 100644 --- a/packages/richtext-slate/package.json +++ b/packages/richtext-slate/package.json @@ -1,6 +1,6 @@ { "name": "@payloadcms/richtext-slate", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "description": "The officially supported Slate richtext adapter for Payload", "repository": "https://github.com/payloadcms/payload", "license": "MIT", diff --git a/packages/richtext-slate/src/field/elements/link/Button/index.tsx b/packages/richtext-slate/src/field/elements/link/Button/index.tsx index da50424e6..fc7af2147 100644 --- a/packages/richtext-slate/src/field/elements/link/Button/index.tsx +++ b/packages/richtext-slate/src/field/elements/link/Button/index.tsx @@ -2,7 +2,7 @@ import type { FormState } from 'payload/types' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getFormState, reduceFieldsToValues, @@ -63,6 +63,8 @@ const insertLink = (editor, fields) => { } export const LinkButton: React.FC = () => { + const { useModal } = facelessUIImport + const { fieldProps } = useElementButton() const [initialState, setInitialState] = useState({}) diff --git a/packages/richtext-slate/src/field/elements/link/Element/index.tsx b/packages/richtext-slate/src/field/elements/link/Element/index.tsx index d0231b651..be0910752 100644 --- a/packages/richtext-slate/src/field/elements/link/Element/index.tsx +++ b/packages/richtext-slate/src/field/elements/link/Element/index.tsx @@ -2,7 +2,7 @@ import type { FormState } from 'payload/types' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' import { Button, @@ -60,6 +60,7 @@ const insertChange = (editor, fields) => { export const LinkElement = () => { const { attributes, children, editorRef, element, fieldProps, schemaPath } = useElement() + const { useModal } = facelessUIImport const fieldMapPath = `${schemaPath}.${linkFieldsSchemaPath}` diff --git a/packages/richtext-slate/src/field/elements/upload/Element/UploadDrawer/index.tsx b/packages/richtext-slate/src/field/elements/upload/Element/UploadDrawer/index.tsx index a9ff2353a..3f424d3df 100644 --- a/packages/richtext-slate/src/field/elements/upload/Element/UploadDrawer/index.tsx +++ b/packages/richtext-slate/src/field/elements/upload/Element/UploadDrawer/index.tsx @@ -3,7 +3,7 @@ import type { FormFieldBase } from '@payloadcms/ui/types' import type { SanitizedCollectionConfig } from 'payload/types' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' import { Drawer, @@ -37,6 +37,8 @@ export const UploadDrawer: React.FC<{ relatedCollection: SanitizedCollectionConfig schemaPath: string }> = (props) => { + const { useModal } = facelessUIImport + const editor = useSlateStatic() const { drawerSlug, element, fieldProps, relatedCollection, schemaPath } = props diff --git a/packages/translations/package.json b/packages/translations/package.json index b1518d4d6..6af397482 100644 --- a/packages/translations/package.json +++ b/packages/translations/package.json @@ -1,6 +1,6 @@ { "name": "@payloadcms/translations", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "main": "./dist/exports/index.ts", "types": "./dist/types.d.ts", "type": "module", diff --git a/packages/translations/src/_generatedFiles_/client/nl.json b/packages/translations/src/_generatedFiles_/client/nl.json index 2eddc769f..de9464251 100644 --- a/packages/translations/src/_generatedFiles_/client/nl.json +++ b/packages/translations/src/_generatedFiles_/client/nl.json @@ -210,7 +210,7 @@ "near": "nabij" }, "upload": { - "crop": "Gewas", + "crop": "Bijsnijden", "cropToolDescription": "Sleep de hoeken van het geselecteerde gebied, teken een nieuw gebied of pas de waarden hieronder aan.", "dragAndDrop": "Sleep een bestand", "editImage": "Afbeelding bewerken", @@ -220,7 +220,7 @@ "previewSizes": "Voorbeeldgroottes", "selectCollectionToBrowse": "Selecteer een collectie om door te bladeren", "selectFile": "Selecteer een bestand", - "setCropArea": "Stel oogstgebied in", + "setCropArea": "Stel bijsnijdgebied in", "setFocalPoint": "Stel het brandpunt in", "sizesFor": "Maten voor {{label}}", "width": "Breedte" diff --git a/packages/translations/src/all/nl.json b/packages/translations/src/all/nl.json index 73085656d..442d599cc 100644 --- a/packages/translations/src/all/nl.json +++ b/packages/translations/src/all/nl.json @@ -274,7 +274,7 @@ "near": "nabij" }, "upload": { - "crop": "Gewas", + "crop": "Bijsnijden", "cropToolDescription": "Sleep de hoeken van het geselecteerde gebied, teken een nieuw gebied of pas de waarden hieronder aan.", "dragAndDrop": "Sleep een bestand", "dragAndDropHere": "of sleep een bestand naar hier", @@ -289,7 +289,7 @@ "previewSizes": "Voorbeeldgroottes", "selectCollectionToBrowse": "Selecteer een collectie om door te bladeren", "selectFile": "Selecteer een bestand", - "setCropArea": "Stel oogstgebied in", + "setCropArea": "Stel bijsnijdgebied in", "setFocalPoint": "Stel het brandpunt in", "sizes": "Groottes", "sizesFor": "Maten voor {{label}}", diff --git a/packages/ui/package.json b/packages/ui/package.json index 2c0e2d71e..0c42c3e6c 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@payloadcms/ui", - "version": "3.0.0-alpha.31", + "version": "3.0.0-alpha.34", "main": "./src/index.ts", "types": "./dist/index.d.ts", "type": "module", diff --git a/packages/ui/src/elements/DeleteDocument/index.tsx b/packages/ui/src/elements/DeleteDocument/index.tsx index 73cb37707..764c802ce 100644 --- a/packages/ui/src/elements/DeleteDocument/index.tsx +++ b/packages/ui/src/elements/DeleteDocument/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { Modal, useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' import { useRouter } from 'next/navigation.js' import React, { useCallback, useState } from 'react' @@ -22,6 +22,7 @@ const baseClass = 'delete-document' const DeleteDocument: React.FC = (props) => { const { id, buttonId, collectionSlug, singularLabel, title: titleFromProps } = props + const { Modal, useModal } = facelessUIImport const { routes: { admin, api }, diff --git a/packages/ui/src/elements/DeleteMany/index.tsx b/packages/ui/src/elements/DeleteMany/index.tsx index c98932d37..941058bc1 100644 --- a/packages/ui/src/elements/DeleteMany/index.tsx +++ b/packages/ui/src/elements/DeleteMany/index.tsx @@ -1,6 +1,7 @@ 'use client' -import { Modal, useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' +import { useRouter } from 'next/navigation.js' import React, { useCallback, useState } from 'react' import { toast } from 'react-toastify' @@ -20,6 +21,8 @@ import './index.scss' const baseClass = 'delete-documents' export const DeleteMany: React.FC = (props) => { + const { Modal, useModal } = facelessUIImport + const { collection: { slug, labels: { plural } } = {} } = props const { permissions } = useAuth() @@ -31,7 +34,8 @@ export const DeleteMany: React.FC = (props) => { const { count, getQueryParams, selectAll, toggleAll } = useSelection() const { i18n, t } = useTranslation() const [deleting, setDeleting] = useState(false) - const { dispatchSearchParams } = useSearchParams() + const router = useRouter() + const { stringifyParams } = useSearchParams() const collectionPermissions = permissions?.collections?.[slug] const hasDeletePermission = collectionPermissions?.delete?.permission @@ -58,11 +62,14 @@ export const DeleteMany: React.FC = (props) => { if (res.status < 400) { toast.success(json.message || t('general:deletedSuccessfully'), { autoClose: 3000 }) toggleAll() - dispatchSearchParams({ - type: 'SET', - browserHistory: 'replace', - params: { page: selectAll ? '1' : undefined }, - }) + router.replace( + stringifyParams({ + params: { + page: selectAll ? '1' : undefined, + }, + replace: true, + }), + ) return null } @@ -79,13 +86,14 @@ export const DeleteMany: React.FC = (props) => { }, [ addDefaultError, api, - dispatchSearchParams, getQueryParams, i18n.language, modalSlug, + router, selectAll, serverURL, slug, + stringifyParams, t, toggleAll, toggleModal, diff --git a/packages/ui/src/elements/DocumentDrawer/DrawerContent.tsx b/packages/ui/src/elements/DocumentDrawer/DrawerContent.tsx index ee47cda74..da2b1cda0 100644 --- a/packages/ui/src/elements/DocumentDrawer/DrawerContent.tsx +++ b/packages/ui/src/elements/DocumentDrawer/DrawerContent.tsx @@ -2,7 +2,7 @@ import type { FormState } from 'payload/types' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' import queryString from 'qs' import React, { useCallback, useEffect, useRef, useState } from 'react' @@ -33,6 +33,8 @@ const Content: React.FC = ({ drawerSlug, onSave, }) => { + const { useModal } = facelessUIImport + const config = useConfig() const { diff --git a/packages/ui/src/elements/DocumentDrawer/index.tsx b/packages/ui/src/elements/DocumentDrawer/index.tsx index c8aa34958..428470126 100644 --- a/packages/ui/src/elements/DocumentDrawer/index.tsx +++ b/packages/ui/src/elements/DocumentDrawer/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' import React, { useCallback, useEffect, useId, useMemo, useState } from 'react' @@ -64,6 +64,8 @@ export const DocumentDrawer: React.FC = (props) => { } export const useDocumentDrawer: UseDocumentDrawer = ({ id, collectionSlug }) => { + const { useModal } = facelessUIImport + const drawerDepth = useEditDepth() const uuid = useId() const { closeModal, modalState, openModal, toggleModal } = useModal() diff --git a/packages/ui/src/elements/Drawer/index.tsx b/packages/ui/src/elements/Drawer/index.tsx index d1b095ca6..bc2931ab6 100644 --- a/packages/ui/src/elements/Drawer/index.tsx +++ b/packages/ui/src/elements/Drawer/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { Modal, useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import React, { useCallback, useEffect, useState } from 'react' import type { Props, TogglerProps } from './types.js' @@ -24,6 +24,8 @@ export const DrawerToggler: React.FC = ({ onClick, ...rest }) => { + const { Modal, useModal } = facelessUIImport + const { openModal } = useModal() const handleClick = useCallback( @@ -50,6 +52,8 @@ export const Drawer: React.FC = ({ hoverTitle, title, }) => { + const { Modal, useModal } = facelessUIImport + const { t } = useTranslation() const { closeModal, modalState } = useModal() const drawerDepth = useEditDepth() diff --git a/packages/ui/src/elements/DuplicateDocument/index.tsx b/packages/ui/src/elements/DuplicateDocument/index.tsx index 1f1c2f946..6a8e98a20 100644 --- a/packages/ui/src/elements/DuplicateDocument/index.tsx +++ b/packages/ui/src/elements/DuplicateDocument/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { Modal, useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' import { useRouter } from 'next/navigation.js' import React, { useCallback, useState } from 'react' @@ -19,6 +19,8 @@ import './index.scss' const baseClass = 'duplicate' const Duplicate: React.FC = ({ id, slug, singularLabel }) => { + const { Modal, useModal } = facelessUIImport + const { push } = useRouter() const modified = useFormModified() const { toggleModal } = useModal() diff --git a/packages/ui/src/elements/EditMany/index.tsx b/packages/ui/src/elements/EditMany/index.tsx index b681c9a96..e9643fe51 100644 --- a/packages/ui/src/elements/EditMany/index.tsx +++ b/packages/ui/src/elements/EditMany/index.tsx @@ -1,8 +1,9 @@ 'use client' import type { FormState } from 'payload/types' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' +import { useRouter } from 'next/navigation.js' import React, { useCallback, useState } from 'react' import type { Props } from './types.js' @@ -89,6 +90,8 @@ const SaveDraft: React.FC<{ action: string; disabled: boolean }> = ({ action, di ) } export const EditMany: React.FC = (props) => { + const { Modal, useModal } = facelessUIImport + const { collection: { slug, fields, labels: { plural } } = {}, collection } = props const { permissions } = useAuth() @@ -100,7 +103,8 @@ export const EditMany: React.FC = (props) => { const { count, getQueryParams, selectAll } = useSelection() const { i18n, t } = useTranslation() const [selected, setSelected] = useState([]) - const { dispatchSearchParams } = useSearchParams() + const { stringifyParams } = useSearchParams() + const router = useRouter() const { componentMap } = useComponentMap() const [reducedFieldMap, setReducedFieldMap] = useState([]) const [initialState, setInitialState] = useState() @@ -153,11 +157,11 @@ export const EditMany: React.FC = (props) => { } const onSuccess = () => { - dispatchSearchParams({ - type: 'SET', - browserHistory: 'replace', - params: { page: selectAll === SelectAllStatus.AllAvailable ? '1' : undefined }, - }) + router.replace( + stringifyParams({ + params: { page: selectAll === SelectAllStatus.AllAvailable ? '1' : undefined }, + }), + ) } return ( diff --git a/packages/ui/src/elements/EditUpload/index.tsx b/packages/ui/src/elements/EditUpload/index.tsx index 6c14b1f75..1919f3aa0 100644 --- a/packages/ui/src/elements/EditUpload/index.tsx +++ b/packages/ui/src/elements/EditUpload/index.tsx @@ -1,10 +1,10 @@ 'use client' import type { Data } from 'payload/types' +import type CropType from 'react-image-crop' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import React, { useRef, useState } from 'react' import ReactCrop from 'react-image-crop' -import type CropType from 'react-image-crop' import 'react-image-crop/dist/ReactCrop.css' import { editDrawerSlug } from '../../elements/Upload/index.js' @@ -35,6 +35,8 @@ export const EditUpload: React.FC<{ showCrop?: boolean showFocalPoint?: boolean }> = ({ fileName, fileSrc, imageCacheTag, showCrop, showFocalPoint }) => { + const { Modal, useModal } = facelessUIImport + const { closeModal } = useModal() const { t } = useTranslation() const { dispatchFormQueryParams, formQueryParams } = useFormQueryParams() diff --git a/packages/ui/src/elements/GenerateConfirmation/index.tsx b/packages/ui/src/elements/GenerateConfirmation/index.tsx index 98102e3cf..c12c6b95f 100644 --- a/packages/ui/src/elements/GenerateConfirmation/index.tsx +++ b/packages/ui/src/elements/GenerateConfirmation/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { Modal, useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import React from 'react' import { toast } from 'react-toastify' @@ -15,6 +15,8 @@ import './index.scss' const baseClass = 'generate-confirmation' const GenerateConfirmation: React.FC = (props) => { + const { Modal, useModal } = facelessUIImport + const { highlightField, setKey } = props const { id } = useDocumentInfo() diff --git a/packages/ui/src/elements/ListControls/index.tsx b/packages/ui/src/elements/ListControls/index.tsx index c5ccbc9d4..4aa5a8e46 100644 --- a/packages/ui/src/elements/ListControls/index.tsx +++ b/packages/ui/src/elements/ListControls/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { useWindowInfo } from '@faceless-ui/window-info' +import * as facelessUIImport from '@faceless-ui/window-info' import { getTranslation } from '@payloadcms/translations' import { fieldAffectsData } from 'payload/types' import React, { useState } from 'react' @@ -44,6 +44,8 @@ export const ListControls: React.FC = (props) => { titleField, } = props + const { useWindowInfo } = facelessUIImport + const { searchParams } = useSearchParams() const shouldInitializeWhereOpened = validateWhereQuery(searchParams?.where) diff --git a/packages/ui/src/elements/ListDrawer/DrawerContent.tsx b/packages/ui/src/elements/ListDrawer/DrawerContent.tsx index 3b850b6f6..3cd4d2678 100644 --- a/packages/ui/src/elements/ListDrawer/DrawerContent.tsx +++ b/packages/ui/src/elements/ListDrawer/DrawerContent.tsx @@ -2,7 +2,7 @@ import type { SanitizedCollectionConfig } from 'payload/types' import type { Where } from 'payload/types' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' import React, { useCallback, useEffect, useReducer, useState } from 'react' @@ -51,6 +51,8 @@ export const ListDrawerContent: React.FC = ({ onSelect, selectedCollection, }) => { + const { useModal } = facelessUIImport + const { i18n, t } = useTranslation() const { permissions } = useAuth() const { setPreference } = usePreferences() diff --git a/packages/ui/src/elements/ListDrawer/index.tsx b/packages/ui/src/elements/ListDrawer/index.tsx index 587e522f1..6e162af20 100644 --- a/packages/ui/src/elements/ListDrawer/index.tsx +++ b/packages/ui/src/elements/ListDrawer/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import React, { useCallback, useEffect, useId, useMemo, useState } from 'react' import type { ListDrawerProps, ListTogglerProps, UseListDrawer } from './types.js' @@ -55,6 +55,8 @@ export const useListDrawer: UseListDrawer = ({ selectedCollection, uploads, }) => { + const { useModal } = facelessUIImport + const { collections } = useConfig() const drawerDepth = useEditDepth() const uuid = useId() diff --git a/packages/ui/src/elements/Localizer/index.tsx b/packages/ui/src/elements/Localizer/index.tsx index 85affd629..fe4b06095 100644 --- a/packages/ui/src/elements/Localizer/index.tsx +++ b/packages/ui/src/elements/Localizer/index.tsx @@ -1,4 +1,5 @@ import { getTranslation } from '@payloadcms/translations' +import { useRouter } from 'next/navigation.js' import React from 'react' import { useConfig } from '../../providers/Config/index.js' @@ -21,7 +22,8 @@ const Localizer: React.FC<{ const { i18n } = useTranslation() const locale = useLocale() - const { dispatchSearchParams, searchParams } = useSearchParams() + const { stringifyParams } = useSearchParams() + const router = useRouter() if (localization) { const { locales } = localization @@ -34,25 +36,21 @@ const Localizer: React.FC<{ render={({ close }) => ( {locales.map((localeOption) => { - const newParams = { - ...searchParams, - locale: localeOption.code, - } const localeOptionLabel = getTranslation(localeOption.label, i18n) return ( { + router.replace( + stringifyParams({ + params: { + locale: localeOption.code, + }, + }), + ) close() - dispatchSearchParams({ - type: 'SET', - params: { - locale: searchParams.locale, - }, - }) }} > {localeOptionLabel} diff --git a/packages/ui/src/elements/Nav/NavToggler/index.tsx b/packages/ui/src/elements/Nav/NavToggler/index.tsx index d7792155c..2c15821c6 100644 --- a/packages/ui/src/elements/Nav/NavToggler/index.tsx +++ b/packages/ui/src/elements/Nav/NavToggler/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { useWindowInfo } from '@faceless-ui/window-info' +import * as facelessUIImport from '@faceless-ui/window-info' import React from 'react' import { usePreferences } from '../../../providers/Preferences/index.js' @@ -16,6 +16,7 @@ export const NavToggler: React.FC<{ tabIndex?: number }> = (props) => { const { id, children, className, tabIndex = 0 } = props + const { useWindowInfo } = facelessUIImport const { t } = useTranslation() diff --git a/packages/ui/src/elements/Nav/context.tsx b/packages/ui/src/elements/Nav/context.tsx index d77393a56..961d24979 100644 --- a/packages/ui/src/elements/Nav/context.tsx +++ b/packages/ui/src/elements/Nav/context.tsx @@ -1,5 +1,5 @@ 'use client' -import { useWindowInfo } from '@faceless-ui/window-info' +import * as facelessUIImport from '@faceless-ui/window-info' import { clearAllBodyScrollLocks, disableBodyScroll, enableBodyScroll } from 'body-scroll-lock' import React, { useEffect, useRef } from 'react' @@ -32,6 +32,8 @@ const getNavPreference = async (getPreference): Promise => { export const NavProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const { useWindowInfo } = facelessUIImport + const { breakpoints: { l: largeBreak, m: midBreak, s: smallBreak }, } = useWindowInfo() diff --git a/packages/ui/src/elements/Popup/index.tsx b/packages/ui/src/elements/Popup/index.tsx index 34c2a1cd6..d8c1d8e43 100644 --- a/packages/ui/src/elements/Popup/index.tsx +++ b/packages/ui/src/elements/Popup/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { useWindowInfo } from '@faceless-ui/window-info' +import * as facelessUIImport from '@faceless-ui/window-info' import React, { useCallback, useEffect, useRef, useState } from 'react' import type { Props } from './types.js' @@ -29,6 +29,7 @@ const Popup: React.FC = (props) => { size = 'medium', verticalAlign: verticalAlignFromProps = 'top', } = props + const { useWindowInfo } = facelessUIImport const { height: windowHeight, width: windowWidth } = useWindowInfo() const [intersectionRef, intersectionEntry] = useIntersect({ diff --git a/packages/ui/src/elements/PublishMany/index.tsx b/packages/ui/src/elements/PublishMany/index.tsx index aeda64811..77a063b4e 100644 --- a/packages/ui/src/elements/PublishMany/index.tsx +++ b/packages/ui/src/elements/PublishMany/index.tsx @@ -1,6 +1,7 @@ 'use client' -import { Modal, useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' +import { useRouter } from 'next/navigation.js' import React, { useCallback, useState } from 'react' import { toast } from 'react-toastify' @@ -20,6 +21,8 @@ import './index.scss' const baseClass = 'publish-many' export const PublishMany: React.FC = (props) => { + const { Modal, useModal } = facelessUIImport + const { collection: { slug, labels: { plural }, versions } = {} } = props const { @@ -31,7 +34,8 @@ export const PublishMany: React.FC = (props) => { const { i18n, t } = useTranslation() const { getQueryParams, selectAll } = useSelection() const [submitted, setSubmitted] = useState(false) - const { dispatchSearchParams } = useSearchParams() + const router = useRouter() + const { stringifyParams } = useSearchParams() const collectionPermissions = permissions?.collections?.[slug] const hasPermission = collectionPermissions?.update?.permission @@ -63,11 +67,13 @@ export const PublishMany: React.FC = (props) => { toggleModal(modalSlug) if (res.status < 400) { toast.success(t('general:updatedSuccessfully')) - dispatchSearchParams({ - type: 'SET', - browserHistory: 'replace', - params: { page: selectAll ? '1' : undefined }, - }) + router.replace( + stringifyParams({ + params: { + page: selectAll ? '1' : undefined, + }, + }), + ) return null } @@ -92,7 +98,6 @@ export const PublishMany: React.FC = (props) => { slug, t, toggleModal, - dispatchSearchParams, ]) if (!versions?.drafts || selectAll === SelectAllStatus.None || !hasPermission) { diff --git a/packages/ui/src/elements/Status/index.tsx b/packages/ui/src/elements/Status/index.tsx index d8fdcff8f..6839d608b 100644 --- a/packages/ui/src/elements/Status/index.tsx +++ b/packages/ui/src/elements/Status/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { Modal, useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import React, { useCallback, useState } from 'react' import { toast } from 'react-toastify' @@ -16,6 +16,8 @@ import './index.scss' const baseClass = 'status' const Status: React.FC = () => { + const { Modal, useModal } = facelessUIImport + const { id, collectionSlug, diff --git a/packages/ui/src/elements/StayLoggedIn/index.tsx b/packages/ui/src/elements/StayLoggedIn/index.tsx index 778a9c7df..55f984d33 100644 --- a/packages/ui/src/elements/StayLoggedIn/index.tsx +++ b/packages/ui/src/elements/StayLoggedIn/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { Modal, useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' // TODO: abstract the `next/navigation` dependency out from this component import { useRouter } from 'next/navigation.js' import React from 'react' @@ -16,6 +16,8 @@ const baseClass = 'stay-logged-in' const modalSlug = 'stay-logged-in' const StayLoggedInModal: React.FC = (props) => { + const { Modal, useModal } = facelessUIImport + const { refreshCookie } = props const router = useRouter() const config = useConfig() diff --git a/packages/ui/src/elements/UnpublishMany/index.tsx b/packages/ui/src/elements/UnpublishMany/index.tsx index 0515cbe18..ca834aaf7 100644 --- a/packages/ui/src/elements/UnpublishMany/index.tsx +++ b/packages/ui/src/elements/UnpublishMany/index.tsx @@ -1,6 +1,7 @@ 'use client' -import { Modal, useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' +import { useRouter } from 'next/navigation.js' import React, { useCallback, useState } from 'react' import { toast } from 'react-toastify' @@ -21,6 +22,7 @@ const baseClass = 'unpublish-many' export const UnpublishMany: React.FC = (props) => { const { collection: { slug, labels: { plural }, versions } = {} } = props + const { Modal, useModal } = facelessUIImport const { routes: { api }, @@ -31,7 +33,8 @@ export const UnpublishMany: React.FC = (props) => { const { i18n, t } = useTranslation() const { getQueryParams, selectAll } = useSelection() const [submitted, setSubmitted] = useState(false) - const { dispatchSearchParams } = useSearchParams() + const { stringifyParams } = useSearchParams() + const router = useRouter() const collectionPermissions = permissions?.collections?.[slug] const hasPermission = collectionPermissions?.update?.permission @@ -60,11 +63,13 @@ export const UnpublishMany: React.FC = (props) => { toggleModal(modalSlug) if (res.status < 400) { toast.success(t('general:updatedSuccessfully')) - dispatchSearchParams({ - type: 'SET', - browserHistory: 'replace', - params: { page: selectAll ? '1' : undefined }, - }) + router.replace( + stringifyParams({ + params: { + page: selectAll ? '1' : undefined, + }, + }), + ) return null } @@ -81,7 +86,6 @@ export const UnpublishMany: React.FC = (props) => { }, [ addDefaultError, api, - dispatchSearchParams, getQueryParams, i18n.language, modalSlug, diff --git a/packages/ui/src/exports/elements.ts b/packages/ui/src/exports/elements.ts index 83492b062..d3f3c6b0d 100644 --- a/packages/ui/src/exports/elements.ts +++ b/packages/ui/src/exports/elements.ts @@ -23,8 +23,8 @@ export { LoadingOverlay } from '../elements/Loading/index.js' export { Pagination } from '../elements/Pagination/index.js' export { PerPage } from '../elements/PerPage/index.js' export { Pill } from '../elements/Pill/index.js' -export { default as Popup } from '../elements/Popup/index.js' export * as PopupList from '../elements/Popup/PopupButtonList/index.js' +export { default as Popup } from '../elements/Popup/index.js' export { PublishMany } from '../elements/PublishMany/index.js' export { default as ReactSelect } from '../elements/ReactSelect/index.js' export type { Option } from '../elements/ReactSelect/types.js' @@ -32,11 +32,11 @@ export { RenderCustomComponent } from '../elements/RenderCustomComponent/index.j export { ShimmerEffect } from '../elements/ShimmerEffect/index.js' export { StaggeredShimmers } from '../elements/ShimmerEffect/index.js' export { SortColumn } from '../elements/SortColumn/index.js' -export { useStepNav } from '../elements/StepNav/index.js' export { SetStepNav } from '../elements/StepNav/SetStepNav.js' +export { useStepNav } from '../elements/StepNav/index.js' export type { StepNavItem } from '../elements/StepNav/types.js' -export { Table } from '../elements/Table/index.js' export { TableCellProvider, useTableCell } from '../elements/Table/TableCellProvider/index.js' +export { Table } from '../elements/Table/index.js' export type { Column } from '../elements/Table/types.js' export { TableColumnsProvider } from '../elements/TableColumns/index.js' export { default as Thumbnail } from '../elements/Thumbnail/index.js' @@ -47,4 +47,7 @@ export { UnpublishMany } from '../elements/UnpublishMany/index.js' export { Upload } from '../elements/Upload/index.js' export { BlocksDrawer } from '../forms/fields/Blocks/BlocksDrawer/index.js' export { SetViewActions } from '../providers/ActionsProvider/SetViewActions/index.js' -export { Modal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' +const { Modal } = + facelessUIImport && 'Modal' in facelessUIImport ? facelessUIImport : { Modal: undefined } +export { Modal } diff --git a/packages/ui/src/exports/hooks.ts b/packages/ui/src/exports/hooks.ts index 26fb1c492..28d7d549a 100644 --- a/packages/ui/src/exports/hooks.ts +++ b/packages/ui/src/exports/hooks.ts @@ -5,5 +5,16 @@ export { useIntersect } from '../hooks/useIntersect.js' export { default as usePayloadAPI } from '../hooks/usePayloadAPI.js' export { useResize } from '../hooks/useResize.js' export { default as useThumbnail } from '../hooks/useThumbnail.js' -export { useModal } from '@faceless-ui/modal' -export { useWindowInfo } from '@faceless-ui/window-info' + +import * as facelessUIImport from '@faceless-ui/modal' + +const { useModal } = + facelessUIImport && 'useModal' in facelessUIImport ? facelessUIImport : { useModal: undefined } +export { useModal } + +import * as facelessUIImport2 from '@faceless-ui/window-info' +const { useWindowInfo } = + facelessUIImport && 'useWindowInfo' in facelessUIImport2 + ? facelessUIImport2 + : { useWindowInfo: undefined } +export { useWindowInfo } diff --git a/packages/ui/src/forms/Form/getDataByPath.ts b/packages/ui/src/forms/Form/getDataByPath.ts index df9e17712..98e79ff49 100644 --- a/packages/ui/src/forms/Form/getDataByPath.ts +++ b/packages/ui/src/forms/Form/getDataByPath.ts @@ -1,6 +1,7 @@ import type { FormState } from 'payload/types' -import { unflatten } from 'flatley' +import flatleyImport from 'flatley' +const { unflatten } = flatleyImport const getDataByPath = (fields: FormState, path: string): T => { const pathPrefixToRemove = path.substring(0, path.lastIndexOf('.') + 1) diff --git a/packages/ui/src/forms/Form/getSiblingData.ts b/packages/ui/src/forms/Form/getSiblingData.ts index 70f2adb40..42c7711ab 100644 --- a/packages/ui/src/forms/Form/getSiblingData.ts +++ b/packages/ui/src/forms/Form/getSiblingData.ts @@ -1,6 +1,7 @@ import type { Data, FormState } from 'payload/types' -import { unflatten } from 'flatley' +import flatleyImport from 'flatley' +const { unflatten } = flatleyImport import reduceFieldsToValues from './reduceFieldsToValues.js' diff --git a/packages/ui/src/forms/Form/reduceFieldsToValues.ts b/packages/ui/src/forms/Form/reduceFieldsToValues.ts index f4c36692c..0409681a6 100644 --- a/packages/ui/src/forms/Form/reduceFieldsToValues.ts +++ b/packages/ui/src/forms/Form/reduceFieldsToValues.ts @@ -1,7 +1,7 @@ import type { Data, FormState } from 'payload/types' -import { unflatten as flatleyUnflatten } from 'flatley' - +import flatleyImport from 'flatley' +const { unflatten: flatleyUnflatten } = flatleyImport /** * Reduce flattened form fields (Fields) to just map to the respective values instead of the full FormField object * diff --git a/packages/ui/src/forms/fields/Blocks/BlocksDrawer/index.tsx b/packages/ui/src/forms/fields/Blocks/BlocksDrawer/index.tsx index 61babdc3b..4165061cd 100644 --- a/packages/ui/src/forms/fields/Blocks/BlocksDrawer/index.tsx +++ b/packages/ui/src/forms/fields/Blocks/BlocksDrawer/index.tsx @@ -1,7 +1,7 @@ 'use client' import type { I18n } from '@payloadcms/translations' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' import React, { useEffect, useState } from 'react' @@ -27,6 +27,7 @@ const getBlockLabel = (block: ReducedBlock, i18n: I18n) => { export const BlocksDrawer: React.FC = (props) => { const { addRow, addRowIndex, blocks, drawerSlug, labels } = props + const { useModal } = facelessUIImport const [searchTerm, setSearchTerm] = useState('') const [filteredBlocks, setFilteredBlocks] = useState(blocks) diff --git a/packages/ui/src/forms/fields/Blocks/RowActions.tsx b/packages/ui/src/forms/fields/Blocks/RowActions.tsx index 129455916..9b1516b5e 100644 --- a/packages/ui/src/forms/fields/Blocks/RowActions.tsx +++ b/packages/ui/src/forms/fields/Blocks/RowActions.tsx @@ -1,7 +1,7 @@ 'use client' import type { Labels } from 'payload/types' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import React from 'react' import type { FieldMap, ReducedBlock } from '../../../utilities/buildComponentMap/types.js' @@ -35,6 +35,7 @@ export const RowActions: React.FC<{ rowCount, rowIndex, } = props + const { useModal } = facelessUIImport const { closeModal, openModal } = useModal() const drawerSlug = useDrawerSlug('blocks-drawer') diff --git a/packages/ui/src/hooks/useHotkey.tsx b/packages/ui/src/hooks/useHotkey.tsx index 4b76e5062..e1c266698 100644 --- a/packages/ui/src/hooks/useHotkey.tsx +++ b/packages/ui/src/hooks/useHotkey.tsx @@ -1,6 +1,6 @@ 'use client' /* eslint-disable no-shadow */ -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { setsAreEqual } from 'payload/utilities' import { useCallback, useEffect } from 'react' @@ -74,6 +74,8 @@ const useHotkey = ( }, func: (e: KeyboardEvent) => void, ): void => { + const { useModal } = facelessUIImport + const { cmdCtrlKey, editDepth, keyCodes } = options const { modalState } = useModal() diff --git a/packages/ui/src/providers/Auth/index.tsx b/packages/ui/src/providers/Auth/index.tsx index eebfcfbcc..3e0b8d971 100644 --- a/packages/ui/src/providers/Auth/index.tsx +++ b/packages/ui/src/providers/Auth/index.tsx @@ -1,7 +1,7 @@ 'use client' import type { Permissions, User } from 'payload/auth' -import { useModal } from '@faceless-ui/modal' +import * as facelessUIImport from '@faceless-ui/modal' import { usePathname, useRouter } from 'next/navigation.js' import qs from 'qs' import React, { createContext, useCallback, useContext, useEffect, useState } from 'react' @@ -21,6 +21,8 @@ const Context = createContext({} as AuthContext) const maxTimeoutTime = 2147483647 export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const { useModal } = facelessUIImport + const { searchParams } = useSearchParams() const [user, setUser] = useState() const [tokenInMemory, setTokenInMemory] = useState() @@ -145,12 +147,11 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children [serverURL, api, userSlug, i18n, redirectToInactivityRoute, setTokenAndExpiration], ) - const logOut = useCallback(() => { + const logOut = useCallback(async () => { setUser(null) revokeTokenAndExpire() try { - // TODO: I dont think errors from unawaited promises can be caught - requests.post(`${serverURL}${api}/${userSlug}/logout`) + await requests.post(`${serverURL}${api}/${userSlug}/logout`) } catch (e) { toast.error(`Logging out failed: ${e.message}`) } diff --git a/packages/ui/src/providers/Locale/index.tsx b/packages/ui/src/providers/Locale/index.tsx index 93425a177..819824653 100644 --- a/packages/ui/src/providers/Locale/index.tsx +++ b/packages/ui/src/providers/Locale/index.tsx @@ -2,8 +2,6 @@ import type { Locale } from 'payload/config' -// TODO: abstract the `next/navigation` dependency out from this component -import { useRouter } from 'next/navigation.js' import React, { createContext, useContext, useEffect, useState } from 'react' import { findLocaleFromCode } from '../../utilities/findLocaleFromCode.js' @@ -18,15 +16,14 @@ export const LocaleProvider: React.FC<{ children?: React.ReactNode }> = ({ child const { localization } = useConfig() const { user } = useAuth() - const defaultLocale = localization && localization.defaultLocale ? localization.defaultLocale : 'en' - const { dispatchSearchParams, searchParams } = useSearchParams() - const router = useRouter() + const { searchParams } = useSearchParams() + const localeFromParams = searchParams?.locale || '' const [localeCode, setLocaleCode] = useState( - (searchParams?.locale as string) || defaultLocale, + (localeFromParams as string) || defaultLocale, ) const [locale, setLocale] = useState( @@ -35,53 +32,55 @@ export const LocaleProvider: React.FC<{ children?: React.ReactNode }> = ({ child const { getPreference, setPreference } = usePreferences() - const localeFromParams = searchParams.locale - - useEffect(() => { - async function localeChangeHandler() { + const switchLocale = React.useCallback( + async (newLocale: string) => { if (!localization) { return } - // set locale from search param - if (localeFromParams && localization.localeCodes.indexOf(localeFromParams as string) > -1) { - setLocaleCode(localeFromParams as string) - setLocale(findLocaleFromCode(localization, localeFromParams as string)) - if (user) await setPreference('locale', localeFromParams) - return - } + const localeToSet = + localization.localeCodes.indexOf(newLocale) > -1 ? newLocale : defaultLocale - // set locale from preferences or default - let preferenceLocale: string - let isPreferenceInConfig: boolean - if (user) { - preferenceLocale = await getPreference('locale') - isPreferenceInConfig = - preferenceLocale && localization.localeCodes.indexOf(preferenceLocale) > -1 - if (isPreferenceInConfig) { - setLocaleCode(preferenceLocale) - setLocale(findLocaleFromCode(localization, preferenceLocale)) - return + if (localeToSet !== localeCode) { + setLocaleCode(localeToSet) + setLocale(findLocaleFromCode(localization, localeToSet)) + try { + if (user) await setPreference('locale', localeToSet) + } catch (error) { + // swallow error } - await setPreference('locale', defaultLocale) } - setLocaleCode(defaultLocale) - setLocale(findLocaleFromCode(localization, defaultLocale)) - } - - void localeChangeHandler() - }, [defaultLocale, getPreference, localeFromParams, setPreference, user, localization, router]) + }, + [localization, setPreference, user, defaultLocale, localeCode], + ) useEffect(() => { - if (searchParams?.locale) { - dispatchSearchParams({ - type: 'SET', - params: { - locale: searchParams.locale, - }, - }) + async function setInitialLocale() { + let localeToSet = defaultLocale + + if (typeof localeFromParams === 'string') { + localeToSet = localeFromParams + } else if (user) { + try { + localeToSet = await getPreference('locale') + } catch (error) { + // swallow error + } + } + + await switchLocale(localeToSet) } - }, [searchParams.locale, dispatchSearchParams]) + + void setInitialLocale() + }, [ + defaultLocale, + getPreference, + localization, + localeFromParams, + setPreference, + user, + switchLocale, + ]) return {children} } diff --git a/packages/ui/src/providers/Root/index.tsx b/packages/ui/src/providers/Root/index.tsx index 67095ff0f..d13eeace1 100644 --- a/packages/ui/src/providers/Root/index.tsx +++ b/packages/ui/src/providers/Root/index.tsx @@ -2,9 +2,9 @@ import type { LanguageTranslations } from '@payloadcms/translations' import type { ClientConfig } from 'payload/types' -import { ModalContainer, ModalProvider } from '@faceless-ui/modal' -import { ScrollInfoProvider } from '@faceless-ui/scroll-info' -import { WindowInfoProvider } from '@faceless-ui/window-info' +import * as facelessUIImport from '@faceless-ui/modal' +import * as facelessUIImport3 from '@faceless-ui/scroll-info' +import * as facelessUIImport2 from '@faceless-ui/window-info' import React, { Fragment } from 'react' import { Slide, ToastContainer } from 'react-toastify' @@ -47,6 +47,13 @@ export const RootProvider: React.FC = ({ languageOptions, translations, }) => { + const { ModalContainer, ModalProvider } = facelessUIImport || { + ModalContainer: React.Fragment, + ModalProvider: React.Fragment, + } + const { WindowInfoProvider } = facelessUIImport2 || { WindowInfoProvider: React.Fragment } + const { ScrollInfoProvider } = facelessUIImport3 || { ScrollInfoProvider: React.Fragment } + return ( diff --git a/packages/ui/src/providers/SearchParams/index.tsx b/packages/ui/src/providers/SearchParams/index.tsx index b43bb6473..ac56c0c67 100644 --- a/packages/ui/src/providers/SearchParams/index.tsx +++ b/packages/ui/src/providers/SearchParams/index.tsx @@ -1,13 +1,13 @@ 'use client' -import { useSearchParams as useNextSearchParams, useRouter } from 'next/navigation.js' +import { useSearchParams as useNextSearchParams } from 'next/navigation.js' import qs from 'qs' import React, { createContext, useContext } from 'react' -import type { Action, SearchParamsContext, State } from './types.js' +import type { SearchParamsContext, State } from './types.js' const initialContext: SearchParamsContext = { - dispatchSearchParams: () => {}, searchParams: {}, + stringifyParams: () => '', } const Context = createContext(initialContext) @@ -15,46 +15,36 @@ const Context = createContext(initialContext) // TODO: abstract the `next/navigation` dependency out from this provider so that it can be used in other contexts export const SearchParamsProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) => { const nextSearchParams = useNextSearchParams() - const router = useRouter() - const initialParams = qs.parse(nextSearchParams.toString(), { + const searchString = nextSearchParams.toString() + const initialParams = qs.parse(searchString, { depth: 10, ignoreQueryPrefix: true, }) - const [searchParams, dispatchSearchParams] = React.useReducer((state: State, action: Action) => { - const stackAction = action.browserHistory || 'push' - let paramsToSet + const [searchParams, setSearchParams] = React.useState(initialParams) - switch (action.type) { - case 'SET': - paramsToSet = { - ...state, - ...action.params, - } - break - case 'REPLACE': - paramsToSet = action.params - break - case 'CLEAR': - paramsToSet = {} - break - default: - return state - } - - const newSearchString = qs.stringify(paramsToSet, { addQueryPrefix: true }) - if (stackAction === 'push') { - router.push(newSearchString) - } else if (stackAction === 'replace') { - router.replace(newSearchString) - } - - return paramsToSet - }, initialParams) - - return ( - {children} + const stringifyParams = React.useCallback( + ({ params, replace = false }: { params: State; replace?: boolean }) => { + return qs.stringify( + { + ...(replace ? {} : searchParams), + ...params, + }, + { addQueryPrefix: true }, + ) + }, + [searchParams], ) + + React.useEffect(() => { + const newSearchParams = qs.parse(searchString, { + depth: 10, + ignoreQueryPrefix: true, + }) + setSearchParams(newSearchParams) + }, [searchString]) + + return {children} } export const useSearchParams = (): SearchParamsContext => useContext(Context) diff --git a/packages/ui/src/providers/SearchParams/types.ts b/packages/ui/src/providers/SearchParams/types.ts index d941d74d8..ec4e617d0 100644 --- a/packages/ui/src/providers/SearchParams/types.ts +++ b/packages/ui/src/providers/SearchParams/types.ts @@ -1,27 +1,6 @@ export type SearchParamsContext = { - dispatchSearchParams: (action: Action) => void searchParams: qs.ParsedQs + stringifyParams: ({ params, replace }: { params: State; replace?: boolean }) => string } export type State = qs.ParsedQs - -export type Action = ( - | { - params: qs.ParsedQs - type: 'REPLACE' - } - | { - params: qs.ParsedQs - type: 'SET' - } - | { - type: 'CLEAR' - } -) & { - /** - * `push` will add a new entry to the browser history stack. - * `replace` will overwrite the browser history entry. - * @default 'push' - * */ - browserHistory?: 'push' | 'replace' -} diff --git a/packages/ui/src/utilities/buildComponentMap/index.tsx b/packages/ui/src/utilities/buildComponentMap/index.tsx index 1c4fd91b2..e30902ccb 100644 --- a/packages/ui/src/utilities/buildComponentMap/index.tsx +++ b/packages/ui/src/utilities/buildComponentMap/index.tsx @@ -31,7 +31,7 @@ export const buildComponentMap = (args: { const collections = config.collections.reduce((acc, collectionConfig) => { const { slug, fields } = collectionConfig - entityPermissions = permissions.collections[collectionConfig.slug] + entityPermissions = permissions?.collections?.[collectionConfig.slug] const editViewFromConfig = collectionConfig?.admin?.components?.views?.Edit const listViewFromConfig = collectionConfig?.admin?.components?.views?.List @@ -108,7 +108,7 @@ export const buildComponentMap = (args: { DefaultCell, config, fieldSchema: fields, - permissions: entityPermissions.fields, + permissions: entityPermissions?.fields, readOnly: readOnlyOverride, }), } @@ -123,7 +123,7 @@ export const buildComponentMap = (args: { const globals = config.globals.reduce((acc, globalConfig) => { const { slug, fields } = globalConfig - entityPermissions = permissions.globals[globalConfig.slug] + entityPermissions = permissions?.globals?.[globalConfig.slug] const editViewFromConfig = globalConfig?.admin?.components?.views?.Edit @@ -149,7 +149,7 @@ export const buildComponentMap = (args: { DefaultCell, config, fieldSchema: fields, - permissions: entityPermissions.fields, + permissions: entityPermissions?.fields, readOnly: readOnlyOverride, }), } diff --git a/packages/ui/src/utilities/formatDate/index.ts b/packages/ui/src/utilities/formatDate/index.ts index 83130cf40..ed4b129a5 100644 --- a/packages/ui/src/utilities/formatDate/index.ts +++ b/packages/ui/src/utilities/formatDate/index.ts @@ -1,5 +1,5 @@ import { format, formatDistanceToNow } from 'date-fns' -import * as Locale from 'date-fns/locale' +import * as Locale from 'date-fns/locale/index.js' import { getSupportedDateLocale } from './getSupportedDateLocale.js' diff --git a/playwright-1.43.0-next.tgz b/playwright-1.43.0-next.tgz new file mode 100644 index 000000000..a5daa46e0 Binary files /dev/null and b/playwright-1.43.0-next.tgz differ diff --git a/playwright-core-1.43.0-next.tgz b/playwright-core-1.43.0-next.tgz new file mode 100644 index 000000000..54049c549 Binary files /dev/null and b/playwright-core-1.43.0-next.tgz differ diff --git a/playwright.bail.config.ts b/playwright.bail.config.ts index 0ea4db790..e74a4d684 100644 --- a/playwright.bail.config.ts +++ b/playwright.bail.config.ts @@ -1,6 +1,6 @@ import type { PlaywrightTestConfig } from '@playwright/test' -import baseConfig from './playwright.config' +import baseConfig from './playwright.config.js' const config: PlaywrightTestConfig = { ...baseConfig, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d9a99ccd..15490578d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,6 +13,8 @@ overrides: react: ^18.2.0 react-dom: ^18.2.0 typescript: 5.2.2 + playwright: file:playwright-1.43.0-next.tgz + playwright-core: file:playwright-core-1.43.0-next.tgz importers: @@ -196,6 +198,12 @@ importers: pino-pretty: specifier: 10.2.0 version: 10.2.0 + playwright: + specifier: file:/Users/jmikrut/payload/core/playwright-1.43.0-next.tgz + version: file:playwright-1.43.0-next.tgz + playwright-core: + specifier: file:/Users/jmikrut/payload/core/playwright-core-1.43.0-next.tgz + version: file:playwright-core-1.43.0-next.tgz prettier: specifier: ^3.0.3 version: 3.2.5 @@ -4665,7 +4673,7 @@ packages: engines: {node: '>=16'} hasBin: true dependencies: - playwright: 1.42.1 + playwright: file:playwright-1.43.0-next.tgz dev: true /@pnpm/config.env-replace@1.1.0: @@ -13582,22 +13590,6 @@ packages: find-up: 3.0.0 dev: false - /playwright-core@1.42.1: - resolution: {integrity: sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==} - engines: {node: '>=16'} - hasBin: true - dev: true - - /playwright@1.42.1: - resolution: {integrity: sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==} - engines: {node: '>=16'} - hasBin: true - dependencies: - playwright-core: 1.42.1 - optionalDependencies: - fsevents: 2.3.2 - dev: true - /pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -16480,6 +16472,26 @@ packages: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false + file:playwright-1.43.0-next.tgz: + resolution: {integrity: sha512-vw1WPxm0BJVOuQeqObJeqRZPkRMEZwBAjdB6H7UB2ZN3mhd/SwnqpmYOU58M3tymjByoNCCU8/1FJucIUG3vLw==, tarball: file:playwright-1.43.0-next.tgz} + name: playwright + version: 1.43.0-next + engines: {node: '>=16'} + hasBin: true + dependencies: + playwright-core: file:playwright-core-1.43.0-next.tgz + optionalDependencies: + fsevents: 2.3.2 + dev: true + + file:playwright-core-1.43.0-next.tgz: + resolution: {integrity: sha512-1l2lYqjxj/TdjjKipJU48O3I64KpVDkbrrDB6ChhWE9FdeLv49iqLPgNQoD0Vde3N1etu/50GWkTtPIQUyZTMw==, tarball: file:playwright-core-1.43.0-next.tgz} + name: playwright-core + version: 1.43.0-next + engines: {node: '>=16'} + hasBin: true + dev: true + github.com/Raynos/readable-stream/b1a911ce6e4f4c5a7e2948cd23c2f9ee1ea0696f: resolution: {tarball: https://codeload.github.com/Raynos/readable-stream/tar.gz/b1a911ce6e4f4c5a7e2948cd23c2f9ee1ea0696f} name: readable-stream diff --git a/test/_community/collections/Media/index.ts b/test/_community/collections/Media/index.ts index ed7f619eb..88a71a999 100644 --- a/test/_community/collections/Media/index.ts +++ b/test/_community/collections/Media/index.ts @@ -1,4 +1,4 @@ -import type { CollectionConfig } from '../../../../packages/payload/src/collections/config/types' +import type { CollectionConfig } from '../../../../packages/payload/src/collections/config/types.js' export const mediaSlug = 'media' diff --git a/test/_community/collections/Posts/index.ts b/test/_community/collections/Posts/index.ts index 3f75852e8..37701f38b 100644 --- a/test/_community/collections/Posts/index.ts +++ b/test/_community/collections/Posts/index.ts @@ -1,4 +1,4 @@ -import type { CollectionConfig } from '../../../../packages/payload/src/collections/config/types.d.ts' +import type { CollectionConfig } from '../../../../packages/payload/src/collections/config/types.js' import { mediaSlug } from '../Media/index.js' @@ -51,6 +51,5 @@ export const PostsCollection: CollectionConfig = { ], }, ], - versions: true, slug: postsSlug, } diff --git a/test/_community/config.ts b/test/_community/config.ts index f335261ee..9caac4a1c 100644 --- a/test/_community/config.ts +++ b/test/_community/config.ts @@ -19,6 +19,7 @@ export default buildConfigWithDefaults({ }, onInit: async (payload) => { + console.log('onInit') await payload.create({ collection: 'users', data: { diff --git a/test/_community/globals/Menu/index.ts b/test/_community/globals/Menu/index.ts index 86e5ee6c2..afdd01b4d 100644 --- a/test/_community/globals/Menu/index.ts +++ b/test/_community/globals/Menu/index.ts @@ -1,4 +1,4 @@ -import type { GlobalConfig } from '../../../../packages/payload/src/globals/config/types' +import type { GlobalConfig } from '../../../../packages/payload/src/globals/config/types.js' export const menuSlug = 'menu' diff --git a/test/access-control/config.ts b/test/access-control/config.ts index 8858f7615..a621d0f0a 100644 --- a/test/access-control/config.ts +++ b/test/access-control/config.ts @@ -1,21 +1,22 @@ -import type { FieldAccess } from '../../packages/payload/src/fields/config/types' +import type { FieldAccess } from '../../packages/payload/src/fields/config/types.js' -import { buildConfigWithDefaults } from '../buildConfigWithDefaults' -import { devUser } from '../credentials' -import { firstArrayText, secondArrayText } from './shared' +import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js' +import { devUser } from '../credentials.js' import { docLevelAccessSlug, + firstArrayText, hiddenAccessSlug, hiddenFieldsSlug, readOnlySlug, relyOnRequestHeadersSlug, restrictedSlug, restrictedVersionsSlug, + secondArrayText, siblingDataSlug, slug, unrestrictedSlug, userRestrictedSlug, -} from './shared' +} from './shared.js' const openAccess = { create: () => true, diff --git a/test/access-control/e2e.spec.ts b/test/access-control/e2e.spec.ts index 098aa5020..ba208442f 100644 --- a/test/access-control/e2e.spec.ts +++ b/test/access-control/e2e.spec.ts @@ -2,6 +2,7 @@ import type { Page } from '@playwright/test' import type { Payload } from 'payload' import { expect, test } from '@playwright/test' +import { fileURLToPath } from 'url' import type { ReadOnlyCollection, RestrictedVersion } from './payload-types' @@ -18,6 +19,8 @@ import { slug, unrestrictedSlug, } from './shared' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) /** * TODO: Access Control @@ -39,7 +42,7 @@ describe('access control', () => { let serverURL: string beforeAll(async ({ browser }) => { - ;({ payload, serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ payload, serverURL } = await initPayloadE2E({ config, dirname })) url = new AdminUrlUtil(serverURL, slug) restrictedUrl = new AdminUrlUtil(serverURL, restrictedSlug) diff --git a/test/admin/e2e.spec.ts b/test/admin/e2e.spec.ts index 393d01317..cb6c7edd4 100644 --- a/test/admin/e2e.spec.ts +++ b/test/admin/e2e.spec.ts @@ -36,6 +36,8 @@ import { slugPluralLabel, } from './shared' import { + customIdCollectionId, + customIdCollectionSlug, customViews2CollectionSlug, geoCollectionSlug, globalSlug, @@ -44,8 +46,6 @@ import { noApiViewCollectionSlug, noApiViewGlobalSlug, postsCollectionSlug, - customIdCollectionSlug, - customIdCollectionId, } from './slugs' const { beforeAll, beforeEach, describe } = test @@ -55,6 +55,11 @@ const description = 'Description' let payload: Payload +import path from 'path' +import { fileURLToPath } from 'url' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) + describe('admin', () => { let page: Page let geoUrl: AdminUrlUtil @@ -63,7 +68,7 @@ describe('admin', () => { let serverURL: string beforeAll(async ({ browser }) => { - ;({ payload, serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ payload, serverURL } = await initPayloadE2E({ config, dirname })) geoUrl = new AdminUrlUtil(serverURL, geoCollectionSlug) url = new AdminUrlUtil(serverURL, postsCollectionSlug) customViewsURL = new AdminUrlUtil(serverURL, customViews2CollectionSlug) @@ -537,7 +542,7 @@ describe('admin', () => { test('should allow custom ID field nested inside an unnamed tab', async () => { await page.goto(url.collection('customIdTab') + '/' + customIdCollectionId) - const idField = await page.locator('#field-id') + const idField = page.locator('#field-id') await expect(idField).toHaveValue(customIdCollectionId) }) @@ -545,7 +550,7 @@ describe('admin', () => { test('should allow custom ID field nested inside a row', async () => { await page.goto(url.collection('customIdRow') + '/' + customIdCollectionId) - const idField = await page.locator('#field-id') + const idField = page.locator('#field-id') await expect(idField).toHaveValue(customIdCollectionId) }) diff --git a/test/auth/e2e.spec.ts b/test/auth/e2e.spec.ts index bd10726cc..3e10a605a 100644 --- a/test/auth/e2e.spec.ts +++ b/test/auth/e2e.spec.ts @@ -1,6 +1,8 @@ import type { Page } from '@playwright/test' import { expect, test } from '@playwright/test' +import path from 'path' +import { fileURLToPath } from 'url' import payload from '../../packages/payload/src' import { initPageConsoleErrorCatch, login, saveDocAndAssert } from '../helpers' @@ -8,6 +10,8 @@ import { AdminUrlUtil } from '../helpers/adminUrlUtil' import { initPayloadE2E } from '../helpers/configHelpers' import config from './config' import { apiKeysSlug, slug } from './shared' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) /** * TODO: Auth @@ -29,7 +33,7 @@ describe('auth', () => { let apiURL: string beforeAll(async ({ browser }) => { - ;({ serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ serverURL } = await initPayloadE2E({ config, dirname })) url = new AdminUrlUtil(serverURL, slug) const context = await browser.newContext() diff --git a/test/buildConfigWithDefaults.ts b/test/buildConfigWithDefaults.ts index 8dc50c372..c539ca1b1 100644 --- a/test/buildConfigWithDefaults.ts +++ b/test/buildConfigWithDefaults.ts @@ -4,6 +4,7 @@ import type { Config, SanitizedConfig } from '../packages/payload/src/config/typ import { mongooseAdapter } from '../packages/db-mongodb/src/index.js' import { postgresAdapter } from '../packages/db-postgres/src/index.js' +//import { postgresAdapter } from '../packages/db-postgres/src/index.js' import { buildConfig as buildPayloadConfig } from '../packages/payload/src/config/build.js' import { AlignFeature, @@ -28,8 +29,7 @@ import { UploadFeature, lexicalEditor, } from '../packages/richtext-lexical/src/index.js' -// import { slateEditor } from '../packages/richtext-slate/src/index.js' - +//import { slateEditor } from '../packages/richtext-slate/src/index.js' // process.env.PAYLOAD_DATABASE = 'postgres' const databaseAdapters = { @@ -60,11 +60,11 @@ const databaseAdapters = { }, }), } - export function buildConfigWithDefaults(testConfig?: Partial): Promise { const config: Config = { db: databaseAdapters[process.env.PAYLOAD_DATABASE || 'mongoose'], secret: 'TEST_SECRET', + //editor: slateEditor({}), // editor: slateEditor({ // admin: { // upload: { diff --git a/test/collections-graphql/config.ts b/test/collections-graphql/config.ts index cace7429b..04d4c0b73 100644 --- a/test/collections-graphql/config.ts +++ b/test/collections-graphql/config.ts @@ -1,9 +1,12 @@ import path from 'path' +import { fileURLToPath } from 'url' import type { CollectionConfig } from '../../packages/payload/src/collections/config/types' import { buildConfigWithDefaults } from '../buildConfigWithDefaults' import { devUser } from '../credentials' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) export interface Relation { id: string @@ -355,7 +358,7 @@ export default buildConfigWithDefaults({ }, } }, - schemaOutputFile: path.resolve(__dirname, 'schema.graphql'), + schemaOutputFile: path.resolve(dirname, 'schema.graphql'), }, onInit: async (payload) => { await payload.create({ diff --git a/test/create-payload-app/int.spec.ts b/test/create-payload-app/int.spec.ts index 4a5672864..620437ab4 100644 --- a/test/create-payload-app/int.spec.ts +++ b/test/create-payload-app/int.spec.ts @@ -4,9 +4,13 @@ import * as CommentJson from 'comment-json' import fs from 'fs' import path from 'path' import shelljs from 'shelljs' +import { fileURLToPath } from 'url' import { promisify } from 'util' import { initNext } from '../../packages/create-payload-app/src/lib/init-next' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) + const readFile = promisify(fs.readFile) const nextCreateCommands: Partial> = { @@ -24,16 +28,13 @@ describe('create-payload-app', () => { describe('Next.js app template files', () => { it('should exist in dist', () => { - const distPath = path.resolve( - __dirname, - '../../packages/create-payload-app/dist/app/(payload)', - ) + const distPath = path.resolve(dirname, '../../packages/create-payload-app/dist/app/(payload)') expect(fs.existsSync(distPath)).toBe(true) }) }) describe.each(Object.keys(nextCreateCommands))(`--init-next with %s`, (nextCmdKey) => { - const projectDir = path.resolve(__dirname, 'test-app') + const projectDir = path.resolve(dirname, 'test-app') beforeEach(() => { if (fs.existsSync(projectDir)) { diff --git a/test/database/int.spec.ts b/test/database/int.spec.ts index 8a56ec689..0c222701e 100644 --- a/test/database/int.spec.ts +++ b/test/database/int.spec.ts @@ -1,5 +1,6 @@ import fs from 'fs' import path from 'path' +import { fileURLToPath } from 'url' import type { PostgresAdapter } from '../../packages/db-postgres/src/types' import type { Payload } from '../../packages/payload/src' @@ -13,18 +14,20 @@ import { devUser } from '../credentials' import removeFiles from '../helpers/removeFiles' import { startMemoryDB } from '../startMemoryDB' import configPromise from './config' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) let payload: Payload let user: TypeWithID & Record const collection = 'posts' const title = 'title' -process.env.PAYLOAD_CONFIG_PATH = path.join(__dirname, 'config.ts') +process.env.PAYLOAD_CONFIG_PATH = path.join(dirname, 'config.ts') describe('database', () => { beforeAll(async () => { const config = await startMemoryDB(configPromise) payload = await getPayload({ config }) - payload.db.migrationDir = path.join(__dirname, './migrations') + payload.db.migrationDir = path.join(dirname, './migrations') const loginResult = await payload.login({ collection: 'users', @@ -51,7 +54,7 @@ describe('database', () => { }) afterAll(() => { - removeFiles(path.join(__dirname, './migrations')) + removeFiles(path.join(dirname, './migrations')) }) it('should run migrate:create', async () => { diff --git a/test/field-error-states/e2e.spec.ts b/test/field-error-states/e2e.spec.ts index c1bf1f6ee..1afb5e666 100644 --- a/test/field-error-states/e2e.spec.ts +++ b/test/field-error-states/e2e.spec.ts @@ -8,12 +8,17 @@ import config from './config' const { beforeAll, describe } = test +import path from 'path' +import { fileURLToPath } from 'url' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) + describe('field error states', () => { let serverURL: string let page: Page beforeAll(async ({ browser }) => { - ;({ serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ serverURL } = await initPayloadE2E({ config, dirname })) const context = await browser.newContext() page = await context.newPage() initPageConsoleErrorCatch(page) diff --git a/test/fields-relationship/e2e.spec.ts b/test/fields-relationship/e2e.spec.ts index 59c496078..f7dd8b4a4 100644 --- a/test/fields-relationship/e2e.spec.ts +++ b/test/fields-relationship/e2e.spec.ts @@ -1,6 +1,8 @@ import type { Page } from '@playwright/test' import { expect, test } from '@playwright/test' +import path from 'path' +import { fileURLToPath } from 'url' import type { Payload } from '../../packages/payload/src' import type { @@ -26,6 +28,8 @@ import { slug, } from './collectionSlugs' import config from './config' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const { beforeAll, beforeEach, describe } = test @@ -44,7 +48,7 @@ describe('fields - relationship', () => { let serverURL: string beforeAll(async ({ browser }) => { - ;({ payload, serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ payload, serverURL } = await initPayloadE2E({ config, dirname })) url = new AdminUrlUtil(serverURL, slug) diff --git a/test/fields/collections/Upload/index.ts b/test/fields/collections/Upload/index.ts index 2689275f0..f55232ff5 100644 --- a/test/fields/collections/Upload/index.ts +++ b/test/fields/collections/Upload/index.ts @@ -1,13 +1,16 @@ import path from 'path' +import { fileURLToPath } from 'url' import type { CollectionConfig } from '../../../../packages/payload/src/collections/config/types' import { uploadsSlug } from '../../slugs' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const Uploads: CollectionConfig = { slug: uploadsSlug, upload: { - staticDir: path.resolve(__dirname, './uploads'), + staticDir: path.resolve(dirname, './uploads'), }, fields: [ { diff --git a/test/fields/collections/Upload2/index.ts b/test/fields/collections/Upload2/index.ts index 3ce779b5c..a27560db2 100644 --- a/test/fields/collections/Upload2/index.ts +++ b/test/fields/collections/Upload2/index.ts @@ -1,13 +1,16 @@ import path from 'path' +import { fileURLToPath } from 'url' import type { CollectionConfig } from '../../../../packages/payload/src/collections/config/types' import { uploads2Slug } from '../../slugs' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const Uploads2: CollectionConfig = { slug: uploads2Slug, upload: { - staticDir: path.resolve(__dirname, './uploads2'), + staticDir: path.resolve(dirname, './uploads2'), }, labels: { singular: 'Upload 2', diff --git a/test/fields/collections/Uploads3/index.ts b/test/fields/collections/Uploads3/index.ts index 400a9fe66..ef2327fa4 100644 --- a/test/fields/collections/Uploads3/index.ts +++ b/test/fields/collections/Uploads3/index.ts @@ -1,13 +1,16 @@ import path from 'path' +import { fileURLToPath } from 'url' import type { CollectionConfig } from '../../../../packages/payload/src/collections/config/types' import { uploads3Slug } from '../../slugs' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const Uploads3: CollectionConfig = { slug: uploads3Slug, upload: { - staticDir: path.resolve(__dirname, './uploads3'), + staticDir: path.resolve(dirname, './uploads3'), }, labels: { singular: 'Upload 3', diff --git a/test/fields/e2e.spec.ts b/test/fields/e2e.spec.ts index f093091cd..54b8fe5d3 100644 --- a/test/fields/e2e.spec.ts +++ b/test/fields/e2e.spec.ts @@ -3,6 +3,7 @@ import type { Payload } from 'payload' import { expect, test } from '@playwright/test' import path from 'path' +import { fileURLToPath } from 'url' import type { RelationshipField, TextField } from './payload-types' @@ -28,6 +29,8 @@ import { tabsFieldsSlug, textFieldsSlug, } from './slugs' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const { afterEach, beforeAll, beforeEach, describe } = test @@ -39,7 +42,7 @@ let serverURL: string describe('fields', () => { beforeAll(async ({ browser }) => { - ;({ payload, serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ payload, serverURL } = await initPayloadE2E({ config, dirname })) client = new RESTClient(null, { defaultSlug: 'users', serverURL }) await client.login() @@ -1845,7 +1848,7 @@ describe('fields', () => { // create a jpg upload await page .locator('.file-field__upload input[type="file"]') - .setInputFiles(path.resolve(__dirname, './collections/Upload/payload.jpg')) + .setInputFiles(path.resolve(dirname, './collections/Upload/payload.jpg')) await expect(page.locator('.file-field .file-field__filename')).toHaveValue('payload.jpg') await page.locator('#action-save').click() await wait(200) @@ -1871,7 +1874,7 @@ describe('fields', () => { await page.locator('.field-type.upload .upload__toggler.doc-drawer__toggler').click() await page .locator('[id^=doc-drawer_uploads_1_] .file-field__upload input[type="file"]') - .setInputFiles(path.resolve(__dirname, './uploads/payload.png')) + .setInputFiles(path.resolve(dirname, './uploads/payload.png')) await page.locator('[id^=doc-drawer_uploads_1_] #action-save').click() await wait(200) await expect(page.locator('.Toastify')).toContainText('successfully') @@ -1897,7 +1900,7 @@ describe('fields', () => { await page.locator('.field-type.upload .upload__toggler.doc-drawer__toggler').click() await page .locator('[id^=doc-drawer_uploads_1_] .file-field__upload input[type="file"]') - .setInputFiles(path.resolve(__dirname, './uploads/payload.png')) + .setInputFiles(path.resolve(dirname, './uploads/payload.png')) await page.locator('[id^=doc-drawer_uploads_1_] #action-save').click() await wait(200) await expect(page.locator('.Toastify')).toContainText('successfully') @@ -1920,7 +1923,7 @@ describe('fields', () => { // create file in uploads 3 collection await page .locator('.file-field__upload input[type="file"]') - .setInputFiles(path.resolve(__dirname, './collections/Upload/payload.jpg')) + .setInputFiles(path.resolve(dirname, './collections/Upload/payload.jpg')) await expect(page.locator('.file-field .file-field__filename')).toContainText('payload.jpg') await page.locator('#action-save').click() diff --git a/test/fields/lexical.e2e.spec.ts b/test/fields/lexical.e2e.spec.ts index df36dcdb3..1d0c53975 100644 --- a/test/fields/lexical.e2e.spec.ts +++ b/test/fields/lexical.e2e.spec.ts @@ -2,6 +2,8 @@ import type { Page } from '@playwright/test' import type { SerializedEditorState, SerializedParagraphNode, SerializedTextNode } from 'lexical' import { expect, test } from '@playwright/test' +import path from 'path' +import { fileURLToPath } from 'url' import type { Payload } from '../../packages/payload/src' import type { SerializedBlockNode } from '../../packages/richtext-lexical/src' @@ -15,6 +17,8 @@ import { lexicalDocData } from './collections/Lexical/data' import config from './config' import { clearAndSeedEverything } from './seed' import { lexicalFieldsSlug } from './slugs' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const { beforeAll, describe, beforeEach } = test @@ -37,7 +41,7 @@ async function navigateToLexicalFields() { describe('lexical', () => { beforeAll(async ({ browser }) => { - ;({ payload, serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ payload, serverURL } = await initPayloadE2E({ config, dirname })) client = new RESTClient(null, { serverURL, defaultSlug: 'rich-text-fields' }) await client.login() diff --git a/test/fields/seed.ts b/test/fields/seed.ts index 792c77c2e..65ff3333e 100644 --- a/test/fields/seed.ts +++ b/test/fields/seed.ts @@ -1,4 +1,5 @@ import path from 'path' +import { fileURLToPath } from 'url' import { type Payload } from '../../packages/payload/src' import getFileByPath from '../../packages/payload/src/uploads/getFileByPath' @@ -44,6 +45,8 @@ import { uploadsSlug, usersSlug, } from './slugs' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) export async function clearAndSeedEverything(_payload: Payload) { return await seedDB({ @@ -172,6 +175,6 @@ export async function clearAndSeedEverything(_payload: Payload) { }, shouldResetDB: true, snapshotKey: 'fieldsTest', - uploadsDir: path.resolve(__dirname, './collections/Upload/uploads'), + uploadsDir: path.resolve(dirname, './collections/Upload/uploads'), }) } diff --git a/test/generateGraphQLSchema.ts b/test/generateGraphQLSchema.ts index 5187d1672..02924a1e7 100644 --- a/test/generateGraphQLSchema.ts +++ b/test/generateGraphQLSchema.ts @@ -6,16 +6,20 @@ import { setTestEnvPaths } from './helpers/setTestEnvPaths' const [testConfigDir] = process.argv.slice(2) +import { fileURLToPath } from 'url' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) + let testDir if (testConfigDir) { - testDir = path.resolve(__dirname, testConfigDir) + testDir = path.resolve(dirname, testConfigDir) setTestEnvPaths(testDir) generateGraphQLSchema() } else { // Generate graphql schema for entire directory - testDir = __dirname + testDir = dirname - fs.readdirSync(__dirname, { withFileTypes: true }) + fs.readdirSync(dirname, { withFileTypes: true }) .filter((f) => f.isDirectory()) .forEach((dir) => { const suiteDir = path.resolve(testDir, dir.name) diff --git a/test/generateTypes.ts b/test/generateTypes.ts index 6178309a8..3d285409b 100644 --- a/test/generateTypes.ts +++ b/test/generateTypes.ts @@ -6,16 +6,20 @@ import { setTestEnvPaths } from './helpers/setTestEnvPaths' const [testConfigDir] = process.argv.slice(2) +import { fileURLToPath } from 'url' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) + let testDir if (testConfigDir) { - testDir = path.resolve(__dirname, testConfigDir) + testDir = path.resolve(dirname, testConfigDir) setTestEnvPaths(testDir) generateTypes() } else { // Generate types for entire directory - testDir = __dirname + testDir = dirname - fs.readdirSync(__dirname, { withFileTypes: true }) + fs.readdirSync(dirname, { withFileTypes: true }) .filter((f) => f.isDirectory()) .forEach((dir) => { const suiteDir = path.resolve(testDir, dir.name) diff --git a/test/graphql-schema-gen/config.ts b/test/graphql-schema-gen/config.ts index 331176982..63311608d 100644 --- a/test/graphql-schema-gen/config.ts +++ b/test/graphql-schema-gen/config.ts @@ -1,13 +1,16 @@ import path from 'path' +import { fileURLToPath } from 'url' import { buildConfigWithDefaults } from '../buildConfigWithDefaults' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) export default buildConfigWithDefaults({ graphQL: { - schemaOutputFile: path.resolve(__dirname, 'schema.graphql'), + schemaOutputFile: path.resolve(dirname, 'schema.graphql'), }, typescript: { - outputFile: path.resolve(__dirname, 'schema.ts'), + outputFile: path.resolve(dirname, 'schema.ts'), }, collections: [ { diff --git a/test/helpers/bootAdminPanel.mjs b/test/helpers/bootAdminPanel.mjs new file mode 100644 index 000000000..60f8e8943 --- /dev/null +++ b/test/helpers/bootAdminPanel.mjs @@ -0,0 +1,37 @@ +import { createServer } from 'http' +import next from 'next' +import { parse } from 'url' + + +const actualNext = next.default || next +export const bootAdminPanel = async ({ port = 3000, appDir }) => { + const serverURL = `http://localhost:${port}` + const app = actualNext({ + dev: true, + hostname: 'localhost', + port, + dir: appDir, + }) + + const handle = app.getRequestHandler() + await app.prepare() + + createServer(async (req, res) => { + try { + const parsedUrl = parse(req.url, true) + console.log('Requested path: ', parsedUrl.path) + await handle(req, res, parsedUrl) + } catch (err) { + console.error('Error occurred handling', req.url, err) + res.statusCode = 500 + res.end('internal server error') + } + }) + .once('error', (err) => { + console.error(err) + process.exit(1) + }) + .listen(port, () => { + console.log(`> Ready on ${serverURL}`) + }) +} diff --git a/test/helpers/configHelpers.ts b/test/helpers/configHelpers.ts index 83a86e090..b1e324f99 100644 --- a/test/helpers/configHelpers.ts +++ b/test/helpers/configHelpers.ts @@ -1,11 +1,12 @@ import getPort from 'get-port' -import { nextDev } from 'next/dist/cli/next-dev.js' +//import { nextDev } from 'next/dist/cli/next-dev.js' import path from 'path' import type { SanitizedConfig } from '../../packages/payload/src/config/types.js' import type { Payload } from '../../packages/payload/src/index.js' import { getPayload } from '../../packages/payload/src/index.js' +import { bootAdminPanel } from './bootAdminPanel.mjs' type InitializedPayload = { payload: Payload; serverURL: string } @@ -15,20 +16,22 @@ export async function initPayloadE2E(args: { }): Promise { const { config, dirname } = args + console.log('dirname', dirname) + // process.env.TURBOPACK = '1' // Not working due to turbopack pulling in mongoose, pg - process.env.PAYLOAD_CONFIG_PATH = path.resolve(dirname, './config.ts') + process.env.PAYLOAD_CONFIG_PATH = path.resolve(dirname, './config.js') process.env.PAYLOAD_DROP_DATABASE = 'true' - // @ts-expect-error - process.env.NODE_ENV = 'test' + //process.env.NODE_ENV = 'test' const payload = await getPayload({ config }) const port = await getPort() const serverURL = `http://localhost:${port}` - process.env.APP_ENV = 'test' - process.env.__NEXT_TEST_MODE = 'jest' - nextDev({ _: [path.resolve(dirname, '../../')], port: process.env.PORT || 3000 }) + //process.env.APP_ENV = 'test' + //process.env.__NEXT_TEST_MODE = 'jest' + //await nextDev({ _: [path.resolve(dirname, '../../')], port }) // Running nextDev directly does not work for ports other than 3000 + await bootAdminPanel({ port, appDir: path.resolve(dirname, '../../') }) return { serverURL, payload } } diff --git a/test/live-preview/e2e.spec.ts b/test/live-preview/e2e.spec.ts index b96862187..61d25462f 100644 --- a/test/live-preview/e2e.spec.ts +++ b/test/live-preview/e2e.spec.ts @@ -2,6 +2,8 @@ import type { Page } from '@playwright/test' import type { Payload } from 'payload' import { expect, test } from '@playwright/test' +import path from 'path' +import { fileURLToPath } from 'url' import { exactText, initPageConsoleErrorCatch, saveDocAndAssert } from '../helpers' import { AdminUrlUtil } from '../helpers/adminUrlUtil' @@ -9,6 +11,8 @@ import { initPayloadE2E } from '../helpers/configHelpers' import config from './config' import { mobileBreakpoint } from './shared' import { startLivePreviewDemo } from './startLivePreviewDemo' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const { beforeAll, describe } = test @@ -38,7 +42,7 @@ describe('Live Preview', () => { } beforeAll(async ({ browser }) => { - ;({ serverURL, payload } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ serverURL, payload } = await initPayloadE2E({ config, dirname })) url = new AdminUrlUtil(serverURL, 'pages') const context = await browser.newContext() page = await context.newPage() diff --git a/test/live-preview/int.spec.ts b/test/live-preview/int.spec.ts index 6c2580a4d..83f2f0d4a 100644 --- a/test/live-preview/int.spec.ts +++ b/test/live-preview/int.spec.ts @@ -1,4 +1,5 @@ import path from 'path' +import { fileURLToPath } from 'url' import type { Payload } from '../../packages/payload/src' import type { Media, Page, Post, Tenant } from './payload-types' @@ -15,6 +16,8 @@ import { Pages } from './collections/Pages' import { postsSlug } from './collections/Posts' import configPromise from './config' import { tenantsSlug } from './shared' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const schemaJSON = fieldSchemaToJSON(Pages.fields) @@ -55,7 +58,7 @@ describe('Collections - Live Preview', () => { }) // Create image - const filePath = path.resolve(__dirname, './seed/image-1.jpg') + const filePath = path.resolve(dirname, './seed/image-1.jpg') const file = await getFileByPath(filePath) file.name = 'image-1.jpg' diff --git a/test/live-preview/seed/index.ts b/test/live-preview/seed/index.ts index a18092bad..1d2c52624 100644 --- a/test/live-preview/seed/index.ts +++ b/test/live-preview/seed/index.ts @@ -1,4 +1,5 @@ import path from 'path' +import { fileURLToPath } from 'url' import type { Config } from '../../../packages/payload/src/config/types' @@ -15,9 +16,11 @@ import { post3 } from './post-3' import { postsPage } from './posts-page' import { tenant1 } from './tenant-1' import { tenant2 } from './tenant-2' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) export const seed: Config['onInit'] = async (payload) => { - const uploadsDir = path.resolve(__dirname, './media') + const uploadsDir = path.resolve(dirname, './media') removeFiles(path.normalize(uploadsDir)) await payload.create({ @@ -41,7 +44,7 @@ export const seed: Config['onInit'] = async (payload) => { const media = await payload.create({ collection: 'media', - filePath: path.resolve(__dirname, 'image-1.jpg'), + filePath: path.resolve(dirname, 'image-1.jpg'), data: { alt: 'Image 1', }, diff --git a/test/live-preview/startLivePreviewDemo.ts b/test/live-preview/startLivePreviewDemo.ts index 7ee7dc72b..d9aad16e5 100644 --- a/test/live-preview/startLivePreviewDemo.ts +++ b/test/live-preview/startLivePreviewDemo.ts @@ -1,7 +1,10 @@ import { spawn } from 'child_process' import path from 'path' +import { fileURLToPath } from 'url' import type { Payload } from '../../packages/payload/src' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const installNodeModules = async (args: { payload: Payload }): Promise => { const { payload } = args @@ -11,7 +14,7 @@ const installNodeModules = async (args: { payload: Payload }): Promise => return new Promise(function (resolve) { // Install the node modules for the Next.js app const installation = spawn('yarn', ['install'], { - cwd: path.resolve(__dirname, './next-app'), + cwd: path.resolve(dirname, './next-app'), }) installation.stdout.on('data', (data) => { @@ -42,7 +45,7 @@ const bootNextApp = async (args: { payload: Payload }): Promise => { return new Promise(function (resolve, reject) { // Boot up the Next.js app const app = spawn('yarn', ['dev'], { - cwd: path.resolve(__dirname, './next-app'), + cwd: path.resolve(dirname, './next-app'), }) app.stdout.on('data', (data) => { diff --git a/test/localization/e2e.spec.ts b/test/localization/e2e.spec.ts index d612431e6..48b96b101 100644 --- a/test/localization/e2e.spec.ts +++ b/test/localization/e2e.spec.ts @@ -2,6 +2,8 @@ import type { Page } from '@playwright/test' import type { Payload } from 'payload' import { expect, test } from '@playwright/test' +import path from 'path' +import { fileURLToPath } from 'url' import type { LocalizedPost } from './payload-types' @@ -21,6 +23,8 @@ import { spanishLocale, withRequiredLocalizedFields, } from './shared' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) /** * TODO: Localization @@ -49,7 +53,7 @@ describe('Localization', () => { beforeAll(async ({ browser }) => { ;({ payload, serverURL } = await initPayloadE2E({ config, - dirname: __dirname, + dirname, })) url = new AdminUrlUtil(serverURL, localizedPostsSlug) diff --git a/test/plugin-cloud-storage/int.spec.ts b/test/plugin-cloud-storage/int.spec.ts index 018fd32a1..5511ddd26 100644 --- a/test/plugin-cloud-storage/int.spec.ts +++ b/test/plugin-cloud-storage/int.spec.ts @@ -1,6 +1,7 @@ /* eslint-disable jest/require-top-level-describe */ import * as AWS from '@aws-sdk/client-s3' import path from 'path' +import { fileURLToPath } from 'url' import type { Payload } from '../../packages/payload/src' @@ -8,6 +9,8 @@ import { getPayload } from '../../packages/payload/src' import { describeIfInCIOrHasLocalstack } from '../helpers' import { startMemoryDB } from '../startMemoryDB' import configPromise from './config' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) let payload: Payload @@ -43,7 +46,7 @@ describe('@payloadcms/plugin-cloud-storage', () => { const upload = await payload.create({ collection: 'media', data: {}, - filePath: path.resolve(__dirname, '../uploads/image.png'), + filePath: path.resolve(dirname, '../uploads/image.png'), }) expect(upload.id).toBeTruthy() diff --git a/test/plugin-nested-docs/e2e.spec.ts b/test/plugin-nested-docs/e2e.spec.ts index 0e8cfe860..47f7b59d3 100644 --- a/test/plugin-nested-docs/e2e.spec.ts +++ b/test/plugin-nested-docs/e2e.spec.ts @@ -1,11 +1,17 @@ import type { Page } from '@playwright/test' import { expect, test } from '@playwright/test' +import path from 'path' +import { fileURLToPath } from 'url' + import type { Page as PayloadPage } from './payload-types' -import { AdminUrlUtil } from '../helpers/adminUrlUtil' -import { initPayloadE2E } from '../helpers/configHelpers' + import payload from '../../packages/payload/src' import { initPageConsoleErrorCatch } from '../helpers' +import { AdminUrlUtil } from '../helpers/adminUrlUtil' +import { initPayloadE2E } from '../helpers/configHelpers' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const { beforeAll, describe } = test let url: AdminUrlUtil @@ -16,10 +22,10 @@ let draftChildId: string let childId: string type Args = { - slug: string - title?: string parent?: string - status?: 'published' | 'draft' + slug: string + status?: 'draft' | 'published' + title?: string } async function createPage({ @@ -31,8 +37,8 @@ async function createPage({ return payload.create({ collection: 'pages', data: { - title: title, - slug: slug, + title, + slug, _status: status, parent, }, @@ -41,7 +47,7 @@ async function createPage({ describe('Nested Docs Plugin', () => { beforeAll(async ({ browser }) => { - const { serverURL } = await initPayloadE2E(__dirname) + const { serverURL } = await initPayloadE2E(dirname) url = new AdminUrlUtil(serverURL, 'pages') const context = await browser.newContext() diff --git a/test/plugin-seo/collections/Media.ts b/test/plugin-seo/collections/Media.ts index b56c7bf28..5738ce23c 100644 --- a/test/plugin-seo/collections/Media.ts +++ b/test/plugin-seo/collections/Media.ts @@ -1,13 +1,16 @@ import path from 'path' +import { fileURLToPath } from 'url' import type { CollectionConfig } from '../../../packages/payload/src/collections/config/types' import { mediaSlug } from '../shared' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) export const Media: CollectionConfig = { slug: mediaSlug, upload: { - staticDir: path.resolve(__dirname, '../media'), + staticDir: path.resolve(dirname, '../media'), }, fields: [ { diff --git a/test/plugin-seo/e2e.spec.ts b/test/plugin-seo/e2e.spec.ts index 8ea5c6d67..955eb1736 100644 --- a/test/plugin-seo/e2e.spec.ts +++ b/test/plugin-seo/e2e.spec.ts @@ -3,6 +3,7 @@ import type { Payload } from 'payload' import { expect, test } from '@playwright/test' import path from 'path' +import { fileURLToPath } from 'url' import type { Page as PayloadPage } from './payload-types' @@ -12,6 +13,8 @@ import { AdminUrlUtil } from '../helpers/adminUrlUtil' import { initPayloadE2E } from '../helpers/configHelpers' import config from '../uploads/config' import { mediaSlug } from './shared' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const { beforeAll, describe } = test let url: AdminUrlUtil @@ -21,14 +24,14 @@ let payload: Payload describe('SEO Plugin', () => { beforeAll(async ({ browser }) => { - const { serverURL } = await initPayloadE2E({ config, dirname: __dirname }) + const { serverURL } = await initPayloadE2E({ config, dirname }) url = new AdminUrlUtil(serverURL, 'pages') const context = await browser.newContext() page = await context.newPage() initPageConsoleErrorCatch(page) - const filePath = path.resolve(__dirname, './image-1.jpg') + const filePath = path.resolve(dirname, './image-1.jpg') const file = await getFileByPath(filePath) const mediaDoc = await payload.create({ diff --git a/test/plugin-seo/int.spec.ts b/test/plugin-seo/int.spec.ts index 219077c84..34b831d6c 100644 --- a/test/plugin-seo/int.spec.ts +++ b/test/plugin-seo/int.spec.ts @@ -1,4 +1,5 @@ import path from 'path' +import { fileURLToPath } from 'url' import type { Payload } from '../../packages/payload/src' @@ -8,6 +9,8 @@ import removeFiles from '../helpers/removeFiles' import { startMemoryDB } from '../startMemoryDB' import configPromise from './config' import { mediaSlug } from './shared' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) let payload: Payload @@ -16,14 +19,14 @@ describe('@payloadcms/plugin-seo', () => { let mediaDoc = null beforeAll(async () => { - const uploadsDir = path.resolve(__dirname, './media') + const uploadsDir = path.resolve(dirname, './media') removeFiles(path.normalize(uploadsDir)) const config = await startMemoryDB(configPromise) payload = await getPayload({ config }) // Create image - const filePath = path.resolve(__dirname, './image-1.jpg') + const filePath = path.resolve(dirname, './image-1.jpg') const file = await getFileByPath(filePath) mediaDoc = await payload.create({ diff --git a/test/refresh-permissions/e2e.spec.ts b/test/refresh-permissions/e2e.spec.ts index 4b7968484..70236bf54 100644 --- a/test/refresh-permissions/e2e.spec.ts +++ b/test/refresh-permissions/e2e.spec.ts @@ -1,10 +1,14 @@ import type { Page } from '@playwright/test' import { expect, test } from '@playwright/test' +import path from 'path' +import { fileURLToPath } from 'url' import { closeNav, initPageConsoleErrorCatch, openNav } from '../helpers' import { initPayloadE2E } from '../helpers/configHelpers' import config from './config' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const { beforeAll, describe } = test @@ -13,7 +17,7 @@ describe('refresh-permissions', () => { let page: Page beforeAll(async ({ browser }) => { - ;({ serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ serverURL } = await initPayloadE2E({ config, dirname })) const context = await browser.newContext() page = await context.newPage() diff --git a/test/runE2E.ts b/test/runE2E.ts index 307f9405e..3d269c0c2 100644 --- a/test/runE2E.ts +++ b/test/runE2E.ts @@ -6,11 +6,11 @@ import slash from 'slash' import { fileURLToPath } from 'url' const __filename = fileURLToPath(import.meta.url) -const __dirname = path.dirname(__filename) +const dirname = path.dirname(__filename) shelljs.env.DISABLE_LOGGING = 'true' -const playwrightBin = path.resolve(__dirname, '../node_modules/.bin/playwright') +const playwrightBin = path.resolve(dirname, '../node_modules/.bin/playwright') const testRunCodes: { code: number; suiteName: string }[] = [] const { _: args, bail, part } = minimist(process.argv.slice(2)) @@ -18,7 +18,7 @@ const suiteName = args[0] // Run all if (!suiteName) { - let files = glob.sync(`${path.resolve(__dirname).replace(/\\/g, '/')}/**/*e2e.spec.ts`) + let files = glob.sync(`${path.resolve(dirname).replace(/\\/g, '/')}/**/*e2e.spec.ts`) const totalFiles = files.length @@ -53,7 +53,7 @@ if (!suiteName) { } else { // Run specific suite clearWebpackCache() - const suitePath = path.resolve(__dirname, suiteName, 'e2e.spec.ts') + const suitePath = path.resolve(dirname, suiteName, 'e2e.spec.ts') executePlaywright(suitePath) } @@ -68,7 +68,7 @@ if (testRunCodes.some((tr) => tr.code > 0)) process.exit(1) function executePlaywright(suitePath: string, bail = false) { console.log(`Executing ${suitePath}...`) const playwrightCfg = path.resolve( - __dirname, + dirname, '..', `${bail ? 'playwright.bail.config.ts' : 'playwright.config.ts'}`, ) @@ -89,6 +89,6 @@ function executePlaywright(suitePath: string, bail = false) { } function clearWebpackCache() { - const webpackCachePath = path.resolve(__dirname, '../node_modules/.cache/webpack') + const webpackCachePath = path.resolve(dirname, '../node_modules/.cache/webpack') shelljs.rm('-rf', webpackCachePath) } diff --git a/test/tsconfig.json b/test/tsconfig.json index a52f3dd73..d10d99f84 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -13,9 +13,10 @@ "src/**/*.d.ts", "src/**/*.json", "**/*.ts", + "**/*.ts", "test/**/*.tsx", "../packages/**/src/**/*.ts", - ], + "../packages/**/src/**/*.tsx"], "plugins": [ { "name": "next", diff --git a/test/uploads/e2e.spec.ts b/test/uploads/e2e.spec.ts index 67c0020ef..8f5d119e9 100644 --- a/test/uploads/e2e.spec.ts +++ b/test/uploads/e2e.spec.ts @@ -3,6 +3,7 @@ import type { Payload } from 'payload' import { expect, test } from '@playwright/test' import path from 'path' +import { fileURLToPath } from 'url' import type { Media } from './payload-types' @@ -14,6 +15,8 @@ import { RESTClient } from '../helpers/rest' import { adminThumbnailSrc } from './collections/admin-thumbnail' import config from './config' import { adminThumbnailSlug, audioSlug, mediaSlug, relationSlug } from './shared' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const { beforeAll, describe } = test @@ -31,7 +34,7 @@ describe('uploads', () => { let audioDoc: Media beforeAll(async ({ browser }) => { - ;({ payload, serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ payload, serverURL } = await initPayloadE2E({ config, dirname })) client = new RESTClient(null, { defaultSlug: 'users', serverURL }) await client.login() @@ -88,7 +91,7 @@ describe('uploads', () => { test('should create file upload', async () => { await page.goto(mediaURL.create) - await page.setInputFiles('input[type="file"]', path.resolve(__dirname, './image.png')) + await page.setInputFiles('input[type="file"]', path.resolve(dirname, './image.png')) const filename = page.locator('.file-field__filename') @@ -201,7 +204,7 @@ describe('uploads', () => { await expect(page.locator('[id^=doc-drawer_media_2_]')).toBeVisible() await page .locator('[id^=doc-drawer_media_2_] .file-field__upload input[type="file"]') - .setInputFiles(path.resolve(__dirname, './image.png')) + .setInputFiles(path.resolve(dirname, './image.png')) await page.locator('[id^=doc-drawer_media_2_] button#action-save').click() await wait(200) await expect(page.locator('.Toastify')).toContainText('successfully') @@ -227,7 +230,7 @@ describe('uploads', () => { test('Should detect correct mimeType', async () => { await page.goto(mediaURL.create) - await page.setInputFiles('input[type="file"]', path.resolve(__dirname, './image.png')) + await page.setInputFiles('input[type="file"]', path.resolve(dirname, './image.png')) await saveDocAndAssert(page) const imageID = page.url().split('/').pop() @@ -265,7 +268,7 @@ describe('uploads', () => { const fileChooserPromise = page.waitForEvent('filechooser') await page.getByText('Select a file').click() const fileChooser = await fileChooserPromise - await fileChooser.setFiles(path.join(__dirname, 'test-image.jpg')) + await fileChooser.setFiles(path.join(dirname, 'test-image.jpg')) await page.locator('.file-field__edit').click() // set crop diff --git a/test/uploads/int.spec.ts b/test/uploads/int.spec.ts index 51d9cb83c..ff9373304 100644 --- a/test/uploads/int.spec.ts +++ b/test/uploads/int.spec.ts @@ -2,6 +2,7 @@ import { File as FileBuffer } from 'buffer' import NodeFormData from 'form-data' import fs from 'fs' import path from 'path' +import { fileURLToPath } from 'url' import { promisify } from 'util' import type { Payload } from '../../packages/payload/src' @@ -20,6 +21,8 @@ import { unstoredMediaSlug, usersSlug, } from './shared' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const getMimeType = ( filePath: string, @@ -64,7 +67,7 @@ const bufferToFileBlob = async (filePath: string): Promise => // Convert type FileBuffer > unknown > File // The File type expects webkitRelativePath, we don't have that - resolve(new FileBuffer([data], filename, { type: type }) as unknown as File) + resolve(new FileBuffer([data], filename, { type }) as unknown as File) }) }) @@ -85,7 +88,7 @@ describe('Collections - Uploads', () => { describe('create', () => { it('creates from form data given a png', async () => { const formData = new FormData() - const filePath = path.join(__dirname, './image.png') + const filePath = path.join(dirname, './image.png') formData.append('file', await bufferToFileBlob(filePath)) @@ -98,7 +101,7 @@ describe('Collections - Uploads', () => { expect(response.status).toBe(201) const { sizes } = doc - const expectedPath = path.join(__dirname, './media') + const expectedPath = path.join(dirname, './media') // Check for files expect(await fileExists(path.join(expectedPath, doc.filename))).toBe(true) @@ -122,7 +125,7 @@ describe('Collections - Uploads', () => { it('creates from form data given an svg', async () => { const formData = new FormData() - const filePath = path.join(__dirname, './image.svg') + const filePath = path.join(dirname, './image.svg') formData.append('file', await bufferToFileBlob(filePath)) const response = await restClient.POST(`/${mediaSlug}`, { @@ -134,7 +137,7 @@ describe('Collections - Uploads', () => { expect(response.status).toBe(201) // Check for files - expect(await fileExists(path.join(__dirname, './media', doc.filename))).toBe(true) + expect(await fileExists(path.join(dirname, './media', doc.filename))).toBe(true) // Check api response expect(doc.mimeType).toEqual('image/svg+xml') @@ -146,7 +149,7 @@ describe('Collections - Uploads', () => { it('should have valid image url', async () => { const formData = new FormData() - const fileBlob = await bufferToFileBlob(path.join(__dirname, './image.svg')) + const fileBlob = await bufferToFileBlob(path.join(dirname, './image.svg')) formData.append('file', fileBlob) const response = await restClient.POST(`/${mediaSlug}`, { @@ -156,7 +159,7 @@ describe('Collections - Uploads', () => { const { doc } = await response.json() expect(response.status).toBe(201) - const expectedPath = path.join(__dirname, './media') + const expectedPath = path.join(dirname, './media') expect(await fileExists(path.join(expectedPath, doc.filename))).toBe(true) expect(doc.url).not.toContain('undefined') @@ -164,7 +167,7 @@ describe('Collections - Uploads', () => { it('creates images that do not require all sizes', async () => { const formData = new FormData() - const fileBlob = await bufferToFileBlob(path.join(__dirname, './small.png')) + const fileBlob = await bufferToFileBlob(path.join(dirname, './small.png')) formData.append('file', fileBlob) const response = await restClient.POST(`/${mediaSlug}`, { @@ -175,7 +178,7 @@ describe('Collections - Uploads', () => { expect(response.status).toBe(201) - const expectedPath = path.join(__dirname, './media') + const expectedPath = path.join(dirname, './media') // Check for files expect(await fileExists(path.join(expectedPath, doc.filename))).toBe(true) @@ -189,7 +192,7 @@ describe('Collections - Uploads', () => { it('creates images from a different format', async () => { const formData = new FormData() - const fileBlob = await bufferToFileBlob(path.join(__dirname, './image.jpg')) + const fileBlob = await bufferToFileBlob(path.join(dirname, './image.jpg')) formData.append('file', fileBlob) const response = await restClient.POST(`/${mediaSlug}`, { @@ -200,7 +203,7 @@ describe('Collections - Uploads', () => { expect(response.status).toBe(201) - const expectedPath = path.join(__dirname, './media') + const expectedPath = path.join(dirname, './media') // Check for files expect(await fileExists(path.join(expectedPath, doc.filename))).toBe(true) @@ -217,7 +220,7 @@ describe('Collections - Uploads', () => { it('creates media without storing a file', async () => { const formData = new FormData() - const fileBlob = await bufferToFileBlob(path.join(__dirname, './unstored.png')) + const fileBlob = await bufferToFileBlob(path.join(dirname, './unstored.png')) formData.append('file', fileBlob) // unstored media @@ -230,14 +233,14 @@ describe('Collections - Uploads', () => { expect(response.status).toBe(201) // Check for files - expect(await fileExists(path.join(__dirname, './media', doc.filename))).toBe(false) + expect(await fileExists(path.join(dirname, './media', doc.filename))).toBe(false) // Check api response expect(doc.filename).toBeDefined() }) it('should enlarge images if resize options `withoutEnlargement` is set to false', async () => { - const small = await getFileByPath(path.resolve(__dirname, './small.png')) + const small = await getFileByPath(path.resolve(dirname, './small.png')) const result = await payload.create({ collection: enlargeSlug, @@ -248,7 +251,7 @@ describe('Collections - Uploads', () => { expect(result).toBeTruthy() const { sizes } = result as unknown as Enlarge - const expectedPath = path.join(__dirname, './media/enlarge') + const expectedPath = path.join(dirname, './media/enlarge') // Check for files expect(await fileExists(path.join(expectedPath, small.name))).toBe(true) @@ -282,7 +285,7 @@ describe('Collections - Uploads', () => { // This test makes sure that the image resizing is not prevented if only one dimension is larger (due to payload preventing enlargement by default) it('should resize images if one desired dimension is smaller and the other is larger', async () => { - const small = await getFileByPath(path.resolve(__dirname, './small.png')) + const small = await getFileByPath(path.resolve(dirname, './small.png')) const result = (await payload.create({ collection: enlargeSlug, @@ -293,7 +296,7 @@ describe('Collections - Uploads', () => { expect(result).toBeTruthy() const { sizes } = result - const expectedPath = path.join(__dirname, './media/enlarge') + const expectedPath = path.join(dirname, './media/enlarge') // Check for files expect(await fileExists(path.join(expectedPath, sizes.widthLowerHeightLarger.filename))).toBe( @@ -310,8 +313,8 @@ describe('Collections - Uploads', () => { it('should not reduce images if resize options `withoutReduction` is set to true', async () => { const formData = new NodeFormData() - formData.append('file', fs.createReadStream(path.join(__dirname, './small.png'))) - const small = await getFileByPath(path.resolve(__dirname, './small.png')) + formData.append('file', fs.createReadStream(path.join(dirname, './small.png'))) + const small = await getFileByPath(path.resolve(dirname, './small.png')) const result = await payload.create({ collection: reduceSlug, @@ -322,7 +325,7 @@ describe('Collections - Uploads', () => { expect(result).toBeTruthy() const { sizes } = result as unknown as Enlarge - const expectedPath = path.join(__dirname, './media/reduce') + const expectedPath = path.join(dirname, './media/reduce') // Check for files expect(await fileExists(path.join(expectedPath, small.name))).toBe(true) @@ -352,7 +355,7 @@ describe('Collections - Uploads', () => { it('update', async () => { // Create image - const filePath = path.resolve(__dirname, './image.png') + const filePath = path.resolve(dirname, './image.png') const file = await getFileByPath(filePath) file.name = 'renamed.png' @@ -363,7 +366,7 @@ describe('Collections - Uploads', () => { })) as unknown as Media const formData = new FormData() - formData.append('file', await bufferToFileBlob(path.join(__dirname, './small.png'))) + formData.append('file', await bufferToFileBlob(path.join(dirname, './small.png'))) const response = await restClient.PATCH(`/${mediaSlug}/${mediaDoc.id}`, { body: formData, @@ -372,7 +375,7 @@ describe('Collections - Uploads', () => { expect(response.status).toBe(200) - const expectedPath = path.join(__dirname, './media') + const expectedPath = path.join(dirname, './media') // Check that previously existing files were removed expect(await fileExists(path.join(expectedPath, mediaDoc.filename))).toBe(false) @@ -381,7 +384,7 @@ describe('Collections - Uploads', () => { it('update - update many', async () => { // Create image - const filePath = path.resolve(__dirname, './image.png') + const filePath = path.resolve(dirname, './image.png') const file = await getFileByPath(filePath) file.name = 'renamed.png' @@ -392,7 +395,7 @@ describe('Collections - Uploads', () => { })) as unknown as Media const formData = new FormData() - formData.append('file', await bufferToFileBlob(path.join(__dirname, './small.png'))) + formData.append('file', await bufferToFileBlob(path.join(dirname, './small.png'))) const response = await restClient.PATCH(`/${mediaSlug}`, { body: formData, @@ -408,7 +411,7 @@ describe('Collections - Uploads', () => { expect(response.status).toBe(200) - const expectedPath = path.join(__dirname, './media') + const expectedPath = path.join(dirname, './media') // Check that previously existing files were removed expect(await fileExists(path.join(expectedPath, mediaDoc.filename))).toBe(false) @@ -417,7 +420,7 @@ describe('Collections - Uploads', () => { it('should remove existing media on re-upload', async () => { // Create temp file - const filePath = path.resolve(__dirname, './temp.png') + const filePath = path.resolve(dirname, './temp.png') const file = await getFileByPath(filePath) file.name = 'temp.png' @@ -427,13 +430,13 @@ describe('Collections - Uploads', () => { file, })) as unknown as Media - const expectedPath = path.join(__dirname, './media') + const expectedPath = path.join(dirname, './media') // Check that the temp file was created expect(await fileExists(path.join(expectedPath, mediaDoc.filename))).toBe(true) // Replace the temp file with a new one - const newFilePath = path.resolve(__dirname, './temp-renamed.png') + const newFilePath = path.resolve(dirname, './temp-renamed.png') const newFile = await getFileByPath(newFilePath) newFile.name = 'temp-renamed.png' @@ -451,7 +454,7 @@ describe('Collections - Uploads', () => { it('should remove existing media on re-upload - update many', async () => { // Create temp file - const filePath = path.resolve(__dirname, './temp.png') + const filePath = path.resolve(dirname, './temp.png') const file = await getFileByPath(filePath) file.name = 'temp.png' @@ -461,13 +464,13 @@ describe('Collections - Uploads', () => { file, })) as unknown as Media - const expectedPath = path.join(__dirname, './media') + const expectedPath = path.join(dirname, './media') // Check that the temp file was created expect(await fileExists(path.join(expectedPath, mediaDoc.filename))).toBe(true) // Replace the temp file with a new one - const newFilePath = path.resolve(__dirname, './temp-renamed.png') + const newFilePath = path.resolve(dirname, './temp-renamed.png') const newFile = await getFileByPath(newFilePath) newFile.name = 'temp-renamed-second.png' @@ -487,9 +490,9 @@ describe('Collections - Uploads', () => { }) it('should remove extra sizes on update', async () => { - const filePath = path.resolve(__dirname, './image.png') + const filePath = path.resolve(dirname, './image.png') const file = await getFileByPath(filePath) - const small = await getFileByPath(path.resolve(__dirname, './small.png')) + const small = await getFileByPath(path.resolve(dirname, './small.png')) const { id } = await payload.create({ collection: mediaSlug, @@ -509,9 +512,9 @@ describe('Collections - Uploads', () => { }) it('should remove extra sizes on update - update many', async () => { - const filePath = path.resolve(__dirname, './image.png') + const filePath = path.resolve(dirname, './image.png') const file = await getFileByPath(filePath) - const small = await getFileByPath(path.resolve(__dirname, './small.png')) + const small = await getFileByPath(path.resolve(dirname, './small.png')) const { id } = await payload.create({ collection: mediaSlug, @@ -533,7 +536,7 @@ describe('Collections - Uploads', () => { }) it('should allow update removing a relationship', async () => { - const filePath = path.resolve(__dirname, './image.png') + const filePath = path.resolve(dirname, './image.png') const file = await getFileByPath(filePath) file.name = 'renamed.png' @@ -562,7 +565,7 @@ describe('Collections - Uploads', () => { }) it('should allow update removing a relationship - update many', async () => { - const filePath = path.resolve(__dirname, './image.png') + const filePath = path.resolve(dirname, './image.png') const file = await getFileByPath(filePath) file.name = 'renamed.png' @@ -594,7 +597,7 @@ describe('Collections - Uploads', () => { it('delete', async () => { const formData = new FormData() - formData.append('file', await bufferToFileBlob(path.join(__dirname, './image.png'))) + formData.append('file', await bufferToFileBlob(path.join(dirname, './image.png'))) const { doc } = await restClient .POST(`/${mediaSlug}`, { @@ -606,12 +609,12 @@ describe('Collections - Uploads', () => { const response2 = await restClient.DELETE(`/${mediaSlug}/${doc.id}`) expect(response2.status).toBe(200) - expect(await fileExists(path.join(__dirname, doc.filename))).toBe(false) + expect(await fileExists(path.join(dirname, doc.filename))).toBe(false) }) it('delete - update many', async () => { const formData = new FormData() - formData.append('file', await bufferToFileBlob(path.join(__dirname, './image.png'))) + formData.append('file', await bufferToFileBlob(path.join(dirname, './image.png'))) const { doc } = await restClient .POST(`/${mediaSlug}`, { @@ -634,7 +637,7 @@ describe('Collections - Uploads', () => { expect(errors).toHaveLength(0) - expect(await fileExists(path.join(__dirname, doc.filename))).toBe(false) + expect(await fileExists(path.join(dirname, doc.filename))).toBe(false) }) describe('filesRequiredOnCreate', () => { @@ -643,7 +646,7 @@ describe('Collections - Uploads', () => { expect( async () => await payload.create({ - // @ts-ignore + // @ts-expect-error collection: 'optional-file', data: {}, }), @@ -653,7 +656,7 @@ describe('Collections - Uploads', () => { it('should throw an error if no file and filesRequiredOnCreate is true', async () => { await expect(async () => payload.create({ - // @ts-ignore + // @ts-expect-error collection: 'required-file', data: {}, }), diff --git a/test/versions/e2e.spec.ts b/test/versions/e2e.spec.ts index 6f34c9b73..78fd5b339 100644 --- a/test/versions/e2e.spec.ts +++ b/test/versions/e2e.spec.ts @@ -27,6 +27,8 @@ import type { Page } from '@playwright/test' import type { Payload } from 'payload' import { expect, test } from '@playwright/test' +import path from 'path' +import { fileURLToPath } from 'url' import wait from '../../packages/payload/src/utilities/wait' import { globalSlug } from '../admin/slugs' @@ -52,6 +54,8 @@ import { draftGlobalSlug, postCollectionSlug, } from './slugs' +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) const { beforeAll, beforeEach, describe } = test @@ -67,7 +71,7 @@ describe('versions', () => { let postURL: AdminUrlUtil beforeAll(async ({ browser }) => { - ;({ payload, serverURL } = await initPayloadE2E({ config, dirname: __dirname })) + ;({ payload, serverURL } = await initPayloadE2E({ config, dirname })) const context = await browser.newContext() page = await context.newPage()