fix: disallow duplicate fieldNames to be used on the same level in the config (#4381)

This commit is contained in:
Jarrod Flesch
2023-12-11 16:52:24 -05:00
committed by GitHub
parent 548e78c598
commit a1d66b83e0
14 changed files with 758 additions and 279 deletions

View File

@@ -0,0 +1,11 @@
import APIError from './APIError'
class DuplicateFieldName extends APIError {
constructor(fieldName: string) {
super(
`A field with the name '${fieldName}' was found multiple times on the same level. Field names must be unique.`,
)
}
}
export default DuplicateFieldName

View File

@@ -2,6 +2,7 @@ export { default as errorHandler } from '../express/middleware/errorHandler'
export { default as APIError } from './APIError'
export { default as AuthenticationError } from './AuthenticationError'
export { default as DuplicateCollection } from './DuplicateCollection'
export { default as DuplicateFieldName } from './DuplicateFieldName'
export { default as DuplicateGlobal } from './DuplicateGlobal'
export { default as ErrorDeletingFile } from './ErrorDeletingFile'
export { default as FileUploadError } from './FileUploadError'

View File

@@ -2,7 +2,12 @@ import type { Config } from '../../config/types'
import type { Field } from './types'
import withCondition from '../../admin/components/forms/withCondition'
import { InvalidFieldName, InvalidFieldRelationship, MissingFieldType } from '../../errors'
import {
DuplicateFieldName,
InvalidFieldName,
InvalidFieldRelationship,
MissingFieldType,
} from '../../errors'
import { formatLabels, toWords } from '../../utilities/formatLabels'
import { baseBlockFields } from '../baseFields/baseBlockFields'
import { baseIDField } from '../baseFields/baseIDField'
@@ -11,6 +16,7 @@ import { fieldAffectsData, tabHasName } from './types'
type Args = {
config: Config
existingFieldNames?: Set<string>
fields: Field[]
/**
* If not null, will validate that upload and relationship fields do not relate to a collection that is not in this array.
@@ -19,7 +25,12 @@ type Args = {
validRelationships: null | string[]
}
export const sanitizeFields = ({ config, fields, validRelationships }: Args): Field[] => {
export const sanitizeFields = ({
config,
existingFieldNames = new Set(),
fields,
validRelationships,
}: Args): Field[] => {
if (!fields) return []
return fields.map((unsanitizedField) => {
@@ -100,6 +111,12 @@ export const sanitizeFields = ({ config, fields, validRelationships }: Args): Fi
}
if (fieldAffectsData(field)) {
if (existingFieldNames.has(field.name)) {
throw new DuplicateFieldName(field.name)
} else if (!['id', 'blockName'].includes(field.name)) {
existingFieldNames.add(field.name)
}
if (field.localized && !config.localization) delete field.localized
if (typeof field.validate === 'undefined') {
@@ -126,6 +143,7 @@ export const sanitizeFields = ({ config, fields, validRelationships }: Args): Fi
if ('fields' in field && field.fields) {
field.fields = sanitizeFields({
config,
existingFieldNames: fieldAffectsData(field) ? new Set() : existingFieldNames,
fields: field.fields,
validRelationships,
})
@@ -140,6 +158,7 @@ export const sanitizeFields = ({ config, fields, validRelationships }: Args): Fi
unsanitizedTab.fields = sanitizeFields({
config,
existingFieldNames: tabHasName(tab) ? new Set() : existingFieldNames,
fields: tab.fields,
validRelationships,
})
@@ -159,6 +178,7 @@ export const sanitizeFields = ({ config, fields, validRelationships }: Args): Fi
config,
fields: block.fields,
validRelationships,
existingFieldNames: new Set(),
})
return unsanitizedBlock

View File

@@ -1,33 +1,164 @@
/* tslint:disable */
/* eslint-disable */
/**
* This file was automatically generated by Payload CMS.
* 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 {
collections: {
posts: Post
'error-fields': ErrorField
uploads: Upload
users: User
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
globals: {}
}
export interface Post {
export interface ErrorField {
id: string
arrayField?: {
group23field: {
arrayField: {
group23field: {
arrayField: {
textField: string
id?: string
parentArray?:
| {
childArray: {
childArrayText: string
id?: string | null
}[]
id?: string | null
}[]
| null
home: {
tabText: string
text: string
array?:
| {
requiredArrayText: string
arrayText?: string | null
group: {
text: string
number: number
date: string
checkbox: boolean
}
id?: string
}[]
code: string
json:
| {
[k: string]: unknown
}
id?: string
| unknown[]
| string
| number
| boolean
| null
email: string
/**
* @minItems 2
* @maxItems 2
*/
point: [number, number]
radio: 'mint' | 'dark_gray'
relationship: string | User
richtext: {
[k: string]: unknown
}[]
select: 'mint' | 'dark_gray'
upload: string | Upload
text: string
textarea: string
id?: string | null
}[]
| null
}
tabText: string
text: string
array?:
| {
requiredArrayText: string
arrayText?: string | null
group: {
text: string
number: number
date: string
checkbox: boolean
}
code: string
json:
| {
[k: string]: unknown
}
| unknown[]
| string
| number
| boolean
| null
email: string
/**
* @minItems 2
* @maxItems 2
*/
point: [number, number]
radio: 'mint' | 'dark_gray'
relationship: string | User
richtext: {
[k: string]: unknown
}[]
select: 'mint' | 'dark_gray'
upload: string | Upload
text: string
textarea: string
id?: string | null
}[]
| null
layout?:
| {
tabText: string
text: string
array?:
| {
requiredArrayText: string
arrayText?: string | null
group: {
text: string
number: number
date: string
checkbox: boolean
}
code: string
json:
| {
[k: string]: unknown
}
| unknown[]
| string
| number
| boolean
| null
email: string
/**
* @minItems 2
* @maxItems 2
*/
point: [number, number]
radio: 'mint' | 'dark_gray'
relationship: string | User
richtext: {
[k: string]: unknown
}[]
select: 'mint' | 'dark_gray'
upload: string | Upload
text: string
textarea: string
id?: string | null
}[]
| null
id?: string | null
blockName?: string | null
blockType: 'block1'
}[]
| null
group: {
text: string
}
updatedAt: string
createdAt: string
}
@@ -35,12 +166,60 @@ export interface User {
id: string
updatedAt: string
createdAt: string
email?: string
resetPasswordToken?: string
resetPasswordExpiration?: string
salt?: string
hash?: string
loginAttempts?: number
lockUntil?: string
password?: string
email: string
resetPasswordToken?: string | null
resetPasswordExpiration?: string | null
salt?: string | null
hash?: string | null
loginAttempts?: number | null
lockUntil?: string | null
password: string | null
}
export interface Upload {
id: string
text?: string | null
media?: string | Upload | null
richText?:
| {
[k: string]: unknown
}[]
| null
updatedAt: string
createdAt: string
url?: string | null
filename?: string | null
mimeType?: string | null
filesize?: number | null
width?: number | null
height?: number | null
}
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
}
export interface PayloadMigration {
id: string
name?: string | null
batch?: number | null
updatedAt: string
createdAt: string
}
declare module 'payload' {
export interface GeneratedTypes extends Config {}
}

