From 0a2ecf8a4a790433f176d471ad19a98ecc845e5b Mon Sep 17 00:00:00 2001 From: Jacob Fletcher Date: Mon, 8 Jul 2024 17:28:05 -0400 Subject: [PATCH] fix!: exports getSiblingData, getDataByPath, and reduceFieldsToValues from payload (#7070) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Exports `getSiblingData`, `getDataByPath`, `reduceFieldsToValues`, and `unflatten` from `payload`. These utilities were previously accessible using direct import paths from `@payloadcms/ui`—but this is no longer advised since moving to a pre-bundled UI library pattern. Instead of simply exporting these from the `@payloadcms/ui` package, these exports have been moved to Payload itself to provision for use outside of React environments. This is considered a breaking change. If you were previously importing any of these utilities, the imports paths have changed as follows: Old: ```ts import { getSiblingData, getDataByPath, reduceFieldsToValues } from '@payloadcms/ui/forms/Form' import { unflatten } from '@payloadcms/ui/utilities' ``` New: ```ts import { getSiblingData, getDataByPath, reduceFieldsToValues, unflatten } from 'payload/shared' ``` The `is-buffer` dependency was also removed in this PR. - [x] I have read and understand the [CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md) document in this repository. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## Checklist: - [x] Existing test suite passes locally with my changes --- docs/admin/hooks.mdx | 3 ++- .../next/src/views/Document/getDocumentData.tsx | 2 +- .../next/src/views/LivePreview/Preview/index.tsx | 2 +- packages/payload/src/exports/shared.ts | 6 ++++++ .../src/utilities}/getDataByPath.ts | 2 +- .../src/utilities}/getSiblingData.ts | 4 ++-- .../src/utilities/reduceFieldsToValues.ts | 0 .../{ui => payload}/src/utilities/unflatten.ts | 14 +++++++++++++- .../features/blocks/component/FormSavePlugin.tsx | 2 +- .../src/field/elements/link/Button/index.tsx | 3 ++- .../src/field/elements/link/Element/index.tsx | 4 ++-- packages/ui/package.json | 1 - packages/ui/src/elements/Upload/index.tsx | 3 +-- packages/ui/src/exports/shared/index.ts | 1 - packages/ui/src/forms/Form/index.tsx | 10 ++++++---- packages/ui/src/providers/DocumentInfo/index.tsx | 2 +- packages/ui/src/utilities/buildFormState.ts | 5 +++-- .../reduceFieldsToValuesWithValidation.ts | 2 +- pnpm-lock.yaml | 3 --- 19 files changed, 43 insertions(+), 26 deletions(-) rename packages/{ui/src/forms/Form => payload/src/utilities}/getDataByPath.ts (92%) rename packages/{ui/src/forms/Form => payload/src/utilities}/getSiblingData.ts (89%) rename packages/{ui => payload}/src/utilities/reduceFieldsToValues.ts (100%) rename packages/{ui => payload}/src/utilities/unflatten.ts (90%) diff --git a/docs/admin/hooks.mdx b/docs/admin/hooks.mdx index 0f20e40dd..44ef9f120 100644 --- a/docs/admin/hooks.mdx +++ b/docs/admin/hooks.mdx @@ -136,7 +136,8 @@ You can do lots of powerful stuff by retrieving the full form state, like using ```tsx 'use client' -import { useAllFormFields, reduceFieldsToValues, getSiblingData } from '@payloadcms/ui' +import { useAllFormFields } from '@payloadcms/ui' +import { reduceFieldsToValues, getSiblingData } from 'payload/shared' const ExampleComponent: React.FC = () => { // the `fields` const will be equal to all fields' state, diff --git a/packages/next/src/views/Document/getDocumentData.tsx b/packages/next/src/views/Document/getDocumentData.tsx index b19246851..5bfb9f5f7 100644 --- a/packages/next/src/views/Document/getDocumentData.tsx +++ b/packages/next/src/views/Document/getDocumentData.tsx @@ -6,8 +6,8 @@ import type { SanitizedGlobalConfig, } from 'payload' -import { reduceFieldsToValues } from '@payloadcms/ui/shared' import { buildFormState } from '@payloadcms/ui/utilities/buildFormState' +import { reduceFieldsToValues } from 'payload/shared' export const getDocumentData = async (args: { collectionConfig?: SanitizedCollectionConfig diff --git a/packages/next/src/views/LivePreview/Preview/index.tsx b/packages/next/src/views/LivePreview/Preview/index.tsx index 2fe845041..7bfce44e2 100644 --- a/packages/next/src/views/LivePreview/Preview/index.tsx +++ b/packages/next/src/views/LivePreview/Preview/index.tsx @@ -3,7 +3,7 @@ import type { EditViewProps } from 'payload' import { ShimmerEffect, useAllFormFields, useDocumentEvents } from '@payloadcms/ui' -import { reduceFieldsToValues } from '@payloadcms/ui/shared' +import { reduceFieldsToValues } from 'payload/shared' import React, { useEffect } from 'react' import { useLivePreviewContext } from '../Context/context.js' diff --git a/packages/payload/src/exports/shared.ts b/packages/payload/src/exports/shared.ts index 8a2b60cff..bc03fb8f6 100644 --- a/packages/payload/src/exports/shared.ts +++ b/packages/payload/src/exports/shared.ts @@ -30,6 +30,10 @@ export { deepMerge } from '../utilities/deepMerge.js' export { fieldSchemaToJSON } from '../utilities/fieldSchemaToJSON.js' +export { getDataByPath } from '../utilities/getDataByPath.js' + +export { getSiblingData } from '../utilities/getSiblingData.js' + export { getUniqueListBy } from '../utilities/getUniqueListBy.js' export { isNumber } from '../utilities/isNumber.js' @@ -40,6 +44,8 @@ export { isReactServerComponentOrFunction, } from '../utilities/isReactComponent.js' +export { reduceFieldsToValues } from '../utilities/reduceFieldsToValues.js' + export { setsAreEqual } from '../utilities/setsAreEqual.js' export { default as toKebabCase } from '../utilities/toKebabCase.js' diff --git a/packages/ui/src/forms/Form/getDataByPath.ts b/packages/payload/src/utilities/getDataByPath.ts similarity index 92% rename from packages/ui/src/forms/Form/getDataByPath.ts rename to packages/payload/src/utilities/getDataByPath.ts index 61a0c5a2b..f29f731b3 100644 --- a/packages/ui/src/forms/Form/getDataByPath.ts +++ b/packages/payload/src/utilities/getDataByPath.ts @@ -1,6 +1,6 @@ import type { FormState } from 'payload' -import { unflatten } from '../../utilities/unflatten.js' +import { unflatten } from './unflatten.js' export 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/payload/src/utilities/getSiblingData.ts similarity index 89% rename from packages/ui/src/forms/Form/getSiblingData.ts rename to packages/payload/src/utilities/getSiblingData.ts index ee0795bd9..74fa71133 100644 --- a/packages/ui/src/forms/Form/getSiblingData.ts +++ b/packages/payload/src/utilities/getSiblingData.ts @@ -1,7 +1,7 @@ import type { Data, FormState } from 'payload' -import { reduceFieldsToValues } from '../../utilities/reduceFieldsToValues.js' -import { unflatten } from '../../utilities/unflatten.js' +import { reduceFieldsToValues } from './reduceFieldsToValues.js' +import { unflatten } from './unflatten.js' export const getSiblingData = (fields: FormState, path: string): Data => { if (!fields) return null diff --git a/packages/ui/src/utilities/reduceFieldsToValues.ts b/packages/payload/src/utilities/reduceFieldsToValues.ts similarity index 100% rename from packages/ui/src/utilities/reduceFieldsToValues.ts rename to packages/payload/src/utilities/reduceFieldsToValues.ts diff --git a/packages/ui/src/utilities/unflatten.ts b/packages/payload/src/utilities/unflatten.ts similarity index 90% rename from packages/ui/src/utilities/unflatten.ts rename to packages/payload/src/utilities/unflatten.ts index ccd67f93b..6424a3a66 100644 --- a/packages/ui/src/utilities/unflatten.ts +++ b/packages/payload/src/utilities/unflatten.ts @@ -10,7 +10,19 @@ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import isBuffer from 'is-buffer' +/* + * Copyright (c) 2020, Feross Aboukhadijeh + * Reference: https://www.npmjs.com/package/is-buffer + * All rights reserved. + */ +function isBuffer(obj) { + return ( + obj != null && + obj.constructor != null && + typeof obj.constructor.isBuffer === 'function' && + obj.constructor.isBuffer(obj) + ) +} interface Opts { delimiter?: string diff --git a/packages/richtext-lexical/src/features/blocks/component/FormSavePlugin.tsx b/packages/richtext-lexical/src/features/blocks/component/FormSavePlugin.tsx index d0b87adc2..28bd107a2 100644 --- a/packages/richtext-lexical/src/features/blocks/component/FormSavePlugin.tsx +++ b/packages/richtext-lexical/src/features/blocks/component/FormSavePlugin.tsx @@ -2,7 +2,7 @@ import type { Data, FormState } from 'payload' import type React from 'react' import { useAllFormFields } from '@payloadcms/ui' -import { reduceFieldsToValues } from '@payloadcms/ui/shared' +import { reduceFieldsToValues } from 'payload/shared' import { useEffect } from 'react' import { removeEmptyArrayValues } from './removeEmptyArrayValues.js' 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 b12112979..90a4cdeb6 100644 --- a/packages/richtext-slate/src/field/elements/link/Button/index.tsx +++ b/packages/richtext-slate/src/field/elements/link/Button/index.tsx @@ -3,7 +3,8 @@ import type { FormState } from 'payload' import { useConfig, useDrawerSlug, useFieldProps, useModal, useTranslation } from '@payloadcms/ui' -import { getFormState, reduceFieldsToValues } from '@payloadcms/ui/shared' +import { getFormState } from '@payloadcms/ui/shared' +import { reduceFieldsToValues } from 'payload/shared' import React, { Fragment, useState } from 'react' import { Editor, Range, Transforms } from 'slate' import { ReactEditor, useSlate } from 'slate-react' 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 bf7b91cfd..8c0bc498f 100644 --- a/packages/richtext-slate/src/field/elements/link/Element/index.tsx +++ b/packages/richtext-slate/src/field/elements/link/Element/index.tsx @@ -14,8 +14,8 @@ import { useModal, useTranslation, } from '@payloadcms/ui' -import { getFormState, reduceFieldsToValues } from '@payloadcms/ui/shared' -import { deepCopyObject } from 'payload/shared' +import { getFormState } from '@payloadcms/ui/shared' +import { deepCopyObject, reduceFieldsToValues } from 'payload/shared' import React, { useCallback, useEffect, useState } from 'react' import { Editor, Node, Transforms } from 'slate' import { ReactEditor, useSlate } from 'slate-react' diff --git a/packages/ui/package.json b/packages/ui/package.json index c3894ef48..448c75338 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -82,7 +82,6 @@ "bson-objectid": "2.0.4", "date-fns": "3.3.1", "dequal": "2.0.3", - "is-buffer": "^2.0.5", "md5": "2.3.0", "object-to-formdata": "4.5.1", "qs": "6.12.1", diff --git a/packages/ui/src/elements/Upload/index.tsx b/packages/ui/src/elements/Upload/index.tsx index 322626ea9..00118919a 100644 --- a/packages/ui/src/elements/Upload/index.tsx +++ b/packages/ui/src/elements/Upload/index.tsx @@ -1,7 +1,7 @@ 'use client' import type { FormState, SanitizedCollectionConfig } from 'payload' -import { isImage } from 'payload/shared' +import { isImage, reduceFieldsToValues } from 'payload/shared' import React, { useCallback, useEffect, useState } from 'react' import { FieldError } from '../../fields/FieldError/index.js' @@ -11,7 +11,6 @@ import { useField } from '../../forms/useField/index.js' import { useDocumentInfo } from '../../providers/DocumentInfo/index.js' import { useFormQueryParams } from '../../providers/FormQueryParams/index.js' import { useTranslation } from '../../providers/Translation/index.js' -import { reduceFieldsToValues } from '../../utilities/reduceFieldsToValues.js' import { Button } from '../Button/index.js' import { Drawer, DrawerToggler } from '../Drawer/index.js' import { Dropzone } from '../Dropzone/index.js' diff --git a/packages/ui/src/exports/shared/index.ts b/packages/ui/src/exports/shared/index.ts index 17bb76c0c..10d910a79 100644 --- a/packages/ui/src/exports/shared/index.ts +++ b/packages/ui/src/exports/shared/index.ts @@ -17,4 +17,3 @@ export { } from '../../utilities/groupNavItems.js' export { hasSavePermission } from '../../utilities/hasSavePermission.js' export { isEditing } from '../../utilities/isEditing.js' -export { reduceFieldsToValues } from '../../utilities/reduceFieldsToValues.js' diff --git a/packages/ui/src/forms/Form/index.tsx b/packages/ui/src/forms/Form/index.tsx index 528abc73a..831455894 100644 --- a/packages/ui/src/forms/Form/index.tsx +++ b/packages/ui/src/forms/Form/index.tsx @@ -5,7 +5,12 @@ import type { FormState } from 'payload' import { dequal } from 'dequal/lite' // lite: no need for Map and Set support import { useRouter } from 'next/navigation.js' import { serialize } from 'object-to-formdata' -import { wait } from 'payload/shared' +import { + getDataByPath as getDataByPathFunc, + getSiblingData as getSiblingDataFunc, + reduceFieldsToValues, + wait, +} from 'payload/shared' import qs from 'qs' import React, { useCallback, useEffect, useReducer, useRef, useState } from 'react' import { toast } from 'sonner' @@ -28,7 +33,6 @@ import { useOperation } from '../../providers/Operation/index.js' import { useTranslation } from '../../providers/Translation/index.js' import { requests } from '../../utilities/api.js' import { getFormState } from '../../utilities/getFormState.js' -import { reduceFieldsToValues } from '../../utilities/reduceFieldsToValues.js' import { FormContext, FormFieldsContext, @@ -40,8 +44,6 @@ import { } from './context.js' import { errorMessages } from './errorMessages.js' import { fieldReducer } from './fieldReducer.js' -import { getDataByPath as getDataByPathFunc } from './getDataByPath.js' -import { getSiblingData as getSiblingDataFunc } from './getSiblingData.js' import { initContextState } from './initContextState.js' import { mergeServerFormState } from './mergeServerFormState.js' diff --git a/packages/ui/src/providers/DocumentInfo/index.tsx b/packages/ui/src/providers/DocumentInfo/index.tsx index 0886f3e80..a26bcede4 100644 --- a/packages/ui/src/providers/DocumentInfo/index.tsx +++ b/packages/ui/src/providers/DocumentInfo/index.tsx @@ -12,6 +12,7 @@ import type { } from 'payload' import { notFound } from 'next/navigation.js' +import { reduceFieldsToValues } from 'payload/shared' import qs from 'qs' import React, { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react' @@ -21,7 +22,6 @@ import { formatDocTitle } from '../../utilities/formatDocTitle.js' import { getFormState } from '../../utilities/getFormState.js' import { hasSavePermission as getHasSavePermission } from '../../utilities/hasSavePermission.js' import { isEditing as getIsEditing } from '../../utilities/isEditing.js' -import { reduceFieldsToValues } from '../../utilities/reduceFieldsToValues.js' import { useAuth } from '../Auth/index.js' import { useConfig } from '../Config/index.js' import { useLocale } from '../Locale/index.js' diff --git a/packages/ui/src/utilities/buildFormState.ts b/packages/ui/src/utilities/buildFormState.ts index c55609be5..a869f4348 100644 --- a/packages/ui/src/utilities/buildFormState.ts +++ b/packages/ui/src/utilities/buildFormState.ts @@ -1,12 +1,13 @@ import type { DocumentPreferences, Field, FormState, PayloadRequest, TypeWithID } from 'payload' +// eslint-disable-next-line payload/no-imports-from-exports-dir +import { reduceFieldsToValues } from 'payload/shared' + import type { BuildFormStateArgs } from '../forms/buildStateFromSchema/index.js' import type { FieldSchemaMap } from './buildFieldSchemaMap/types.js' // eslint-disable-next-line payload/no-imports-from-exports-dir import {} from '../exports/client/index.js' -// eslint-disable-next-line payload/no-imports-from-exports-dir -import { reduceFieldsToValues } from '../exports/shared/index.js' import { buildStateFromSchema } from '../forms/buildStateFromSchema/index.js' import { buildFieldSchemaMap } from './buildFieldSchemaMap/index.js' diff --git a/packages/ui/src/utilities/reduceFieldsToValuesWithValidation.ts b/packages/ui/src/utilities/reduceFieldsToValuesWithValidation.ts index b2e51394c..d26b24b3d 100644 --- a/packages/ui/src/utilities/reduceFieldsToValuesWithValidation.ts +++ b/packages/ui/src/utilities/reduceFieldsToValuesWithValidation.ts @@ -1,6 +1,6 @@ import type { Data, FormState } from 'payload' -import { unflatten as flatleyUnflatten } from './unflatten.js' +import { unflatten as flatleyUnflatten } from '../../../payload/src/utilities/unflatten.js' type ReturnType = { data: Data diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0a5d6d89a..28e9b933d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1419,9 +1419,6 @@ importers: dequal: specifier: 2.0.3 version: 2.0.3 - is-buffer: - specifier: ^2.0.5 - version: 2.0.5 md5: specifier: 2.3.0 version: 2.3.0