Compare commits
4 Commits
templates/
...
fix/field-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
340089f483 | ||
|
|
e8604bde6d | ||
|
|
0d49752c06 | ||
|
|
b187da4639 |
@@ -1,7 +1,7 @@
|
||||
import { type SupportedLanguages } from '@payloadcms/translations'
|
||||
|
||||
import type { SanitizedDocumentPermissions } from '../../auth/types.js'
|
||||
import type { Field, Validate } from '../../fields/config/types.js'
|
||||
import type { Field, TabAsField, Validate } from '../../fields/config/types.js'
|
||||
import type { TypedLocale } from '../../index.js'
|
||||
import type { DocumentPreferences } from '../../preferences/types.js'
|
||||
import type { PayloadRequest, Where } from '../../types/index.js'
|
||||
@@ -43,7 +43,7 @@ export type FieldState = {
|
||||
* The fieldSchema may be part of the form state if `includeSchema: true` is passed to buildFormState.
|
||||
* This will never be in the form state of the client.
|
||||
*/
|
||||
fieldSchema?: Field
|
||||
fieldSchema?: Field | TabAsField
|
||||
filterOptions?: FilterOptionsResult
|
||||
initialValue?: unknown
|
||||
passesCondition?: boolean
|
||||
|
||||
@@ -1683,7 +1683,7 @@ export type FieldWithManyClient = RelationshipFieldClient | SelectFieldClient
|
||||
export type FieldWithMaxDepth = RelationshipField | UploadField
|
||||
export type FieldWithMaxDepthClient = JoinFieldClient | RelationshipFieldClient | UploadFieldClient
|
||||
|
||||
export function fieldHasSubFields<TField extends ClientField | Field>(
|
||||
export function fieldHasSubFields<TField extends ClientField | Field | TabAsField>(
|
||||
field: TField,
|
||||
): field is TField & (TField extends ClientField ? FieldWithSubFieldsClient : FieldWithSubFields) {
|
||||
return (
|
||||
|
||||
@@ -31,30 +31,6 @@ export function getFieldPaths({
|
||||
parentIndexPath,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
}: Args): FieldPaths {
|
||||
if ('name' in field) {
|
||||
return {
|
||||
indexPath: `${parentIndexPath ? parentIndexPath + '-' : ''}${index}`,
|
||||
path: `${parentPath ? parentPath + '.' : ''}${field.name}`,
|
||||
schemaPath: `${parentSchemaPath ? parentSchemaPath + '.' : ''}${field.name}`,
|
||||
}
|
||||
}
|
||||
|
||||
const indexSuffix = `_index-${`${parentIndexPath ? parentIndexPath + '-' : ''}${index}`}`
|
||||
|
||||
return {
|
||||
indexPath: `${parentIndexPath ? parentIndexPath + '-' : ''}${index}`,
|
||||
path: `${parentPath ? parentPath + '.' : ''}${indexSuffix}`,
|
||||
schemaPath: `${parentSchemaPath ? parentSchemaPath + '.' : ''}${indexSuffix}`,
|
||||
}
|
||||
}
|
||||
|
||||
export function getFieldPathsModified({
|
||||
field,
|
||||
index,
|
||||
parentIndexPath,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
}: Args): FieldPaths {
|
||||
const parentPathSegments = parentPath.split('.')
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { Field, TabAsField } from '../../config/types.js'
|
||||
|
||||
import { MissingEditorProp } from '../../../errors/index.js'
|
||||
import { fieldAffectsData, tabHasName } from '../../config/types.js'
|
||||
import { getFieldPathsModified as getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { traverseFields } from './traverseFields.js'
|
||||
|
||||
type Args = {
|
||||
|
||||
@@ -14,7 +14,7 @@ import type { Field, TabAsField } from '../../config/types.js'
|
||||
import { MissingEditorProp } from '../../../errors/index.js'
|
||||
import { fieldAffectsData, tabHasName } from '../../config/types.js'
|
||||
import { getDefaultValue } from '../../getDefaultValue.js'
|
||||
import { getFieldPathsModified as getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { relationshipPopulationPromise } from './relationshipPopulationPromise.js'
|
||||
import { traverseFields } from './traverseFields.js'
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { deepMergeWithSourceArrays } from '../../../utilities/deepMerge.js'
|
||||
import { getLabelFromPath } from '../../../utilities/getLabelFromPath.js'
|
||||
import { getTranslatedLabel } from '../../../utilities/getTranslatedLabel.js'
|
||||
import { fieldAffectsData, tabHasName } from '../../config/types.js'
|
||||
import { getFieldPathsModified as getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { getExistingRowDoc } from './getExistingRowDoc.js'
|
||||
import { traverseFields } from './traverseFields.js'
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { JsonObject, PayloadRequest } from '../../../types/index.js'
|
||||
import type { Field, FieldHookArgs, TabAsField } from '../../config/types.js'
|
||||
|
||||
import { fieldAffectsData } from '../../config/types.js'
|
||||
import { getFieldPathsModified as getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { runBeforeDuplicateHooks } from './runHook.js'
|
||||
import { traverseFields } from './traverseFields.js'
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { Field, TabAsField } from '../../config/types.js'
|
||||
import { MissingEditorProp } from '../../../errors/index.js'
|
||||
import { fieldAffectsData, tabHasName, valueIsValueWithRelation } from '../../config/types.js'
|
||||
import { getDefaultValue } from '../../getDefaultValue.js'
|
||||
import { getFieldPathsModified as getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { cloneDataFromOriginalDoc } from '../beforeChange/cloneDataFromOriginalDoc.js'
|
||||
import { getExistingRowDoc } from '../beforeChange/getExistingRowDoc.js'
|
||||
import { traverseFields } from './traverseFields.js'
|
||||
|
||||
@@ -32,6 +32,7 @@ export const getGenerateSchemaMap =
|
||||
fields: field.fields,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentPath: '',
|
||||
parentSchemaPath: `${schemaPath}.lexical_internal_feature.${featureKey}.${schemaKey}`,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
@@ -34,6 +34,7 @@ export const getGenerateSchemaMap =
|
||||
fields: args.admin?.link?.fields as Field[],
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentPath: '',
|
||||
parentSchemaPath: `${schemaPath}.${linkFieldsSchemaPath}`,
|
||||
schemaMap,
|
||||
})
|
||||
@@ -68,6 +69,7 @@ export const getGenerateSchemaMap =
|
||||
fields: args?.admin?.upload?.collections[collection.slug]?.fields,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentPath: '',
|
||||
parentSchemaPath: `${schemaPath}.${uploadFieldsSchemaPath}.${collection.slug}`,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
PayloadRequest,
|
||||
SanitizedFieldPermissions,
|
||||
SanitizedFieldsPermissions,
|
||||
TabAsField,
|
||||
Validate,
|
||||
} from 'payload'
|
||||
|
||||
@@ -21,7 +22,6 @@ import {
|
||||
fieldIsHiddenOrDisabled,
|
||||
fieldIsID,
|
||||
fieldIsLocalized,
|
||||
getFieldPaths,
|
||||
tabHasName,
|
||||
} from 'payload/shared'
|
||||
|
||||
@@ -42,7 +42,7 @@ export type AddFieldStatePromiseArgs = {
|
||||
clientFieldSchemaMap?: ClientFieldSchemaMap
|
||||
collectionSlug?: string
|
||||
data: Data
|
||||
field: Field
|
||||
field: Field | TabAsField
|
||||
fieldIndex: number
|
||||
fieldSchemaMap: FieldSchemaMap
|
||||
/**
|
||||
@@ -168,7 +168,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
return
|
||||
}
|
||||
|
||||
const validate: Validate = field.validate
|
||||
const validate: Validate = 'validate' in field ? field.validate : undefined
|
||||
|
||||
let validationResult: string | true = true
|
||||
|
||||
@@ -235,12 +235,13 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
const arrayValue = Array.isArray(data[field.name]) ? data[field.name] : []
|
||||
|
||||
const { promises, rows } = arrayValue.reduce(
|
||||
(acc, row, i: number) => {
|
||||
const parentPath = path + '.' + i
|
||||
(acc, row, rowIndex: number) => {
|
||||
const rowPath = path + '.' + rowIndex
|
||||
|
||||
row.id = row?.id || new ObjectId().toHexString()
|
||||
|
||||
if (!omitParents && (!filter || filter(args))) {
|
||||
const idKey = parentPath + '.id'
|
||||
const idKey = rowPath + '.id'
|
||||
|
||||
state[idKey] = {
|
||||
initialValue: row.id,
|
||||
@@ -270,7 +271,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
operation,
|
||||
parentIndexPath: '',
|
||||
parentPassesCondition: passesCondition,
|
||||
parentPath,
|
||||
parentPath: rowPath,
|
||||
parentSchemaPath: schemaPath,
|
||||
permissions:
|
||||
fieldPermissions === true ? fieldPermissions : fieldPermissions?.fields || {},
|
||||
@@ -357,22 +358,23 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
const blocksValue = Array.isArray(data[field.name]) ? data[field.name] : []
|
||||
|
||||
const { promises, rowMetadata } = blocksValue.reduce(
|
||||
(acc, row, i: number) => {
|
||||
(acc, row, rowIndex: number) => {
|
||||
const block = field.blocks.find((blockType) => blockType.slug === row.blockType)
|
||||
|
||||
if (!block) {
|
||||
throw new Error(
|
||||
`Block with type "${row.blockType}" was found in block data, but no block with that type is defined in the config for field with schema path ${schemaPath}.`,
|
||||
)
|
||||
}
|
||||
|
||||
const parentPath = path + '.' + i
|
||||
const rowPath = path + '.' + rowIndex
|
||||
|
||||
if (block) {
|
||||
row.id = row?.id || new ObjectId().toHexString()
|
||||
|
||||
if (!omitParents && (!filter || filter(args))) {
|
||||
// Handle block `id` field
|
||||
const idKey = parentPath + '.id'
|
||||
const idKey = rowPath + '.id'
|
||||
|
||||
state[idKey] = {
|
||||
initialValue: row.id,
|
||||
@@ -386,7 +388,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
}
|
||||
|
||||
// Handle `blockType` field
|
||||
const fieldKey = parentPath + '.blockType'
|
||||
const fieldKey = rowPath + '.blockType'
|
||||
|
||||
state[fieldKey] = {
|
||||
initialValue: row.blockType,
|
||||
@@ -400,7 +402,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
}
|
||||
|
||||
// Handle `blockName` field
|
||||
const blockNameKey = parentPath + '.blockName'
|
||||
const blockNameKey = rowPath + '.blockName'
|
||||
|
||||
state[blockNameKey] = {}
|
||||
|
||||
@@ -434,7 +436,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
operation,
|
||||
parentIndexPath: '',
|
||||
parentPassesCondition: passesCondition,
|
||||
parentPath,
|
||||
parentPath: rowPath,
|
||||
parentSchemaPath: schemaPath + '.' + block.slug,
|
||||
permissions:
|
||||
fieldPermissions === true
|
||||
@@ -546,6 +548,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'relationship':
|
||||
case 'upload': {
|
||||
if (field.filterOptions) {
|
||||
@@ -678,8 +681,8 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
operation,
|
||||
parentIndexPath: indexPath,
|
||||
parentPassesCondition: passesCondition,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
parentPath: path,
|
||||
parentSchemaPath: schemaPath,
|
||||
permissions: parentPermissions, // TODO: Verify this is correct
|
||||
preferences,
|
||||
previousFormState,
|
||||
@@ -690,74 +693,85 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
||||
skipValidation,
|
||||
state,
|
||||
})
|
||||
} else if (field.type === 'tabs') {
|
||||
const promises = field.tabs.map((tab, tabIndex) => {
|
||||
const isNamedTab = tabHasName(tab)
|
||||
} else if (field.type === 'tab') {
|
||||
const isNamedTab = tabHasName(field)
|
||||
|
||||
const {
|
||||
indexPath: tabIndexPath,
|
||||
path: tabPath,
|
||||
schemaPath: tabSchemaPath,
|
||||
} = getFieldPaths({
|
||||
field: {
|
||||
...tab,
|
||||
type: 'tab',
|
||||
},
|
||||
index: tabIndex,
|
||||
parentIndexPath: indexPath,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
})
|
||||
let childPermissions: SanitizedFieldsPermissions = undefined
|
||||
|
||||
let childPermissions: SanitizedFieldsPermissions = undefined
|
||||
|
||||
if (isNamedTab) {
|
||||
if (parentPermissions === true) {
|
||||
if (isNamedTab) {
|
||||
if (parentPermissions === true) {
|
||||
childPermissions = true
|
||||
} else {
|
||||
const tabPermissions = parentPermissions?.[field.name]
|
||||
if (tabPermissions === true) {
|
||||
childPermissions = true
|
||||
} else {
|
||||
const tabPermissions = parentPermissions?.[tab.name]
|
||||
if (tabPermissions === true) {
|
||||
childPermissions = true
|
||||
} else {
|
||||
childPermissions = tabPermissions?.fields
|
||||
}
|
||||
childPermissions = tabPermissions?.fields
|
||||
}
|
||||
} else {
|
||||
childPermissions = parentPermissions
|
||||
}
|
||||
} else {
|
||||
childPermissions = parentPermissions
|
||||
}
|
||||
|
||||
return iterateFields({
|
||||
id,
|
||||
addErrorPathToParent: addErrorPathToParentArg,
|
||||
anyParentLocalized: tab.localized || anyParentLocalized,
|
||||
clientFieldSchemaMap,
|
||||
collectionSlug,
|
||||
data: isNamedTab ? data?.[tab.name] || {} : data,
|
||||
fields: tab.fields,
|
||||
fieldSchemaMap,
|
||||
filter,
|
||||
forceFullValue,
|
||||
fullData,
|
||||
includeSchema,
|
||||
omitParents,
|
||||
operation,
|
||||
parentIndexPath: isNamedTab ? '' : tabIndexPath,
|
||||
parentPassesCondition: passesCondition,
|
||||
parentPath: isNamedTab ? tabPath : parentPath,
|
||||
parentSchemaPath: isNamedTab ? tabSchemaPath : parentSchemaPath,
|
||||
permissions: childPermissions,
|
||||
preferences,
|
||||
previousFormState,
|
||||
renderAllFields,
|
||||
renderFieldFn,
|
||||
req,
|
||||
skipConditionChecks,
|
||||
skipValidation,
|
||||
state,
|
||||
})
|
||||
return iterateFields({
|
||||
id,
|
||||
addErrorPathToParent: addErrorPathToParentArg,
|
||||
anyParentLocalized: fieldIsLocalized(field) || anyParentLocalized,
|
||||
clientFieldSchemaMap,
|
||||
collectionSlug,
|
||||
data: isNamedTab ? data?.[field.name] || {} : data,
|
||||
fields: field.fields,
|
||||
fieldSchemaMap,
|
||||
filter,
|
||||
forceFullValue,
|
||||
fullData,
|
||||
includeSchema,
|
||||
omitParents,
|
||||
operation,
|
||||
parentIndexPath: isNamedTab ? '' : indexPath,
|
||||
parentPassesCondition: passesCondition,
|
||||
parentPath: isNamedTab ? path : parentPath,
|
||||
parentSchemaPath: schemaPath,
|
||||
permissions: childPermissions,
|
||||
preferences,
|
||||
previousFormState,
|
||||
renderAllFields,
|
||||
renderFieldFn,
|
||||
req,
|
||||
skipConditionChecks,
|
||||
skipValidation,
|
||||
state,
|
||||
})
|
||||
} else if (field.type === 'tabs') {
|
||||
return iterateFields({
|
||||
id,
|
||||
addErrorPathToParent: addErrorPathToParentArg,
|
||||
anyParentLocalized: fieldIsLocalized(field) || anyParentLocalized,
|
||||
clientFieldSchemaMap,
|
||||
collectionSlug,
|
||||
data,
|
||||
fields: field.tabs.map((tab) => ({ ...tab, type: 'tab' })),
|
||||
fieldSchemaMap,
|
||||
filter,
|
||||
forceFullValue,
|
||||
fullData,
|
||||
includeSchema,
|
||||
omitParents,
|
||||
operation,
|
||||
parentIndexPath: indexPath,
|
||||
parentPassesCondition: passesCondition,
|
||||
parentPath: path,
|
||||
parentSchemaPath: schemaPath,
|
||||
permissions: parentPermissions,
|
||||
preferences,
|
||||
previousFormState,
|
||||
renderAllFields,
|
||||
renderFieldFn,
|
||||
req,
|
||||
skipConditionChecks,
|
||||
skipValidation,
|
||||
state,
|
||||
})
|
||||
|
||||
await Promise.all(promises)
|
||||
} else if (field.type === 'ui') {
|
||||
if (!filter || filter(args)) {
|
||||
state[path] = fieldState
|
||||
|
||||
@@ -2,12 +2,13 @@ import type {
|
||||
ClientFieldSchemaMap,
|
||||
Data,
|
||||
DocumentPreferences,
|
||||
Field as FieldSchema,
|
||||
Field,
|
||||
FieldSchemaMap,
|
||||
FormState,
|
||||
FormStateWithoutComponents,
|
||||
PayloadRequest,
|
||||
SanitizedFieldsPermissions,
|
||||
TabAsField,
|
||||
} from 'payload'
|
||||
|
||||
import { getFieldPaths } from 'payload/shared'
|
||||
@@ -26,7 +27,7 @@ type Args = {
|
||||
clientFieldSchemaMap?: ClientFieldSchemaMap
|
||||
collectionSlug?: string
|
||||
data: Data
|
||||
fields: FieldSchema[]
|
||||
fields: (Field | TabAsField)[]
|
||||
fieldSchemaMap: FieldSchemaMap
|
||||
filter?: (args: AddFieldStatePromiseArgs) => boolean
|
||||
/**
|
||||
@@ -108,7 +109,7 @@ export const iterateFields = async ({
|
||||
const { indexPath, path, schemaPath } = getFieldPaths({
|
||||
field,
|
||||
index: fieldIndex,
|
||||
parentIndexPath: 'name' in field ? '' : parentIndexPath,
|
||||
parentIndexPath,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
})
|
||||
|
||||
@@ -62,6 +62,7 @@ export const buildClientFieldSchemaMap = (args: {
|
||||
fields: fieldsToSet,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentPath: '',
|
||||
parentSchemaPath: collectionSlug,
|
||||
payload,
|
||||
schemaMap,
|
||||
@@ -81,6 +82,7 @@ export const buildClientFieldSchemaMap = (args: {
|
||||
fields: matchedGlobal.fields,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentPath: '',
|
||||
parentSchemaPath: globalSlug,
|
||||
payload,
|
||||
schemaMap,
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
import type { I18n } from '@payloadcms/translations'
|
||||
|
||||
import {
|
||||
type ClientConfig,
|
||||
type ClientField,
|
||||
type ClientFieldSchemaMap,
|
||||
createClientFields,
|
||||
type Field,
|
||||
type FieldSchemaMap,
|
||||
type Payload,
|
||||
import type {
|
||||
ClientConfig,
|
||||
ClientField,
|
||||
ClientFieldSchemaMap,
|
||||
Field,
|
||||
FieldSchemaMap,
|
||||
Payload,
|
||||
TabAsFieldClient,
|
||||
} from 'payload'
|
||||
|
||||
import { createClientFields } from 'payload'
|
||||
import { getFieldPaths, tabHasName } from 'payload/shared'
|
||||
|
||||
type Args = {
|
||||
clientSchemaMap: ClientFieldSchemaMap
|
||||
config: ClientConfig
|
||||
fields: ClientField[]
|
||||
fields: (ClientField | TabAsFieldClient)[]
|
||||
i18n: I18n<any, any>
|
||||
parentIndexPath: string
|
||||
parentPath: string
|
||||
parentSchemaPath: string
|
||||
payload: Payload
|
||||
schemaMap: FieldSchemaMap
|
||||
@@ -28,16 +30,17 @@ export const traverseFields = ({
|
||||
fields,
|
||||
i18n,
|
||||
parentIndexPath,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
payload,
|
||||
schemaMap,
|
||||
}: Args) => {
|
||||
for (const [index, field] of fields.entries()) {
|
||||
const { indexPath, schemaPath } = getFieldPaths({
|
||||
const { indexPath, path, schemaPath } = getFieldPaths({
|
||||
field,
|
||||
index,
|
||||
parentIndexPath: 'name' in field ? '' : parentIndexPath,
|
||||
parentPath: '',
|
||||
parentIndexPath,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
})
|
||||
|
||||
@@ -45,21 +48,23 @@ export const traverseFields = ({
|
||||
|
||||
switch (field.type) {
|
||||
case 'array':
|
||||
case 'group':
|
||||
case 'group': {
|
||||
traverseFields({
|
||||
clientSchemaMap,
|
||||
config,
|
||||
fields: field.fields,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentPath: path + '.' + 0, // mock the row index
|
||||
parentSchemaPath: schemaPath,
|
||||
payload,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'blocks':
|
||||
case 'blocks': {
|
||||
field.blocks.map((block) => {
|
||||
const blockSchemaPath = `${schemaPath}.${block.slug}`
|
||||
|
||||
@@ -70,26 +75,31 @@ export const traverseFields = ({
|
||||
fields: block.fields,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentSchemaPath: blockSchemaPath,
|
||||
parentPath: path + '.' + 0, // mock the row index
|
||||
parentSchemaPath: schemaPath + '.' + block.slug,
|
||||
payload,
|
||||
schemaMap,
|
||||
})
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'collapsible':
|
||||
case 'row':
|
||||
case 'row': {
|
||||
traverseFields({
|
||||
clientSchemaMap,
|
||||
config,
|
||||
fields: field.fields,
|
||||
i18n,
|
||||
parentIndexPath: indexPath,
|
||||
parentSchemaPath,
|
||||
parentPath,
|
||||
parentSchemaPath: schemaPath,
|
||||
payload,
|
||||
schemaMap,
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
case 'richText': {
|
||||
// richText sub-fields are not part of the ClientConfig or the Config.
|
||||
@@ -132,36 +142,39 @@ export const traverseFields = ({
|
||||
break
|
||||
}
|
||||
|
||||
case 'tabs':
|
||||
field.tabs.map((tab, tabIndex) => {
|
||||
const isNamedTab = tabHasName(tab)
|
||||
case 'tab': {
|
||||
const isNamedTab = tabHasName(field)
|
||||
|
||||
const { indexPath: tabIndexPath, schemaPath: tabSchemaPath } = getFieldPaths({
|
||||
field: {
|
||||
...tab,
|
||||
type: 'tab',
|
||||
},
|
||||
index: tabIndex,
|
||||
parentIndexPath: indexPath,
|
||||
parentPath: '',
|
||||
parentSchemaPath,
|
||||
})
|
||||
|
||||
clientSchemaMap.set(tabSchemaPath, tab)
|
||||
|
||||
traverseFields({
|
||||
clientSchemaMap,
|
||||
config,
|
||||
fields: tab.fields,
|
||||
i18n,
|
||||
parentIndexPath: isNamedTab ? '' : tabIndexPath,
|
||||
parentSchemaPath: isNamedTab ? tabSchemaPath : parentSchemaPath,
|
||||
payload,
|
||||
schemaMap,
|
||||
})
|
||||
traverseFields({
|
||||
clientSchemaMap,
|
||||
config,
|
||||
fields: field.fields,
|
||||
i18n,
|
||||
parentIndexPath: isNamedTab ? '' : indexPath,
|
||||
parentPath: isNamedTab ? path : parentPath,
|
||||
parentSchemaPath: schemaPath,
|
||||
payload,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'tabs': {
|
||||
traverseFields({
|
||||
clientSchemaMap,
|
||||
config,
|
||||
fields: field.tabs.map((tab) => ({ ...tab, type: 'tab' })),
|
||||
i18n,
|
||||
parentIndexPath: indexPath,
|
||||
parentPath: path,
|
||||
parentSchemaPath: schemaPath,
|
||||
payload,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ export const buildFieldSchemaMap = (args: {
|
||||
fields: fieldsToSet,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentPath: '',
|
||||
parentSchemaPath: collectionSlug,
|
||||
schemaMap,
|
||||
})
|
||||
@@ -73,6 +74,7 @@ export const buildFieldSchemaMap = (args: {
|
||||
fields: matchedGlobal.fields,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentPath: '',
|
||||
parentSchemaPath: globalSlug,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import type { I18n } from '@payloadcms/translations'
|
||||
import type { Field, FieldSchemaMap, SanitizedConfig } from 'payload'
|
||||
import type { Field, FieldSchemaMap, SanitizedConfig, TabAsField } from 'payload'
|
||||
|
||||
import { MissingEditorProp } from 'payload'
|
||||
import { getFieldPaths, tabHasName } from 'payload/shared'
|
||||
|
||||
type Args = {
|
||||
config: SanitizedConfig
|
||||
fields: Field[]
|
||||
fields: (Field | TabAsField)[]
|
||||
i18n: I18n<any, any>
|
||||
parentIndexPath: string
|
||||
parentPath: string
|
||||
parentSchemaPath: string
|
||||
schemaMap: FieldSchemaMap
|
||||
}
|
||||
@@ -18,15 +19,16 @@ export const traverseFields = ({
|
||||
fields,
|
||||
i18n,
|
||||
parentIndexPath,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
schemaMap,
|
||||
}: Args) => {
|
||||
for (const [index, field] of fields.entries()) {
|
||||
const { indexPath, schemaPath } = getFieldPaths({
|
||||
const { indexPath, path, schemaPath } = getFieldPaths({
|
||||
field,
|
||||
index,
|
||||
parentIndexPath: 'name' in field ? '' : parentIndexPath,
|
||||
parentPath: '',
|
||||
parentIndexPath,
|
||||
parentPath,
|
||||
parentSchemaPath,
|
||||
})
|
||||
|
||||
@@ -40,13 +42,14 @@ export const traverseFields = ({
|
||||
fields: field.fields,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentPath: path + '.' + 0, // mock the row index
|
||||
parentSchemaPath: schemaPath,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
break
|
||||
|
||||
case 'blocks':
|
||||
case 'blocks': {
|
||||
field.blocks.map((block) => {
|
||||
const blockSchemaPath = `${schemaPath}.${block.slug}`
|
||||
|
||||
@@ -56,12 +59,15 @@ export const traverseFields = ({
|
||||
fields: block.fields,
|
||||
i18n,
|
||||
parentIndexPath: '',
|
||||
parentSchemaPath: blockSchemaPath,
|
||||
parentPath: path + '.' + 0, // mock the row index
|
||||
parentSchemaPath: schemaPath + '.' + block.slug,
|
||||
schemaMap,
|
||||
})
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'collapsible':
|
||||
case 'row':
|
||||
traverseFields({
|
||||
@@ -69,13 +75,14 @@ export const traverseFields = ({
|
||||
fields: field.fields,
|
||||
i18n,
|
||||
parentIndexPath: indexPath,
|
||||
parentSchemaPath,
|
||||
parentPath,
|
||||
parentSchemaPath: schemaPath,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
break
|
||||
|
||||
case 'richText':
|
||||
case 'richText': {
|
||||
if (!field?.editor) {
|
||||
throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor
|
||||
}
|
||||
@@ -95,35 +102,37 @@ export const traverseFields = ({
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'tabs':
|
||||
field.tabs.map((tab, tabIndex) => {
|
||||
const isNamedTab = tabHasName(tab)
|
||||
case 'tab': {
|
||||
const isNamedTab = tabHasName(field)
|
||||
|
||||
const { indexPath: tabIndexPath, schemaPath: tabSchemaPath } = getFieldPaths({
|
||||
field: {
|
||||
...tab,
|
||||
type: 'tab',
|
||||
},
|
||||
index: tabIndex,
|
||||
parentIndexPath: indexPath,
|
||||
parentPath: '',
|
||||
parentSchemaPath,
|
||||
})
|
||||
|
||||
schemaMap.set(tabSchemaPath, tab)
|
||||
|
||||
traverseFields({
|
||||
config,
|
||||
fields: tab.fields,
|
||||
i18n,
|
||||
parentIndexPath: isNamedTab ? '' : tabIndexPath,
|
||||
parentSchemaPath: isNamedTab ? tabSchemaPath : parentSchemaPath,
|
||||
schemaMap,
|
||||
})
|
||||
traverseFields({
|
||||
config,
|
||||
fields: field.fields,
|
||||
i18n,
|
||||
parentIndexPath: isNamedTab ? '' : indexPath,
|
||||
parentPath: isNamedTab ? path : parentPath,
|
||||
parentSchemaPath: schemaPath,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'tabs': {
|
||||
traverseFields({
|
||||
config,
|
||||
fields: field.tabs.map((tab) => ({ ...tab, type: 'tab' })),
|
||||
i18n,
|
||||
parentIndexPath: indexPath,
|
||||
parentPath: path,
|
||||
parentSchemaPath: schemaPath,
|
||||
schemaMap,
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,6 +131,8 @@ export const buildFormState = async (
|
||||
i18n,
|
||||
})
|
||||
|
||||
console.log('schemaMap', schemaMap)
|
||||
|
||||
const clientSchemaMap = getClientSchemaMap({
|
||||
collectionSlug,
|
||||
config: getClientConfig({ config, i18n, importMap: req.payload.importMap }),
|
||||
|
||||
22
test/field-paths/config.ts
Normal file
22
test/field-paths/config.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import path from 'path'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
import type { SanitizedConfig } from 'payload'
|
||||
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||
import { FieldPaths } from './collections/FieldPaths/index.js'
|
||||
|
||||
export const HooksConfig: Promise<SanitizedConfig> = buildConfigWithDefaults({
|
||||
admin: {
|
||||
importMap: {
|
||||
baseDir: path.resolve(dirname),
|
||||
},
|
||||
},
|
||||
collections: [FieldPaths],
|
||||
typescript: {
|
||||
outputFile: path.resolve(dirname, 'payload-types.ts'),
|
||||
},
|
||||
})
|
||||
|
||||
export default HooksConfig
|
||||
49
test/field-paths/e2e.spec.ts
Normal file
49
test/field-paths/e2e.spec.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { Page } from '@playwright/test'
|
||||
|
||||
import { test } from '@playwright/test'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { PayloadTestSDK } from '../helpers/sdk/index.js'
|
||||
import type { Config } from './payload-types.js'
|
||||
|
||||
import { ensureCompilationIsDone, initPageConsoleErrorCatch, saveDocAndAssert } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
const { beforeAll, beforeEach, describe } = test
|
||||
|
||||
let payload: PayloadTestSDK<Config>
|
||||
|
||||
describe('Field Paths', () => {
|
||||
let url: AdminUrlUtil
|
||||
let beforeChangeURL: AdminUrlUtil
|
||||
let page: Page
|
||||
let serverURL: string
|
||||
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig<Config>({ dirname }))
|
||||
|
||||
url = new AdminUrlUtil(serverURL, 'before-validate')
|
||||
beforeChangeURL = new AdminUrlUtil(serverURL, 'before-change-hooks')
|
||||
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
|
||||
initPageConsoleErrorCatch(page)
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('should replace value with before validate response', async () => {
|
||||
expect(true).toBe(true)
|
||||
})
|
||||
})
|
||||
19
test/field-paths/eslint.config.js
Normal file
19
test/field-paths/eslint.config.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { rootParserOptions } from '../../eslint.config.js'
|
||||
import testEslintConfig from '../eslint.config.js'
|
||||
|
||||
/** @typedef {import('eslint').Linter.Config} Config */
|
||||
|
||||
/** @type {Config[]} */
|
||||
export const index = [
|
||||
...testEslintConfig,
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
...rootParserOptions,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export default index
|
||||
177
test/field-paths/int.spec.ts
Normal file
177
test/field-paths/int.spec.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
import type { Payload, SanitizedConfig } from 'payload'
|
||||
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import { buildFieldSchemaMap } from '../../packages/ui/src/utilities/buildFieldSchemaMap/index.js'
|
||||
|
||||
import { initPayloadInt } from '../helpers/initPayloadInt.js'
|
||||
import { fieldPathsSlug } from './shared.js'
|
||||
import { initI18n } from '@payloadcms/translations'
|
||||
|
||||
let payload: Payload
|
||||
let config: SanitizedConfig
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
describe('Field Paths', () => {
|
||||
beforeAll(async () => {
|
||||
const initResult = await initPayloadInt(dirname)
|
||||
config = initResult.config
|
||||
payload = initResult.payload
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
if (typeof payload.db.destroy === 'function') {
|
||||
await payload.db.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
describe('hooks', () => {
|
||||
it('should pass correct field paths through field hooks', async () => {
|
||||
const formatExpectedFieldPaths = (
|
||||
fieldIdentifier: string,
|
||||
{
|
||||
path,
|
||||
schemaPath,
|
||||
}: {
|
||||
path: string[]
|
||||
schemaPath: string[]
|
||||
},
|
||||
) => ({
|
||||
[`${fieldIdentifier}_beforeValidate_FieldPaths`]: {
|
||||
path,
|
||||
schemaPath,
|
||||
},
|
||||
[`${fieldIdentifier}_beforeChange_FieldPaths`]: {
|
||||
path,
|
||||
schemaPath,
|
||||
},
|
||||
[`${fieldIdentifier}_afterRead_FieldPaths`]: {
|
||||
path,
|
||||
schemaPath,
|
||||
},
|
||||
[`${fieldIdentifier}_beforeDuplicate_FieldPaths`]: {
|
||||
path,
|
||||
schemaPath,
|
||||
},
|
||||
})
|
||||
|
||||
const originalDoc = await payload.create({
|
||||
collection: fieldPathsSlug,
|
||||
data: {
|
||||
topLevelNamedField: 'Test',
|
||||
array: [
|
||||
{
|
||||
fieldWithinArray: 'Test',
|
||||
nestedArray: [
|
||||
{
|
||||
fieldWithinNestedArray: 'Test',
|
||||
fieldWithinNestedRow: 'Test',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
fieldWithinRow: 'Test',
|
||||
fieldWithinUnnamedTab: 'Test',
|
||||
namedTab: {
|
||||
fieldWithinNamedTab: 'Test',
|
||||
},
|
||||
fieldWithinNestedUnnamedTab: 'Test',
|
||||
},
|
||||
})
|
||||
|
||||
// duplicate the doc to ensure that the beforeDuplicate hook is run
|
||||
const doc = await payload.duplicate({
|
||||
id: originalDoc.id,
|
||||
collection: fieldPathsSlug,
|
||||
})
|
||||
|
||||
expect(doc).toMatchObject({
|
||||
...formatExpectedFieldPaths('topLevelNamedField', {
|
||||
path: ['topLevelNamedField'],
|
||||
schemaPath: ['topLevelNamedField'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinArray', {
|
||||
path: ['array', '0', 'fieldWithinArray'],
|
||||
schemaPath: ['array', 'fieldWithinArray'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinNestedArray', {
|
||||
path: ['array', '0', 'nestedArray', '0', 'fieldWithinNestedArray'],
|
||||
schemaPath: ['array', 'nestedArray', 'fieldWithinNestedArray'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinRowWithinArray', {
|
||||
path: ['array', '0', 'fieldWithinRowWithinArray'],
|
||||
schemaPath: ['array', '_index-2', 'fieldWithinRowWithinArray'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinRow', {
|
||||
path: ['fieldWithinRow'],
|
||||
schemaPath: ['_index-2', 'fieldWithinRow'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinUnnamedTab', {
|
||||
path: ['fieldWithinUnnamedTab'],
|
||||
schemaPath: ['_index-3-0', 'fieldWithinUnnamedTab'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinNestedUnnamedTab', {
|
||||
path: ['fieldWithinNestedUnnamedTab'],
|
||||
schemaPath: ['_index-3-0-1-0', 'fieldWithinNestedUnnamedTab'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinNamedTab', {
|
||||
path: ['namedTab', 'fieldWithinNamedTab'],
|
||||
schemaPath: ['_index-3', 'namedTab', 'fieldWithinNamedTab'],
|
||||
}),
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('field schema map', () => {
|
||||
it('should build a field schema map with correct field paths', async () => {
|
||||
const i18n = await initI18n({
|
||||
config: config.i18n,
|
||||
context: 'client',
|
||||
language: 'en',
|
||||
})
|
||||
|
||||
const { fieldSchemaMap } = await buildFieldSchemaMap({
|
||||
collectionSlug: fieldPathsSlug,
|
||||
config,
|
||||
i18n,
|
||||
})
|
||||
|
||||
const fieldSchemaKeys: string[] = []
|
||||
|
||||
fieldSchemaMap.forEach((value, key) => {
|
||||
if (key === fieldPathsSlug || key.endsWith('_FieldPaths')) {
|
||||
return
|
||||
}
|
||||
|
||||
fieldSchemaKeys.push(key.replace(`${fieldPathsSlug}.`, ''))
|
||||
})
|
||||
|
||||
expect(fieldSchemaKeys).toEqual([
|
||||
'topLevelNamedField',
|
||||
'array',
|
||||
'array.fieldWithinArray',
|
||||
'array.nestedArray',
|
||||
'array.nestedArray.fieldWithinNestedArray',
|
||||
'array.nestedArray.id',
|
||||
'array._index-2',
|
||||
'array._index-2.fieldWithinRowWithinArray', // THIS ONE IS WRONG!
|
||||
'array.id',
|
||||
'_index-2',
|
||||
'_index-2.fieldWithinRow', // THIS ONE IS WRONG!
|
||||
'_index-3',
|
||||
'_index-3-0',
|
||||
'_index-3-0.fieldWithinUnnamedTab', // THIS ONE IS WRONG!
|
||||
'_index-3-0-1',
|
||||
'_index-3-0-1-0',
|
||||
'_index-3-0-1-0.fieldWithinNestedUnnamedTab', // THIS ONE IS WRONG
|
||||
'_index-3.namedTab', // THIS ONE IS WRONG!
|
||||
'_index-3.namedTab.fieldWithinNamedTab', // THIS ONE IS WRONG!
|
||||
'updatedAt',
|
||||
'createdAt',
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
572
test/field-paths/payload-types.ts
Normal file
572
test/field-paths/payload-types.ts
Normal file
@@ -0,0 +1,572 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* This file was automatically generated by Payload.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
|
||||
* and re-run `payload generate:types` to regenerate this file.
|
||||
*/
|
||||
|
||||
export interface Config {
|
||||
auth: {
|
||||
users: UserAuthOperations;
|
||||
};
|
||||
collections: {
|
||||
'field-paths': FieldPath;
|
||||
users: User;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
};
|
||||
collectionsJoins: {};
|
||||
collectionsSelect: {
|
||||
'field-paths': FieldPathsSelect<false> | FieldPathsSelect<true>;
|
||||
users: UsersSelect<false> | UsersSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
};
|
||||
globals: {};
|
||||
globalsSelect: {};
|
||||
locale: null;
|
||||
user: User & {
|
||||
collection: 'users';
|
||||
};
|
||||
jobs: {
|
||||
tasks: unknown;
|
||||
workflows: unknown;
|
||||
};
|
||||
}
|
||||
export interface UserAuthOperations {
|
||||
forgotPassword: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
login: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
registerFirstUser: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
unlock: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "field-paths".
|
||||
*/
|
||||
export interface FieldPath {
|
||||
id: string;
|
||||
topLevelNamedField?: string | null;
|
||||
array?:
|
||||
| {
|
||||
fieldWithinArray?: string | null;
|
||||
nestedArray?:
|
||||
| {
|
||||
fieldWithinNestedArray?: string | null;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
fieldWithinRowWithinArray?: string | null;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
fieldWithinRow?: string | null;
|
||||
fieldWithinUnnamedTab?: string | null;
|
||||
fieldWithinNestedUnnamedTab?: string | null;
|
||||
namedTab?: {
|
||||
fieldWithinNamedTab?: string | null;
|
||||
};
|
||||
topLevelNamedField_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
topLevelNamedField_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
topLevelNamedField_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
topLevelNamedField_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinArray_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinArray_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinArray_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinArray_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedArray_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedArray_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedArray_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedArray_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRowWithinArray_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRowWithinArray_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRowWithinArray_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRowWithinArray_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRow_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRow_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRow_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRow_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinUnnamedTab_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinUnnamedTab_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinUnnamedTab_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinUnnamedTab_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedUnnamedTab_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedUnnamedTab_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedUnnamedTab_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedUnnamedTab_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNamedTab_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNamedTab_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNamedTab_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNamedTab_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users".
|
||||
*/
|
||||
export interface User {
|
||||
id: string;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
email: string;
|
||||
resetPasswordToken?: string | null;
|
||||
resetPasswordExpiration?: string | null;
|
||||
salt?: string | null;
|
||||
hash?: string | null;
|
||||
loginAttempts?: number | null;
|
||||
lockUntil?: string | null;
|
||||
password?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
*/
|
||||
export interface PayloadLockedDocument {
|
||||
id: string;
|
||||
document?:
|
||||
| ({
|
||||
relationTo: 'field-paths';
|
||||
value: string | FieldPath;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences".
|
||||
*/
|
||||
export interface PayloadPreference {
|
||||
id: string;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
};
|
||||
key?: string | null;
|
||||
value?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations".
|
||||
*/
|
||||
export interface PayloadMigration {
|
||||
id: string;
|
||||
name?: string | null;
|
||||
batch?: number | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "field-paths_select".
|
||||
*/
|
||||
export interface FieldPathsSelect<T extends boolean = true> {
|
||||
topLevelNamedField?: T;
|
||||
array?:
|
||||
| T
|
||||
| {
|
||||
fieldWithinArray?: T;
|
||||
nestedArray?:
|
||||
| T
|
||||
| {
|
||||
fieldWithinNestedArray?: T;
|
||||
id?: T;
|
||||
};
|
||||
fieldWithinRowWithinArray?: T;
|
||||
id?: T;
|
||||
};
|
||||
fieldWithinRow?: T;
|
||||
fieldWithinUnnamedTab?: T;
|
||||
fieldWithinNestedUnnamedTab?: T;
|
||||
namedTab?:
|
||||
| T
|
||||
| {
|
||||
fieldWithinNamedTab?: T;
|
||||
};
|
||||
topLevelNamedField_beforeValidate_FieldPaths?: T;
|
||||
topLevelNamedField_beforeChange_FieldPaths?: T;
|
||||
topLevelNamedField_afterRead_FieldPaths?: T;
|
||||
topLevelNamedField_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinArray_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinArray_beforeChange_FieldPaths?: T;
|
||||
fieldWithinArray_afterRead_FieldPaths?: T;
|
||||
fieldWithinArray_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinNestedArray_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinNestedArray_beforeChange_FieldPaths?: T;
|
||||
fieldWithinNestedArray_afterRead_FieldPaths?: T;
|
||||
fieldWithinNestedArray_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinRowWithinArray_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinRowWithinArray_beforeChange_FieldPaths?: T;
|
||||
fieldWithinRowWithinArray_afterRead_FieldPaths?: T;
|
||||
fieldWithinRowWithinArray_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinRow_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinRow_beforeChange_FieldPaths?: T;
|
||||
fieldWithinRow_afterRead_FieldPaths?: T;
|
||||
fieldWithinRow_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinUnnamedTab_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinUnnamedTab_beforeChange_FieldPaths?: T;
|
||||
fieldWithinUnnamedTab_afterRead_FieldPaths?: T;
|
||||
fieldWithinUnnamedTab_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinNestedUnnamedTab_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinNestedUnnamedTab_beforeChange_FieldPaths?: T;
|
||||
fieldWithinNestedUnnamedTab_afterRead_FieldPaths?: T;
|
||||
fieldWithinNestedUnnamedTab_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinNamedTab_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinNamedTab_beforeChange_FieldPaths?: T;
|
||||
fieldWithinNamedTab_afterRead_FieldPaths?: T;
|
||||
fieldWithinNamedTab_beforeDuplicate_FieldPaths?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users_select".
|
||||
*/
|
||||
export interface UsersSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
email?: T;
|
||||
resetPasswordToken?: T;
|
||||
resetPasswordExpiration?: T;
|
||||
salt?: T;
|
||||
hash?: T;
|
||||
loginAttempts?: T;
|
||||
lockUntil?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents_select".
|
||||
*/
|
||||
export interface PayloadLockedDocumentsSelect<T extends boolean = true> {
|
||||
document?: T;
|
||||
globalSlug?: T;
|
||||
user?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences_select".
|
||||
*/
|
||||
export interface PayloadPreferencesSelect<T extends boolean = true> {
|
||||
user?: T;
|
||||
key?: T;
|
||||
value?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations_select".
|
||||
*/
|
||||
export interface PayloadMigrationsSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
batch?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "auth".
|
||||
*/
|
||||
export interface Auth {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
|
||||
declare module 'payload' {
|
||||
// @ts-ignore
|
||||
export interface GeneratedTypes extends Config {}
|
||||
}
|
||||
2
test/field-paths/shared.ts
Normal file
2
test/field-paths/shared.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export const beforeValidateSlug = 'before-validate'
|
||||
export const fieldPathsSlug = 'field-paths'
|
||||
13
test/field-paths/tsconfig.eslint.json
Normal file
13
test/field-paths/tsconfig.eslint.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
// extend your base config to share compilerOptions, etc
|
||||
//"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
// ensure that nobody can accidentally use this config for a build
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
// whatever paths you intend to lint
|
||||
"./**/*.ts",
|
||||
"./**/*.tsx"
|
||||
]
|
||||
}
|
||||
3
test/field-paths/tsconfig.json
Normal file
3
test/field-paths/tsconfig.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../tsconfig.json"
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import { BeforeValidateCollection } from './collections/BeforeValidate/index.js'
|
||||
import ChainingHooks from './collections/ChainingHooks/index.js'
|
||||
import ContextHooks from './collections/ContextHooks/index.js'
|
||||
import { DataHooks } from './collections/Data/index.js'
|
||||
import { FieldPaths } from './collections/FieldPaths/index.js'
|
||||
import Hooks, { hooksSlug } from './collections/Hook/index.js'
|
||||
import NestedAfterReadHooks from './collections/NestedAfterReadHooks/index.js'
|
||||
import Relations from './collections/Relations/index.js'
|
||||
@@ -39,7 +38,6 @@ export const HooksConfig: Promise<SanitizedConfig> = buildConfigWithDefaults({
|
||||
Relations,
|
||||
Users,
|
||||
DataHooks,
|
||||
FieldPaths,
|
||||
],
|
||||
globals: [DataHooksGlobal],
|
||||
endpoints: [
|
||||
|
||||
@@ -517,101 +517,6 @@ describe('Hooks', () => {
|
||||
|
||||
expect(doc.field_globalAndField).toStrictEqual(globalAndFieldString + globalAndFieldString)
|
||||
})
|
||||
|
||||
it('should pass correct field paths through field hooks', async () => {
|
||||
const formatExpectedFieldPaths = (
|
||||
fieldIdentifier: string,
|
||||
{
|
||||
path,
|
||||
schemaPath,
|
||||
}: {
|
||||
path: string[]
|
||||
schemaPath: string[]
|
||||
},
|
||||
) => ({
|
||||
[`${fieldIdentifier}_beforeValidate_FieldPaths`]: {
|
||||
path,
|
||||
schemaPath,
|
||||
},
|
||||
[`${fieldIdentifier}_beforeChange_FieldPaths`]: {
|
||||
path,
|
||||
schemaPath,
|
||||
},
|
||||
[`${fieldIdentifier}_afterRead_FieldPaths`]: {
|
||||
path,
|
||||
schemaPath,
|
||||
},
|
||||
[`${fieldIdentifier}_beforeDuplicate_FieldPaths`]: {
|
||||
path,
|
||||
schemaPath,
|
||||
},
|
||||
})
|
||||
|
||||
const originalDoc = await payload.create({
|
||||
collection: fieldPathsSlug,
|
||||
data: {
|
||||
topLevelNamedField: 'Test',
|
||||
array: [
|
||||
{
|
||||
fieldWithinArray: 'Test',
|
||||
nestedArray: [
|
||||
{
|
||||
fieldWithinNestedArray: 'Test',
|
||||
fieldWithinNestedRow: 'Test',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
fieldWithinRow: 'Test',
|
||||
fieldWithinUnnamedTab: 'Test',
|
||||
namedTab: {
|
||||
fieldWithinNamedTab: 'Test',
|
||||
},
|
||||
fieldWithinNestedUnnamedTab: 'Test',
|
||||
},
|
||||
})
|
||||
|
||||
// duplicate the doc to ensure that the beforeDuplicate hook is run
|
||||
const doc = await payload.duplicate({
|
||||
id: originalDoc.id,
|
||||
collection: fieldPathsSlug,
|
||||
})
|
||||
|
||||
expect(doc).toMatchObject({
|
||||
...formatExpectedFieldPaths('topLevelNamedField', {
|
||||
path: ['topLevelNamedField'],
|
||||
schemaPath: ['topLevelNamedField'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinArray', {
|
||||
path: ['array', '0', 'fieldWithinArray'],
|
||||
schemaPath: ['array', 'fieldWithinArray'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinNestedArray', {
|
||||
path: ['array', '0', 'nestedArray', '0', 'fieldWithinNestedArray'],
|
||||
schemaPath: ['array', 'nestedArray', 'fieldWithinNestedArray'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinRowWithinArray', {
|
||||
path: ['array', '0', 'fieldWithinRowWithinArray'],
|
||||
schemaPath: ['array', '_index-2', 'fieldWithinRowWithinArray'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinRow', {
|
||||
path: ['fieldWithinRow'],
|
||||
schemaPath: ['_index-2', 'fieldWithinRow'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinUnnamedTab', {
|
||||
path: ['fieldWithinUnnamedTab'],
|
||||
schemaPath: ['_index-3-0', 'fieldWithinUnnamedTab'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinNestedUnnamedTab', {
|
||||
path: ['fieldWithinNestedUnnamedTab'],
|
||||
schemaPath: ['_index-3-0-1-0', 'fieldWithinNestedUnnamedTab'],
|
||||
}),
|
||||
...formatExpectedFieldPaths('fieldWithinNamedTab', {
|
||||
path: ['namedTab', 'fieldWithinNamedTab'],
|
||||
schemaPath: ['_index-3', 'namedTab', 'fieldWithinNamedTab'],
|
||||
}),
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('config level after error hook', () => {
|
||||
|
||||
@@ -22,7 +22,6 @@ export interface Config {
|
||||
relations: Relation;
|
||||
'hooks-users': HooksUser;
|
||||
'data-hooks': DataHook;
|
||||
'field-paths': FieldPath;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
@@ -40,7 +39,6 @@ export interface Config {
|
||||
relations: RelationsSelect<false> | RelationsSelect<true>;
|
||||
'hooks-users': HooksUsersSelect<false> | HooksUsersSelect<true>;
|
||||
'data-hooks': DataHooksSelect<false> | DataHooksSelect<true>;
|
||||
'field-paths': FieldPathsSelect<false> | FieldPathsSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
@@ -238,286 +236,6 @@ export interface DataHook {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "field-paths".
|
||||
*/
|
||||
export interface FieldPath {
|
||||
id: string;
|
||||
topLevelNamedField?: string | null;
|
||||
array?:
|
||||
| {
|
||||
fieldWithinArray?: string | null;
|
||||
nestedArray?:
|
||||
| {
|
||||
fieldWithinNestedArray?: string | null;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
fieldWithinRow?: string | null;
|
||||
fieldWithinUnnamedTab?: string | null;
|
||||
fieldWithinNestedUnnamedTab?: string | null;
|
||||
namedTab?: {
|
||||
fieldWithinNamedTab?: string | null;
|
||||
};
|
||||
topLevelNamedField_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
topLevelNamedField_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
topLevelNamedField_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
topLevelNamedField_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinArray_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinArray_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinArray_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinArray_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedArray_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedArray_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedArray_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedArray_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRow_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRow_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRow_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinRow_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinUnnamedTab_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinUnnamedTab_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinUnnamedTab_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinUnnamedTab_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedUnnamedTab_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedUnnamedTab_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedUnnamedTab_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNestedUnnamedTab_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNamedTab_beforeValidate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNamedTab_beforeChange_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNamedTab_afterRead_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
fieldWithinNamedTab_beforeDuplicate_FieldPaths?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
@@ -568,10 +286,6 @@ export interface PayloadLockedDocument {
|
||||
| ({
|
||||
relationTo: 'data-hooks';
|
||||
value: string | DataHook;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'field-paths';
|
||||
value: string | FieldPath;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
@@ -756,63 +470,6 @@ export interface DataHooksSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "field-paths_select".
|
||||
*/
|
||||
export interface FieldPathsSelect<T extends boolean = true> {
|
||||
topLevelNamedField?: T;
|
||||
array?:
|
||||
| T
|
||||
| {
|
||||
fieldWithinArray?: T;
|
||||
nestedArray?:
|
||||
| T
|
||||
| {
|
||||
fieldWithinNestedArray?: T;
|
||||
id?: T;
|
||||
};
|
||||
id?: T;
|
||||
};
|
||||
fieldWithinRow?: T;
|
||||
fieldWithinUnnamedTab?: T;
|
||||
fieldWithinNestedUnnamedTab?: T;
|
||||
namedTab?:
|
||||
| T
|
||||
| {
|
||||
fieldWithinNamedTab?: T;
|
||||
};
|
||||
topLevelNamedField_beforeValidate_FieldPaths?: T;
|
||||
topLevelNamedField_beforeChange_FieldPaths?: T;
|
||||
topLevelNamedField_afterRead_FieldPaths?: T;
|
||||
topLevelNamedField_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinArray_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinArray_beforeChange_FieldPaths?: T;
|
||||
fieldWithinArray_afterRead_FieldPaths?: T;
|
||||
fieldWithinArray_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinNestedArray_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinNestedArray_beforeChange_FieldPaths?: T;
|
||||
fieldWithinNestedArray_afterRead_FieldPaths?: T;
|
||||
fieldWithinNestedArray_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinRow_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinRow_beforeChange_FieldPaths?: T;
|
||||
fieldWithinRow_afterRead_FieldPaths?: T;
|
||||
fieldWithinRow_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinUnnamedTab_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinUnnamedTab_beforeChange_FieldPaths?: T;
|
||||
fieldWithinUnnamedTab_afterRead_FieldPaths?: T;
|
||||
fieldWithinUnnamedTab_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinNestedUnnamedTab_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinNestedUnnamedTab_beforeChange_FieldPaths?: T;
|
||||
fieldWithinNestedUnnamedTab_afterRead_FieldPaths?: T;
|
||||
fieldWithinNestedUnnamedTab_beforeDuplicate_FieldPaths?: T;
|
||||
fieldWithinNamedTab_beforeValidate_FieldPaths?: T;
|
||||
fieldWithinNamedTab_beforeChange_FieldPaths?: T;
|
||||
fieldWithinNamedTab_afterRead_FieldPaths?: T;
|
||||
fieldWithinNamedTab_beforeDuplicate_FieldPaths?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents_select".
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@payload-config": ["./test/versions/config.ts"],
|
||||
"@payload-config": ["./test/hooks/config.ts"],
|
||||
"@payloadcms/live-preview": ["./packages/live-preview/src"],
|
||||
"@payloadcms/live-preview-react": ["./packages/live-preview-react/src/index.ts"],
|
||||
"@payloadcms/live-preview-vue": ["./packages/live-preview-vue/src/index.ts"],
|
||||
|
||||
Reference in New Issue
Block a user