chore: updates e2e tests for plugin-nested-docs and plugin-seo (#5434)

* test: removes unnecessary lines

* fix: do not error if row field has no fields (#5433)

* ci(deps): update turborepo

* ci: release script updates

* chore: lint all json/yml, add to lint-staged

* chore: lint mdx in lint-staged

* chore: enable e2e live preview (#5444)

* chore: update workflow file

---------

Co-authored-by: Alessio Gravili <70709113+AlessioGr@users.noreply.github.com>
Co-authored-by: Elliot DeNolf <denolfe@gmail.com>
Co-authored-by: Paul <paul@payloadcms.com>
This commit is contained in:
Jessica Chowdhury
2024-04-01 15:01:05 +01:00
committed by GitHub
parent 92ec0a5b1d
commit ece7d92e57
9 changed files with 266 additions and 146 deletions

View File

@@ -226,8 +226,8 @@ jobs:
- fields/lexical - fields/lexical
# - live-preview # - live-preview
- localization - localization
# - plugin-nested-docs - plugin-nested-docs
# - plugin-seo - plugin-seo
# - refresh-permissions # - refresh-permissions
# - uploads # - uploads
# - versions # - versions

View File

@@ -132,34 +132,48 @@ const seo =
(collection.auth || (collection.auth ||
!(typeof collection.auth === 'object' && collection.auth.disableLocalStrategy)) && !(typeof collection.auth === 'object' && collection.auth.disableLocalStrategy)) &&
collection.fields?.find((field) => 'name' in field && field.name === 'email') collection.fields?.find((field) => 'name' in field && field.name === 'email')
const hasOnlyEmailField = collection.fields?.length === 1 && emailField
const seoTabs: TabsField[] = [ const seoTabs: TabsField[] = hasOnlyEmailField
{ ? [
type: 'tabs',
tabs: [
// append a new tab onto the end of the tabs array, if there is one at the first index
// if needed, create a new `Content` tab in the first index for this collection's base fields
...(collection?.fields?.[0]?.type === 'tabs' && collection?.fields?.[0]?.tabs
? collection.fields[0].tabs
: [
{
fields: [
...((emailField
? collection.fields.filter(
(field) => 'name' in field && field.name !== 'email',
)
: collection.fields) || []),
],
label: collection?.labels?.singular || 'Content',
},
]),
{ {
fields: seoFields, type: 'tabs',
label: 'SEO', tabs: [
{
fields: seoFields,
label: 'SEO',
},
],
}, },
], ]
}, : [
] {
type: 'tabs',
tabs: [
// append a new tab onto the end of the tabs array, if there is one at the first index
// if needed, create a new `Content` tab in the first index for this collection's base fields
...(collection?.fields?.[0]?.type === 'tabs' &&
collection?.fields?.[0]?.tabs
? collection.fields[0].tabs
: [
{
fields: [
...(emailField
? collection.fields.filter(
(field) => 'name' in field && field.name !== 'email',
)
: collection.fields),
],
label: collection?.labels?.singular || 'Content',
},
]),
{
fields: seoFields,
label: 'SEO',
},
],
},
]
return { return {
...collection, ...collection,

View File

@@ -1,7 +1,127 @@
import en from './en.json' export const translations = {
import es from './es.json' en: {
import fa from './fa.json' $schema: './translation-schema.json',
import fr from './fr.json' 'plugin-seo': {
import pl from './pl.json' almostThere: 'Almost there',
autoGenerate: 'Auto-generate',
export const translations = { en, es, fa, fr, pl } bestPractices: 'best practices',
characterCount: '{{current}}/{{minLength}}-{{maxLength}} chars, ',
charactersLeftOver: '{{characters}} left over',
charactersToGo: '{{characters}} to go',
charactersTooMany: '{{characters}} too many',
checksPassing: '{{current}}/{{max}} checks are passing',
good: 'Good',
imageAutoGenerationTip: 'Auto-generation will retrieve the selected hero image.',
lengthTipDescription:
'This should be between {{minLength}} and {{maxLength}} characters. For help in writing quality meta descriptions, see ',
lengthTipTitle:
'This should be between {{minLength}} and {{maxLength}} characters. For help in writing quality meta titles, see ',
noImage: 'No image',
preview: 'Preview',
previewDescription: 'Exact result listings may vary based on content and search relevancy.',
tooLong: 'Too long',
tooShort: 'Too short',
},
},
es: {
$schema: './translation-schema.json',
'plugin-seo': {
almostThere: 'Ya casi está',
autoGenerate: 'Autogénerar',
bestPractices: 'mejores prácticas',
characterCount: '{{current}}/{{minLength}}-{{maxLength}} letras, ',
charactersLeftOver: '{{characters}} letras sobrantes',
charactersToGo: '{{characters}} letras sobrantes',
charactersTooMany: '{{characters}} letras demasiados',
checksPassing: '{{current}}/{{max}} las comprobaciones están pasando',
good: 'Bien',
imageAutoGenerationTip: 'La autogeneración recuperará la imagen de héroe seleccionada.',
lengthTipDescription:
'Esto debe estar entre {{minLength}} y {{maxLength}} caracteres. Para obtener ayuda sobre cómo escribir meta descripciones de calidad, consulte ',
lengthTipTitle:
'Debe tener entre {{minLength}} y {{maxLength}} caracteres. Para obtener ayuda sobre cómo escribir metatítulos de calidad, consulte ',
noImage: 'Sin imagen',
preview: 'Vista previa',
previewDescription:
'Las listas de resultados pueden variar segun la relevancia de buesqueda y el contenido.',
tooLong: 'Demasiado largo',
tooShort: 'Demasiado corto',
},
},
fa: {
$schema: './translation-schema.json',
'plugin-seo': {
almostThere: 'چیزیی باقی نمونده',
autoGenerate: 'تولید خودکار',
bestPractices: 'آموزش بیشتر',
characterCount: '{{current}}/{{minLength}}-{{maxLength}} کلمه، ',
charactersLeftOver: '{{characters}} باقی مانده',
charactersToGo: '{{characters}} باقی مانده',
charactersTooMany: '{{characters}} بیش از حد',
checksPassing: '{{current}}/{{max}} بررسی‌ها با موفقیت انجام شده است',
good: 'خوب',
imageAutoGenerationTip:
'این قابلیت، تصویر فعلی بارگذاری شده در مجموعه محتوای شما را بازیابی می‌کند',
lengthTipDescription:
'این باید بین {{minLength}} و {{maxLength}} کلمه باشد. برای کمک در نوشتن توضیحات متا با کیفیت، مراجعه کنید به ',
lengthTipTitle:
'این باید بین {{minLength}} و {{maxLength}} کلمه باشد. برای کمک در نوشتن عناوین متا با کیفیت، مراجعه کنید به ',
noImage: 'بدون تصویر',
preview: 'پیش‌نمایش',
previewDescription:
'فهرست نتایج ممکن است بر اساس محتوا و متناسب با کلمه کلیدی جستجو شده باشند',
tooLong: 'خیلی طولانی',
tooShort: 'خیلی کوتاه',
},
},
fr: {
$schema: './translation-schema.json',
'plugin-seo': {
almostThere: 'On y est presque',
autoGenerate: 'Auto-générer',
bestPractices: 'bonnes pratiques',
characterCount: '{{current}}/{{minLength}}-{{maxLength}} caractères, ',
charactersLeftOver: '{{characters}} restants',
charactersToGo: '{{characters}} à ajouter',
charactersTooMany: '{{characters}} en trop',
checksPassing: '{{current}}/{{max}} vérifications réussies',
good: 'Bien',
imageAutoGenerationTip: "L'auto-génération récupérera l'image principale sélectionnée.",
lengthTipDescription:
"Ceci devrait contenir entre {{minLength}} et {{maxLength}} caractères. Pour obtenir de l'aide pour rédiger des descriptions meta de qualité, consultez les ",
lengthTipTitle:
"Ceci devrait contenir entre {{minLength}} et {{maxLength}} caractères. Pour obtenir de l'aide pour rédiger des titres meta de qualité, consultez les ",
noImage: "Pas d'image",
preview: 'Aperçu',
previewDescription:
'Les résultats exacts peuvent varier en fonction du contenu et de la pertinence de la recherche.',
tooLong: 'Trop long',
tooShort: 'Trop court',
},
},
pl: {
$schema: './translation-schema.json',
'plugin-seo': {
almostThere: 'Prawie gotowe',
autoGenerate: 'Wygeneruj automatycznie',
bestPractices: 'najlepsze praktyki',
characterCount: '{{current}}/{{minLength}}-{{maxLength}} znaków, ',
charactersLeftOver: 'zostało {{characters}} znaków',
charactersToGo: 'pozostało {{characters}} znaków',
charactersTooMany: '{{characters}} znaków za dużo',
checksPassing: '{{current}}/{{max}} testów zakończonych pomyślnie',
good: 'Dobrze',
imageAutoGenerationTip: 'Automatyczne generowanie pobierze wybrany główny obraz.',
lengthTipDescription:
'Długość powinna wynosić od {{minLength}} do {{maxLength}} znaków. Po porady dotyczące pisania wysokiej jakości meta opisów zobacz ',
lengthTipTitle:
'Długość powinna wynosić od {{minLength}} do {{maxLength}} znaków. Po porady dotyczące pisania wysokiej jakości meta tytułów zobacz ',
noImage: 'Brak obrazu',
preview: 'Podgląd',
previewDescription:
'Dokładne wyniki listowania mogą się różnić w zależności od treści i zgodności z kryteriami wyszukiwania.',
tooLong: 'Zbyt długie',
tooShort: 'Zbyt krótkie',
},
},
}

View File

@@ -149,7 +149,7 @@ describe('Live Preview', () => {
test('global - can edit fields', async () => { test('global - can edit fields', async () => {
await goToGlobalPreview(page, 'header') await goToGlobalPreview(page, 'header')
const field = page.locator('input#field-navItems__0__link__newTab') const field = page.locator('input#field-navItems__0__link____newTab')
await expect(field).toBeVisible() await expect(field).toBeVisible()
await expect(field).toBeEnabled() await expect(field).toBeEnabled()
await field.check() await field.check()

View File

@@ -2,7 +2,6 @@ import type { Page } from '@playwright/test'
import { expect, test } from '@playwright/test' import { expect, test } from '@playwright/test'
import path from 'path' import path from 'path'
import payload from 'payload'
import { fileURLToPath } from 'url' import { fileURLToPath } from 'url'
import type { Page as PayloadPage } from './payload-types.js' import type { Page as PayloadPage } from './payload-types.js'
@@ -11,6 +10,7 @@ import { initPageConsoleErrorCatch } from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js' import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
import { initPayloadE2E } from '../helpers/initPayloadE2E.js' import { initPayloadE2E } from '../helpers/initPayloadE2E.js'
import config from './config.js' import config from './config.js'
const filename = fileURLToPath(import.meta.url) const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename) const dirname = path.dirname(filename)
@@ -22,22 +22,32 @@ let parentId: string
let draftChildId: string let draftChildId: string
let childId: string let childId: string
async function createPage(data: Partial<PayloadPage>): Promise<PayloadPage> {
return payload.create({
collection: 'pages',
data,
}) as unknown as Promise<PayloadPage>
}
describe('Nested Docs Plugin', () => { describe('Nested Docs Plugin', () => {
beforeAll(async ({ browser }) => { beforeAll(async ({ browser }) => {
const { serverURL } = await initPayloadE2E({ config, dirname }) const { serverURL, payload } = await initPayloadE2E({ config, dirname })
url = new AdminUrlUtil(serverURL, 'pages') url = new AdminUrlUtil(serverURL, 'pages')
const context = await browser.newContext() const context = await browser.newContext()
page = await context.newPage() page = await context.newPage()
initPageConsoleErrorCatch(page) initPageConsoleErrorCatch(page)
async function createPage({
slug,
title = 'Title page',
parent,
_status = 'published',
}: Partial<PayloadPage>): Promise<PayloadPage> {
return payload.create({
collection: 'pages',
data: {
title,
slug,
_status,
parent,
},
}) as unknown as Promise<PayloadPage>
}
const parentPage = await createPage({ slug: 'parent-slug' }) const parentPage = await createPage({ slug: 'parent-slug' })
parentId = parentPage.id parentId = parentPage.id
@@ -70,41 +80,58 @@ describe('Nested Docs Plugin', () => {
let slug = page.locator(slugClass).nth(0) let slug = page.locator(slugClass).nth(0)
await expect(slug).toHaveValue('child-slug') await expect(slug).toHaveValue('child-slug')
const parentSlugInChildClass = '#field-breadcrumbs__0__url' // TODO: remove when error states are fixed
const apiTabButton = page.locator('text=API')
await apiTabButton.click()
const breadcrumbs = page.locator('text=/parent-slug').first()
await expect(breadcrumbs).toBeVisible()
const parentSlugInChild = page.locator(parentSlugInChildClass).nth(0) // TODO: add back once error states are fixed
await expect(parentSlugInChild).toHaveValue('/parent-slug') // const parentSlugInChildClass = '#field-breadcrumbs__0__url'
// const parentSlugInChild = page.locator(parentSlugInChildClass).nth(0)
// await expect(parentSlugInChild).toHaveValue('/parent-slug')
await page.goto(url.edit(parentId)) await page.goto(url.edit(parentId))
slug = page.locator(slugClass).nth(0) slug = page.locator(slugClass).nth(0)
await slug.fill('updated-parent-slug') await slug.fill('updated-parent-slug')
await expect(slug).toHaveValue('updated-parent-slug') await expect(slug).toHaveValue('updated-parent-slug')
await page.locator(publishButtonClass).nth(0).click() await page.locator(publishButtonClass).nth(0).click()
await page.waitForTimeout(1500)
await page.goto(url.edit(childId)) await page.goto(url.edit(childId))
await expect(parentSlugInChild).toHaveValue('/updated-parent-slug')
// TODO: remove when error states are fixed
await apiTabButton.click()
const updatedBreadcrumbs = page.locator('text=/updated-parent-slug').first()
await expect(updatedBreadcrumbs).toBeVisible()
// TODO: add back once error states are fixed
// await expect(parentSlugInChild).toHaveValue('/updated-parent-slug')
}) })
test('Draft parent slug does not update child', async () => { test('Draft parent slug does not update child', async () => {
await page.goto(url.edit(draftChildId)) await page.goto(url.edit(draftChildId))
const parentSlugInChildClass = '#field-breadcrumbs__0__url' // TODO: remove when error states are fixed
const apiTabButton = page.locator('text=API')
await apiTabButton.click()
const breadcrumbs = page.locator('text=/parent-slug-draft').first()
await expect(breadcrumbs).toBeVisible()
const parentSlugInChild = page.locator(parentSlugInChildClass).nth(0) // TODO: add back once error states are fixed
await expect(parentSlugInChild).toHaveValue('/parent-slug-draft') // const parentSlugInChildClass = '#field-breadcrumbs__0__url'
// const parentSlugInChild = page.locator(parentSlugInChildClass).nth(0)
// await expect(parentSlugInChild).toHaveValue('/parent-slug-draft')
await page.goto(url.edit(parentId)) await page.goto(url.edit(parentId))
await page.locator(slugClass).nth(0).fill('parent-updated-draft') await page.locator(slugClass).nth(0).fill('parent-updated-draft')
await page.locator(draftButtonClass).nth(0).click() await page.locator(draftButtonClass).nth(0).click()
await page.waitForTimeout(1500)
await page.goto(url.edit(draftChildId)) await page.goto(url.edit(draftChildId))
await expect(parentSlugInChild).toHaveValue('/parent-slug-draft')
await apiTabButton.click()
const updatedBreadcrumbs = page.locator('text=/parent-slug-draft').first()
await expect(updatedBreadcrumbs).toBeVisible()
// TODO: add back when error states are fixed
// await expect(parentSlugInChild).toHaveValue('/parent-slug-draft')
}) })
}) })
}) })

View File

@@ -0,0 +1,9 @@
export interface Page {
id: string
parent?: string
slug: string
_status?: 'draft' | 'published'
title?: string
updatedAt: string
createdAt: string
}

View File

@@ -37,11 +37,10 @@ export default buildConfigWithDefaults({
plugins: [ plugins: [
seo({ seo({
collections: ['users'], collections: ['users'],
fields: [],
tabbedUI: true, tabbedUI: true,
}), }),
seo({ seo({
collections: ['pages', 'posts'], collections: ['pages'],
fieldOverrides: { fieldOverrides: {
title: { title: {
required: true, required: true,
@@ -58,7 +57,6 @@ export default buildConfigWithDefaults({
generateTitle: (data: any) => `Website.com — ${data?.doc?.title?.value}`, generateTitle: (data: any) => `Website.com — ${data?.doc?.title?.value}`,
generateURL: ({ doc, locale }: any) => generateURL: ({ doc, locale }: any) =>
`https://yoursite.com/${locale ? locale + '/' : ''}${doc?.slug?.value || ''}`, `https://yoursite.com/${locale ? locale + '/' : ''}${doc?.slug?.value || ''}`,
globals: ['settings'],
tabbedUI: true, tabbedUI: true,
uploadsCollection: 'media', uploadsCollection: 'media',
}), }),

View File

@@ -1,5 +1,4 @@
import type { Page } from '@playwright/test' import type { Page } from '@playwright/test'
import type { Payload } from 'payload/types'
import { expect, test } from '@playwright/test' import { expect, test } from '@playwright/test'
import path from 'path' import path from 'path'
@@ -11,20 +10,21 @@ import type { Page as PayloadPage } from './payload-types.js'
import { initPageConsoleErrorCatch } from '../helpers.js' import { initPageConsoleErrorCatch } from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js' import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
import { initPayloadE2E } from '../helpers/initPayloadE2E.js' import { initPayloadE2E } from '../helpers/initPayloadE2E.js'
import config from '../uploads/config.js' import config from './config.js'
import { mediaSlug } from './shared.js' import { mediaSlug } from './shared.js'
const filename = fileURLToPath(import.meta.url) const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename) const dirname = path.dirname(filename)
const { beforeAll, describe } = test const { beforeAll, describe } = test
let url: AdminUrlUtil let url: AdminUrlUtil
let page: Page let page: Page
let id: string let id: string
let payload: Payload
describe('SEO Plugin', () => { describe('SEO Plugin', () => {
beforeAll(async ({ browser }) => { beforeAll(async ({ browser }) => {
const { serverURL } = await initPayloadE2E({ config, dirname }) const { serverURL, payload } = await initPayloadE2E({ config, dirname })
url = new AdminUrlUtil(serverURL, 'pages') url = new AdminUrlUtil(serverURL, 'pages')
const context = await browser.newContext() const context = await browser.newContext()
@@ -68,15 +68,17 @@ describe('SEO Plugin', () => {
test('Should auto-generate meta title when button is clicked in tabs', async () => { test('Should auto-generate meta title when button is clicked in tabs', async () => {
const contentTabsClass = '.tabs-field__tabs .tabs-field__tab-button' const contentTabsClass = '.tabs-field__tabs .tabs-field__tab-button'
const autoGenerateButtonClass = '.group-field__wrap .render-fields div:nth-of-type(1) button' const autoGenerateButtonClass = '.group-field__wrap .render-fields div:nth-of-type(1) button'
const metaTitleClass = '#field-title' const metaTitleClass = '#field-meta__title'
const secondTab = page.locator(contentTabsClass).nth(1) const secondTab = page.locator(contentTabsClass).nth(1)
await secondTab.click() await secondTab.click()
const metaTitle = page.locator(metaTitleClass).nth(0) const metaTitle = page.locator(metaTitleClass)
await expect(metaTitle).toHaveValue('This is a test meta title') await expect(metaTitle).toHaveValue('This is a test meta title')
const autoGenButton = page.locator(autoGenerateButtonClass).nth(0) const autoGenButton = page.locator(autoGenerateButtonClass).nth(0)
await expect(autoGenButton).toContainText('Auto-generate')
await autoGenButton.click() await autoGenButton.click()
await expect(metaTitle).toHaveValue('Website.com — Test Page') await expect(metaTitle).toHaveValue('Website.com — Test Page')
@@ -108,17 +110,17 @@ describe('SEO Plugin', () => {
await page.goto(url.edit(id)) await page.goto(url.edit(id))
const contentTabsClass = '.tabs-field__tabs .tabs-field__tab-button' const contentTabsClass = '.tabs-field__tabs .tabs-field__tab-button'
const autoGenerateButtonClass = '.group-field__wrap .render-fields div:nth-of-type(1) button' const autoGenerateButtonClass = '.group-field__wrap .render-fields div:nth-of-type(1) button'
const metaDescriptionClass = '#field-description' const metaDescriptionClass = '#field-meta__description'
const previewClass = const previewClass =
'#field-meta > div > div.render-fields.render-fields--margins-small > div:nth-child(6) > div:nth-child(3)' '#field-meta > div > div.render-fields.render-fields--margins-small > div:nth-child(6)'
const secondTab = page.locator(contentTabsClass).nth(1) const secondTab = page.locator(contentTabsClass).nth(1)
await secondTab.click() await secondTab.click()
const metaDescription = page.locator(metaDescriptionClass).nth(0) const metaDescription = page.locator(metaDescriptionClass)
await metaDescription.fill('My new amazing SEO description') await metaDescription.fill('My new amazing SEO description')
const preview = page.locator(previewClass).nth(0) const preview = page.locator(previewClass)
await expect(preview).toContainText('https://yoursite.com/en/') await expect(preview).toContainText('https://yoursite.com/en/')
await expect(preview).toContainText('This is a test meta title') await expect(preview).toContainText('This is a test meta title')
await expect(preview).toContainText('My new amazing SEO description') await expect(preview).toContainText('My new amazing SEO description')
@@ -147,6 +149,7 @@ describe('SEO Plugin', () => {
// Change language to Spanish // Change language to Spanish
await languageField.click() await languageField.click()
await options.locator('text=Español').click() await options.locator('text=Español').click()
await expect(languageField).toContainText('Español')
// Navigate back to the page // Navigate back to the page
await page.goto(url.edit(id)) await page.goto(url.edit(id))

View File

@@ -11,11 +11,7 @@
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"jsx": "preserve", "jsx": "preserve",
"lib": [ "lib": ["dom", "dom.iterable", "esnext"],
"dom",
"dom.iterable",
"esnext"
],
"noEmit": true, "noEmit": true,
"outDir": "./dist", "outDir": "./dist",
"resolveJsonModule": true, "resolveJsonModule": true,
@@ -23,11 +19,7 @@
"skipLibCheck": true, "skipLibCheck": true,
"sourceMap": true, "sourceMap": true,
"strict": false, "strict": false,
"types": [ "types": ["jest", "node", "@types/jest"],
"jest",
"node",
"@types/jest"
],
"incremental": true, "incremental": true,
"isolatedModules": true, "isolatedModules": true,
"plugins": [ "plugins": [
@@ -36,65 +28,26 @@
} }
], ],
"paths": { "paths": {
"@payload-config": [ "@payload-config": ["./test/_community/config.ts"],
"./test/_community/config.ts" "@payloadcms/live-preview": ["./packages/live-preview/src"],
], "@payloadcms/live-preview-react": ["./packages/live-preview-react/src/index.ts"],
"@payloadcms/live-preview": [ "@payloadcms/ui/assets": ["./packages/ui/src/assets/index.ts"],
"./packages/live-preview/src" "@payloadcms/ui/elements/*": ["./packages/ui/src/elements/*/index.tsx"],
], "@payloadcms/ui/fields/*": ["./packages/ui/src/fields/*/index.tsx"],
"@payloadcms/live-preview-react": [ "@payloadcms/ui/forms/*": ["./packages/ui/src/forms/*/index.tsx"],
"./packages/live-preview-react/src/index.ts" "@payloadcms/ui/graphics/*": ["./packages/ui/src/graphics/*/index.tsx"],
], "@payloadcms/ui/hooks/*": ["./packages/ui/src/hooks/*.ts"],
"@payloadcms/ui/assets": [ "@payloadcms/ui/icons/*": ["./packages/ui/src/icons/*/index.tsx"],
"./packages/ui/src/assets/index.ts" "@payloadcms/ui/providers/*": ["./packages/ui/src/providers/*/index.tsx"],
], "@payloadcms/ui/templates/*": ["./packages/ui/src/templates/*/index.tsx"],
"@payloadcms/ui/elements/*": [ "@payloadcms/ui/utilities/*": ["./packages/ui/src/utilities/*.ts"],
"./packages/ui/src/elements/*/index.tsx" "@payloadcms/ui/scss": ["./packages/ui/src/scss.scss"],
], "@payloadcms/ui/scss/app.scss": ["./packages/ui/src/scss/app.scss"],
"@payloadcms/ui/fields/*": [ "@payloadcms/next/*": ["./packages/next/src/*"],
"./packages/ui/src/fields/*/index.tsx" "@payloadcms/next": ["./packages/next/src/exports/*"]
],
"@payloadcms/ui/forms/*": [
"./packages/ui/src/forms/*/index.tsx"
],
"@payloadcms/ui/graphics/*": [
"./packages/ui/src/graphics/*/index.tsx"
],
"@payloadcms/ui/hooks/*": [
"./packages/ui/src/hooks/*.ts"
],
"@payloadcms/ui/icons/*": [
"./packages/ui/src/icons/*/index.tsx"
],
"@payloadcms/ui/providers/*": [
"./packages/ui/src/providers/*/index.tsx"
],
"@payloadcms/ui/templates/*": [
"./packages/ui/src/templates/*/index.tsx"
],
"@payloadcms/ui/utilities/*": [
"./packages/ui/src/utilities/*.ts"
],
"@payloadcms/ui/scss": [
"./packages/ui/src/scss.scss"
],
"@payloadcms/ui/scss/app.scss": [
"./packages/ui/src/scss/app.scss"
],
"@payloadcms/next/*": [
"./packages/next/src/*"
],
"@payloadcms/next": [
"./packages/next/src/exports/*"
]
} }
}, },
"exclude": [ "exclude": ["dist", "build", "temp", "node_modules"],
"dist",
"build",
"temp",
"node_modules"
],
"composite": true, "composite": true,
"references": [ "references": [
{ {
@@ -155,9 +108,5 @@
"path": "./packages/ui" "path": "./packages/ui"
} }
], ],
"include": [ "include": ["next-env.d.ts", ".next/types/**/*.ts", "scripts/**/*.ts"]
"next-env.d.ts",
".next/types/**/*.ts",
"scripts/**/*.ts"
]
} }