View File

@@ -8,7 +8,7 @@ import type {
RelationRestricted,
RelationTwo,
RelationWithTitle,
} from './config'
} from './payload-types'
import payload from '../../packages/payload/src'
import { mapAsync } from '../../packages/payload/src/utilities/mapAsync'
@@ -55,37 +55,37 @@ describe('fields - relationship', () => {
await clearAllDocs()
// Create docs to relate to
relationOneDoc = await payload.create({
relationOneDoc = (await payload.create({
collection: relationOneSlug,
data: {
name: 'relation',
},
})
})) as any
anotherRelationOneDoc = await payload.create({
anotherRelationOneDoc = (await payload.create({
collection: relationOneSlug,
data: {
name: 'relation',
},
})
})) as any
relationTwoDoc = await payload.create({
relationTwoDoc = (await payload.create({
collection: relationTwoSlug,
data: {
name: 'second-relation',
},
})
})) as any
// Create restricted doc
restrictedRelation = await payload.create({
restrictedRelation = (await payload.create({
collection: relationRestrictedSlug,
data: {
name: 'restricted',
},
})
})) as any
// Doc with useAsTitle
relationWithTitle = await payload.create({
relationWithTitle = (await payload.create({
collection: relationWithTitleSlug,
data: {
name: 'relation-title',
@@ -93,7 +93,7 @@ describe('fields - relationship', () => {
title: 'relation-title',
},
},
})
})) as any
// Doc with useAsTitle for word boundary test
await payload.create({
@@ -107,7 +107,7 @@ describe('fields - relationship', () => {
})
// Add restricted doc as relation
docWithExistingRelations = await payload.create({
docWithExistingRelations = (await payload.create({
collection: slug,
data: {
name: 'with-existing-relations',
@@ -116,7 +116,7 @@ describe('fields - relationship', () => {
relationshipWithTitle: relationWithTitle.id,
relationshipReadOnly: relationOneDoc.id,
},
})
})) as any
})
test('should create relationship', async () => {
@@ -279,18 +279,18 @@ describe('fields - relationship', () => {
})
test('should allow usage of relationTo in filterOptions', async () => {
const { id: include } = await payload.create({
const { id: include } = (await payload.create({
collection: relationOneSlug,
data: {
name: 'include',
},
})
const { id: exclude } = await payload.create({
})) as any
const { id: exclude } = (await payload.create({
collection: relationOneSlug,
data: {
name: 'exclude',
},
})
})) as any
await page.goto(url.create)

View File

@@ -1,180 +1,171 @@
/* 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 {}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "fields-relationship".
*/
export interface Config {
collections: {
'fields-relationship': FieldsRelationship
'relation-one': RelationOne
'relation-two': RelationTwo
'relation-restricted': RelationRestricted
'relation-with-title': RelationWithTitle
'relation-updated-externally': RelationUpdatedExternally
'collection-1': Collection1
'collection-2': Collection2
users: User
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
globals: {}
}
export interface FieldsRelationship {
id: string
relationship?: string | RelationOne
relationshipHasMany?: string[] | RelationOne[]
relationship?: (string | null) | RelationOne
relationshipHasMany?: (string | RelationOne)[] | null
relationshipMultiple?:
| {
value: string | RelationOne
| ({
relationTo: 'relation-one'
}
| {
value: string | RelationTwo
value: string | RelationOne
} | null)
| ({
relationTo: 'relation-two'
}
value: string | RelationTwo
} | null)
relationshipHasManyMultiple?:
| (
| {
value: string
relationTo: 'relation-one'
value: string | RelationOne
}
| {
value: string
relationTo: 'relation-two'
value: string | RelationTwo
}
)[]
| (
| {
value: RelationOne
relationTo: 'relation-one'
}
| {
value: RelationTwo
relationTo: 'relation-two'
}
)[]
relationshipRestricted?: string | RelationRestricted
relationshipWithTitle?: string | RelationWithTitle
relationshipFiltered?: string | RelationOne
| null
relationshipRestricted?: (string | null) | RelationRestricted
relationshipWithTitle?: (string | null) | RelationWithTitle
relationshipFiltered?: (string | null) | RelationOne
relationshipFilteredAsync?: (string | null) | RelationOne
relationshipManyFiltered?:
| (
| {
value: string
relationTo: 'relation-with-title'
value: string | RelationWithTitle
}
| {
value: string
relationTo: 'relation-one'
value: string | RelationOne
}
)[]
| (
| {
value: RelationWithTitle
relationTo: 'relation-with-title'
}
| {
value: RelationOne
relationTo: 'relation-one'
}
)[]
filter?: string
createdAt: string
| null
filter?: string | null
relationshipReadOnly?: (string | null) | RelationOne
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "relation-one".
*/
export interface RelationOne {
id: string
name?: string
createdAt: string
name?: string | null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "relation-two".
*/
export interface RelationTwo {
id: string
name?: string
createdAt: string
name?: string | null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "relation-restricted".
*/
export interface RelationRestricted {
id: string
name?: string
createdAt: string
name?: string | null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "relation-with-title".
*/
export interface RelationWithTitle {
id: string
name?: string
createdAt: string
name?: string | null
meta?: {
title?: string | null
}
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "relation-updated-externally".
*/
export interface RelationUpdatedExternally {
id: string
relationPrePopulate?: string | Collection1
relationHasMany?: string[] | Collection1[]
relationPrePopulate?: (string | null) | Collection1
relationHasMany?: (string | Collection1)[] | null
relationToManyHasMany?:
| (
| {
value: string
relationTo: 'collection-1'
value: string | Collection1
}
| {
value: string
relationTo: 'collection-2'
value: string | Collection2
}
)[]
| (
| {
value: Collection1
relationTo: 'collection-1'
}
| {
value: Collection2
relationTo: 'collection-2'
}
)[]
createdAt: string
| null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "collection-1".
*/
export interface Collection1 {
id: string
name?: string
createdAt: string
name?: string | null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "collection-2".
*/
export interface Collection2 {
id: string
name?: string
createdAt: string
name?: string | null
updatedAt: string
createdAt: string
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users".
*/
export interface User {
id: string
email?: string
resetPasswordToken?: string
resetPasswordExpiration?: string
loginAttempts?: number
lockUntil?: string
createdAt: 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
}
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
}
export interface PayloadMigration {
id: string
name?: string | null
batch?: number | null
updatedAt: string
createdAt: string
}
declare module 'payload' {
export interface GeneratedTypes extends Config {}
}

View File

@@ -55,8 +55,7 @@ const CollapsibleFields: CollectionConfig = {
type: 'text',
},
{
// TODO: change group name, to not be a duplicate of the above collapsible
name: 'group',
name: 'group2',
type: 'group',
fields: [
{

View File

@@ -1,11 +1,11 @@
import type { Block } from '../../../../packages/payload/src/fields/config/types'
import type { ArrayField, Block } from '../../../../packages/payload/src/fields/config/types'
import { lexicalEditor } from '../../../../packages/richtext-lexical/src'
import { textFieldsSlug } from '../Text/shared'
export const BlockColumns: any = {
export const BlockColumns = ({ name }: { name: string }): ArrayField => ({
type: 'array',
name: 'columns',
name,
interfaceName: 'BlockColumns',
admin: {
initCollapsed: true,
@@ -16,7 +16,7 @@ export const BlockColumns: any = {
type: 'text',
},
],
}
})
export const ConditionalLayoutBlock: Block = {
fields: [
{
@@ -28,7 +28,7 @@ export const ConditionalLayoutBlock: Block = {
required: true,
},
{
...BlockColumns,
...BlockColumns({ name: 'columns' }),
admin: {
condition: (data, siblingData) => {
return ['1'].includes(siblingData.layout)
@@ -38,7 +38,7 @@ export const ConditionalLayoutBlock: Block = {
maxRows: 1,
},
{
...BlockColumns,
...BlockColumns({ name: 'columns2' }),
admin: {
condition: (data, siblingData) => {
return ['2'].includes(siblingData.layout)
@@ -48,7 +48,7 @@ export const ConditionalLayoutBlock: Block = {
maxRows: 2,
},
{
...BlockColumns,
...BlockColumns({ name: 'columns3' }),
admin: {
condition: (data, siblingData) => {
return ['3'].includes(siblingData.layout)

View File

@@ -270,6 +270,8 @@ export function generateLexicalRichText() {
text: 'text in conditionalLayout block',
},
],
columns2: null,
columns3: null,
},
}, // Do not remove this blocks node. It ensures that validation passes when it's created
{

View File

@@ -29,6 +29,7 @@ import {
import { tabsDoc } from './collections/Tabs/shared'
import { defaultText } from './collections/Text/shared'
import { clearAndSeedEverything } from './seed'
import { GroupField } from './payload-types'
import {
arrayFieldsSlug,
blockFieldsSlug,
@@ -587,10 +588,10 @@ describe('Fields', () => {
})
it('should create with ids and nested ids', async () => {
const docWithIDs = await payload.create({
const docWithIDs = (await payload.create({
collection: groupFieldsSlug,
data: groupDoc,
})
})) as Partial<GroupField>
expect(docWithIDs.group.subGroup.arrayWithinGroup[0].id).toBeDefined()
})

View File

@@ -658,45 +658,15 @@ describe('lexical', () => {
const selectFieldMenu = selectField.locator('.rs__menu').first()
await selectFieldMenu.locator('.rs__option').nth(1).click() // Select "2" (2 columns / array fields)
await conditionalArrayBlock.getByText('Add Column').click()
await conditionalArrayBlock.locator('.btn__label:has-text("Add Columns2")').first().click()
await conditionalArrayBlock.locator('.btn__label:has-text("Add Columns2")').first().click()
await conditionalArrayBlock
.locator('.array-field__draggable-rows')
.first()
.locator('.array-field__row')
.nth(1)
.locator('.input-wrapper input')
.first()
.fill('second text')
.locator('.array-field__draggable-rows > div:nth-child(2) .input-wrapper input')
.fill('second input')
await saveDocAndAssert(page)
await selectField.click()
await selectFieldMenu.locator('.rs__option').nth(0).click() // Select "1" (1 columns / array fields)
// Remove 2nd column
await conditionalArrayBlock
.locator('.array-field__draggable-rows')
.first()
.locator('.array-field__row')
.nth(1)
.locator('.array-actions__button')
.first()
.click()
await conditionalArrayBlock
.locator('.array-field__draggable-rows')
.first()
.locator('.array-field__row')
.nth(1)
.locator('.popup__content')
.first()
.locator('Button')
.nth(1)
.click()
await saveDocAndAssert(page)
// This can be triggered if the 2nd row's data is not actually deleted (<= this is the bug), as the validation expects just one row
await expect(page.locator('.Toastify')).not.toContainText('Please correct invalid fields.')
})
})

View File

@@ -36,7 +36,9 @@ export interface Config {
'payload-preferences': PayloadPreference
'payload-migrations': PayloadMigration
}
globals: {}
globals: {
tabsWithRichText: TabsWithRichText
}
}
export interface LexicalField {
id: string
@@ -169,6 +171,12 @@ export interface ArrayField {
title?: string | null
items: {
text: string
subArray?:
| {
text?: string | null
id?: string | null
}[]
| null
id?: string | null
}[]
collapsedArray?:
@@ -447,6 +455,12 @@ export interface CollapsibleField {
}
}
someText?: string | null
group2?: {
textWithinGroup?: string | null
subGroup?: {
textWithinSubGroup?: string | null
}
}
functionTitleField?: string | null
componentTitleField?: string | null
nestedTitle?: string | null
@@ -838,6 +852,15 @@ export interface TabsField {
}
textInRow: string
numberInRow: number
json?:
| {
[k: string]: unknown
}
| unknown[]
| string
| number
| boolean
| null
tab: {
array: {
text: string
@@ -943,6 +966,45 @@ export interface PayloadMigration {
updatedAt: string
createdAt: string
}
export interface TabsWithRichText {
id: string
tab1: {
rt1?: {
root: {
children: {
type: string
version: number
[k: string]: unknown
}[]
direction: ('ltr' | 'rtl') | null
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''
indent: number
type: string
version: number
}
[k: string]: unknown
} | null
}
tab2: {
rt2?: {
root: {
children: {
type: string
version: number
[k: string]: unknown
}[]
direction: ('ltr' | 'rtl') | null
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''
indent: number
type: string
version: number
}
[k: string]: unknown
} | null
}
updatedAt?: string | null
createdAt?: string | null
}
declare module 'payload' {
export interface GeneratedTypes extends Config {}

View File

@@ -91,7 +91,7 @@ export default buildConfigWithDefaults({
fields: [
{
type: 'array',
name: 'meta',
name: 'metaArray',
interfaceName: 'SharedMetaArray',
fields: [
{
@@ -106,7 +106,7 @@ export default buildConfigWithDefaults({
},
{
type: 'group',
name: 'meta',
name: 'metaGroup',
interfaceName: 'SharedMeta',
fields: [
{

View File

@@ -452,7 +452,8 @@ type Collection1DeleteDocAccess {
type Collection2 {
id: String
meta: SharedMeta
metaArray: [SharedMetaArray!]
metaGroup: SharedMeta
nestedGroup: Collection2_NestedGroup
updatedAt: DateTime
createdAt: DateTime
@@ -482,9 +483,11 @@ type Collection2s {
}
input Collection2_where {
meta__title: Collection2_meta__title_operator
meta__description: Collection2_meta__description_operator
meta__id: Collection2_meta__id_operator
metaArray__title: Collection2_metaArray__title_operator
metaArray__description: Collection2_metaArray__description_operator
metaArray__id: Collection2_metaArray__id_operator
metaGroup__title: Collection2_metaGroup__title_operator
metaGroup__description: Collection2_metaGroup__description_operator
nestedGroup__meta__title: Collection2_nestedGroup__meta__title_operator
nestedGroup__meta__description: Collection2_nestedGroup__meta__description_operator
updatedAt: Collection2_updatedAt_operator
@@ -494,7 +497,7 @@ input Collection2_where {
OR: [Collection2_where_or]
}
input Collection2_meta__title_operator {
input Collection2_metaArray__title_operator {
equals: String
not_equals: String
like: String
@@ -505,7 +508,7 @@ input Collection2_meta__title_operator {
exists: Boolean
}
input Collection2_meta__description_operator {
input Collection2_metaArray__description_operator {
equals: String
not_equals: String
like: String
@@ -516,7 +519,29 @@ input Collection2_meta__description_operator {
exists: Boolean
}
input Collection2_meta__id_operator {
input Collection2_metaArray__id_operator {
equals: String
not_equals: String
like: String
contains: String
in: [String]
not_in: [String]
all: [String]
exists: Boolean
}
input Collection2_metaGroup__title_operator {
equals: String
not_equals: String
like: String
contains: String
in: [String]
not_in: [String]
all: [String]
exists: Boolean
}
input Collection2_metaGroup__description_operator {
equals: String
not_equals: String
like: String
@@ -583,9 +608,11 @@ input Collection2_id_operator {
}
input Collection2_where_and {
meta__title: Collection2_meta__title_operator
meta__description: Collection2_meta__description_operator
meta__id: Collection2_meta__id_operator
metaArray__title: Collection2_metaArray__title_operator
metaArray__description: Collection2_metaArray__description_operator
metaArray__id: Collection2_metaArray__id_operator
metaGroup__title: Collection2_metaGroup__title_operator
metaGroup__description: Collection2_metaGroup__description_operator
nestedGroup__meta__title: Collection2_nestedGroup__meta__title_operator
nestedGroup__meta__description: Collection2_nestedGroup__meta__description_operator
updatedAt: Collection2_updatedAt_operator
@@ -596,9 +623,11 @@ input Collection2_where_and {
}
input Collection2_where_or {
meta__title: Collection2_meta__title_operator
meta__description: Collection2_meta__description_operator
meta__id: Collection2_meta__id_operator
metaArray__title: Collection2_metaArray__title_operator
metaArray__description: Collection2_metaArray__description_operator
metaArray__id: Collection2_metaArray__id_operator
metaGroup__title: Collection2_metaGroup__title_operator
metaGroup__description: Collection2_metaGroup__description_operator
nestedGroup__meta__title: Collection2_nestedGroup__meta__title_operator
nestedGroup__meta__description: Collection2_nestedGroup__meta__description_operator
updatedAt: Collection2_updatedAt_operator
@@ -617,84 +646,184 @@ type collection2DocAccess {
}
type Collection2DocAccessFields {
meta: Collection2DocAccessFields_meta
metaArray: Collection2DocAccessFields_metaArray
metaGroup: Collection2DocAccessFields_metaGroup
nestedGroup: Collection2DocAccessFields_nestedGroup
updatedAt: Collection2DocAccessFields_updatedAt
createdAt: Collection2DocAccessFields_createdAt
}
type Collection2DocAccessFields_meta {
create: Collection2DocAccessFields_meta_Create
read: Collection2DocAccessFields_meta_Read
update: Collection2DocAccessFields_meta_Update
delete: Collection2DocAccessFields_meta_Delete
fields: Collection2DocAccessFields_meta_Fields
type Collection2DocAccessFields_metaArray {
create: Collection2DocAccessFields_metaArray_Create
read: Collection2DocAccessFields_metaArray_Read
update: Collection2DocAccessFields_metaArray_Update
delete: Collection2DocAccessFields_metaArray_Delete
fields: Collection2DocAccessFields_metaArray_Fields
}
type Collection2DocAccessFields_meta_Create {
type Collection2DocAccessFields_metaArray_Create {
permission: Boolean!
}
type Collection2DocAccessFields_meta_Read {
type Collection2DocAccessFields_metaArray_Read {
permission: Boolean!
}
type Collection2DocAccessFields_meta_Update {
type Collection2DocAccessFields_metaArray_Update {
permission: Boolean!
}
type Collection2DocAccessFields_meta_Delete {
type Collection2DocAccessFields_metaArray_Delete {
permission: Boolean!
}
type Collection2DocAccessFields_meta_Fields {
title: Collection2DocAccessFields_meta_title
description: Collection2DocAccessFields_meta_description
type Collection2DocAccessFields_metaArray_Fields {
title: Collection2DocAccessFields_metaArray_title
description: Collection2DocAccessFields_metaArray_description
id: Collection2DocAccessFields_metaArray_id
}
type Collection2DocAccessFields_meta_title {
create: Collection2DocAccessFields_meta_title_Create
read: Collection2DocAccessFields_meta_title_Read
update: Collection2DocAccessFields_meta_title_Update
delete: Collection2DocAccessFields_meta_title_Delete
type Collection2DocAccessFields_metaArray_title {
create: Collection2DocAccessFields_metaArray_title_Create
read: Collection2DocAccessFields_metaArray_title_Read
update: Collection2DocAccessFields_metaArray_title_Update
delete: Collection2DocAccessFields_metaArray_title_Delete
}
type Collection2DocAccessFields_meta_title_Create {
type Collection2DocAccessFields_metaArray_title_Create {
permission: Boolean!
}
type Collection2DocAccessFields_meta_title_Read {
type Collection2DocAccessFields_metaArray_title_Read {
permission: Boolean!
}
type Collection2DocAccessFields_meta_title_Update {
type Collection2DocAccessFields_metaArray_title_Update {
permission: Boolean!
}
type Collection2DocAccessFields_meta_title_Delete {
type Collection2DocAccessFields_metaArray_title_Delete {
permission: Boolean!
}
type Collection2DocAccessFields_meta_description {
create: Collection2DocAccessFields_meta_description_Create
read: Collection2DocAccessFields_meta_description_Read
update: Collection2DocAccessFields_meta_description_Update
delete: Collection2DocAccessFields_meta_description_Delete
type Collection2DocAccessFields_metaArray_description {
create: Collection2DocAccessFields_metaArray_description_Create
read: Collection2DocAccessFields_metaArray_description_Read
update: Collection2DocAccessFields_metaArray_description_Update
delete: Collection2DocAccessFields_metaArray_description_Delete
}
type Collection2DocAccessFields_meta_description_Create {
type Collection2DocAccessFields_metaArray_description_Create {
permission: Boolean!
}
type Collection2DocAccessFields_meta_description_Read {
type Collection2DocAccessFields_metaArray_description_Read {
permission: Boolean!
}
type Collection2DocAccessFields_meta_description_Update {
type Collection2DocAccessFields_metaArray_description_Update {
permission: Boolean!
}
type Collection2DocAccessFields_meta_description_Delete {
type Collection2DocAccessFields_metaArray_description_Delete {
permission: Boolean!
}
type Collection2DocAccessFields_metaArray_id {
create: Collection2DocAccessFields_metaArray_id_Create
read: Collection2DocAccessFields_metaArray_id_Read
update: Collection2DocAccessFields_metaArray_id_Update
delete: Collection2DocAccessFields_metaArray_id_Delete
}
type Collection2DocAccessFields_metaArray_id_Create {
permission: Boolean!
}
type Collection2DocAccessFields_metaArray_id_Read {
permission: Boolean!
}
type Collection2DocAccessFields_metaArray_id_Update {
permission: Boolean!
}
type Collection2DocAccessFields_metaArray_id_Delete {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup {
create: Collection2DocAccessFields_metaGroup_Create
read: Collection2DocAccessFields_metaGroup_Read
update: Collection2DocAccessFields_metaGroup_Update
delete: Collection2DocAccessFields_metaGroup_Delete
fields: Collection2DocAccessFields_metaGroup_Fields
}
type Collection2DocAccessFields_metaGroup_Create {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_Read {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_Update {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_Delete {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_Fields {
title: Collection2DocAccessFields_metaGroup_title
description: Collection2DocAccessFields_metaGroup_description
}
type Collection2DocAccessFields_metaGroup_title {
create: Collection2DocAccessFields_metaGroup_title_Create
read: Collection2DocAccessFields_metaGroup_title_Read
update: Collection2DocAccessFields_metaGroup_title_Update
delete: Collection2DocAccessFields_metaGroup_title_Delete
}
type Collection2DocAccessFields_metaGroup_title_Create {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_title_Read {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_title_Update {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_title_Delete {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_description {
create: Collection2DocAccessFields_metaGroup_description_Create
read: Collection2DocAccessFields_metaGroup_description_Read
update: Collection2DocAccessFields_metaGroup_description_Update
delete: Collection2DocAccessFields_metaGroup_description_Delete
}
type Collection2DocAccessFields_metaGroup_description_Create {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_description_Read {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_description_Update {
permission: Boolean!
}
type Collection2DocAccessFields_metaGroup_description_Delete {
permission: Boolean!
}
@@ -1664,84 +1793,184 @@ type collection2Access {
}
type Collection2Fields {
meta: Collection2Fields_meta
metaArray: Collection2Fields_metaArray
metaGroup: Collection2Fields_metaGroup
nestedGroup: Collection2Fields_nestedGroup
updatedAt: Collection2Fields_updatedAt
createdAt: Collection2Fields_createdAt
}
type Collection2Fields_meta {
create: Collection2Fields_meta_Create
read: Collection2Fields_meta_Read
update: Collection2Fields_meta_Update
delete: Collection2Fields_meta_Delete
fields: Collection2Fields_meta_Fields
type Collection2Fields_metaArray {
create: Collection2Fields_metaArray_Create
read: Collection2Fields_metaArray_Read
update: Collection2Fields_metaArray_Update
delete: Collection2Fields_metaArray_Delete
fields: Collection2Fields_metaArray_Fields
}
type Collection2Fields_meta_Create {
type Collection2Fields_metaArray_Create {
permission: Boolean!
}
type Collection2Fields_meta_Read {
type Collection2Fields_metaArray_Read {
permission: Boolean!
}
type Collection2Fields_meta_Update {
type Collection2Fields_metaArray_Update {
permission: Boolean!
}
type Collection2Fields_meta_Delete {
type Collection2Fields_metaArray_Delete {
permission: Boolean!
}
type Collection2Fields_meta_Fields {
title: Collection2Fields_meta_title
description: Collection2Fields_meta_description
type Collection2Fields_metaArray_Fields {
title: Collection2Fields_metaArray_title
description: Collection2Fields_metaArray_description
id: Collection2Fields_metaArray_id
}
type Collection2Fields_meta_title {
create: Collection2Fields_meta_title_Create
read: Collection2Fields_meta_title_Read
update: Collection2Fields_meta_title_Update
delete: Collection2Fields_meta_title_Delete
type Collection2Fields_metaArray_title {
create: Collection2Fields_metaArray_title_Create
read: Collection2Fields_metaArray_title_Read
update: Collection2Fields_metaArray_title_Update
delete: Collection2Fields_metaArray_title_Delete
}
type Collection2Fields_meta_title_Create {
type Collection2Fields_metaArray_title_Create {
permission: Boolean!
}
type Collection2Fields_meta_title_Read {
type Collection2Fields_metaArray_title_Read {
permission: Boolean!
}
type Collection2Fields_meta_title_Update {
type Collection2Fields_metaArray_title_Update {
permission: Boolean!
}
type Collection2Fields_meta_title_Delete {
type Collection2Fields_metaArray_title_Delete {
permission: Boolean!
}
type Collection2Fields_meta_description {
create: Collection2Fields_meta_description_Create
read: Collection2Fields_meta_description_Read
update: Collection2Fields_meta_description_Update
delete: Collection2Fields_meta_description_Delete
type Collection2Fields_metaArray_description {
create: Collection2Fields_metaArray_description_Create
read: Collection2Fields_metaArray_description_Read
update: Collection2Fields_metaArray_description_Update
delete: Collection2Fields_metaArray_description_Delete
}
type Collection2Fields_meta_description_Create {
type Collection2Fields_metaArray_description_Create {
permission: Boolean!
}
type Collection2Fields_meta_description_Read {
type Collection2Fields_metaArray_description_Read {
permission: Boolean!
}
type Collection2Fields_meta_description_Update {
type Collection2Fields_metaArray_description_Update {
permission: Boolean!
}
type Collection2Fields_meta_description_Delete {
type Collection2Fields_metaArray_description_Delete {
permission: Boolean!
}
type Collection2Fields_metaArray_id {
create: Collection2Fields_metaArray_id_Create
read: Collection2Fields_metaArray_id_Read
update: Collection2Fields_metaArray_id_Update
delete: Collection2Fields_metaArray_id_Delete
}
type Collection2Fields_metaArray_id_Create {
permission: Boolean!
}
type Collection2Fields_metaArray_id_Read {
permission: Boolean!
}
type Collection2Fields_metaArray_id_Update {
permission: Boolean!
}
type Collection2Fields_metaArray_id_Delete {
permission: Boolean!
}
type Collection2Fields_metaGroup {
create: Collection2Fields_metaGroup_Create
read: Collection2Fields_metaGroup_Read
update: Collection2Fields_metaGroup_Update
delete: Collection2Fields_metaGroup_Delete
fields: Collection2Fields_metaGroup_Fields
}
type Collection2Fields_metaGroup_Create {
permission: Boolean!
}
type Collection2Fields_metaGroup_Read {
permission: Boolean!
}
type Collection2Fields_metaGroup_Update {
permission: Boolean!
}
type Collection2Fields_metaGroup_Delete {
permission: Boolean!
}
type Collection2Fields_metaGroup_Fields {
title: Collection2Fields_metaGroup_title
description: Collection2Fields_metaGroup_description
}
type Collection2Fields_metaGroup_title {
create: Collection2Fields_metaGroup_title_Create
read: Collection2Fields_metaGroup_title_Read
update: Collection2Fields_metaGroup_title_Update
delete: Collection2Fields_metaGroup_title_Delete
}
type Collection2Fields_metaGroup_title_Create {
permission: Boolean!
}
type Collection2Fields_metaGroup_title_Read {
permission: Boolean!
}
type Collection2Fields_metaGroup_title_Update {
permission: Boolean!
}
type Collection2Fields_metaGroup_title_Delete {
permission: Boolean!
}
type Collection2Fields_metaGroup_description {
create: Collection2Fields_metaGroup_description_Create
read: Collection2Fields_metaGroup_description_Read
update: Collection2Fields_metaGroup_description_Update
delete: Collection2Fields_metaGroup_description_Delete
}
type Collection2Fields_metaGroup_description_Create {
permission: Boolean!
}
type Collection2Fields_metaGroup_description_Read {
permission: Boolean!
}
type Collection2Fields_metaGroup_description_Update {
permission: Boolean!
}
type Collection2Fields_metaGroup_description_Delete {
permission: Boolean!
}
@@ -2251,13 +2480,20 @@ input mutationCollection1Update_MetaInput {
}
input mutationCollection2Input {
meta: mutationCollection2_MetaInput
metaArray: [mutationCollection2_MetaArrayInput]
metaGroup: mutationCollection2_MetaGroupInput
nestedGroup: mutationCollection2_NestedGroupInput
updatedAt: String
createdAt: String
}
input mutationCollection2_MetaInput {
input mutationCollection2_MetaArrayInput {
title: String
description: String
id: String
}
input mutationCollection2_MetaGroupInput {
title: String
description: String
}
@@ -2272,13 +2508,20 @@ input mutationCollection2_NestedGroup_MetaInput {
}
input mutationCollection2UpdateInput {
meta: mutationCollection2Update_MetaInput
metaArray: [mutationCollection2Update_MetaArrayInput]
metaGroup: mutationCollection2Update_MetaGroupInput
nestedGroup: mutationCollection2Update_NestedGroupInput
updatedAt: String
createdAt: String
}
input mutationCollection2Update_MetaInput {
input mutationCollection2Update_MetaArrayInput {
title: String
description: String
id: String
}
input mutationCollection2Update_MetaGroupInput {
title: String
description: String
}