diff --git a/packages/payload/src/errors/DuplicateFieldName.ts b/packages/payload/src/errors/DuplicateFieldName.ts new file mode 100644 index 0000000000..b71d93abf0 --- /dev/null +++ b/packages/payload/src/errors/DuplicateFieldName.ts @@ -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 diff --git a/packages/payload/src/errors/index.ts b/packages/payload/src/errors/index.ts index 3215d38318..023f074a94 100644 --- a/packages/payload/src/errors/index.ts +++ b/packages/payload/src/errors/index.ts @@ -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' diff --git a/packages/payload/src/fields/config/sanitize.ts b/packages/payload/src/fields/config/sanitize.ts index 3b8e7fdc12..92d4bdd972 100644 --- a/packages/payload/src/fields/config/sanitize.ts +++ b/packages/payload/src/fields/config/sanitize.ts @@ -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 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 diff --git a/test/field-error-states/payload-types.ts b/test/field-error-states/payload-types.ts index 3b8a40897e..ac77db3622 100644 --- a/test/field-error-states/payload-types.ts +++ b/test/field-error-states/payload-types.ts @@ -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 + } + 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 + } + 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 + } + | 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' }[] - } - id?: string - }[] + | 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 {} } diff --git a/test/fields-relationship/e2e.spec.ts b/test/fields-relationship/e2e.spec.ts index 74f6830058..2817f2a20a 100644 --- a/test/fields-relationship/e2e.spec.ts +++ b/test/fields-relationship/e2e.spec.ts @@ -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) diff --git a/test/fields-relationship/payload-types.ts b/test/fields-relationship/payload-types.ts index 02d26789bf..7fe51f10b7 100644 --- a/test/fields-relationship/payload-types.ts +++ b/test/fields-relationship/payload-types.ts @@ -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 - relationTo: 'relation-two' - } - )[] - | ( - | { - value: RelationOne relationTo: 'relation-one' + value: string | RelationOne } | { - value: RelationTwo relationTo: 'relation-two' + value: string | RelationTwo } )[] - 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 - relationTo: 'relation-one' - } - )[] - | ( - | { - value: RelationWithTitle relationTo: 'relation-with-title' + value: string | RelationWithTitle } | { - value: RelationOne relationTo: 'relation-one' + value: string | RelationOne } )[] - 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 - relationTo: 'collection-2' - } - )[] - | ( - | { - value: Collection1 relationTo: 'collection-1' + value: string | Collection1 } | { - value: Collection2 relationTo: 'collection-2' + value: string | Collection2 } )[] - 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 + 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 {} } diff --git a/test/fields/collections/Collapsible/index.ts b/test/fields/collections/Collapsible/index.ts index 3f565f9398..1d0a2a346f 100644 --- a/test/fields/collections/Collapsible/index.ts +++ b/test/fields/collections/Collapsible/index.ts @@ -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: [ { diff --git a/test/fields/collections/Lexical/blocks.ts b/test/fields/collections/Lexical/blocks.ts index 150006e61e..c4851d9c5b 100644 --- a/test/fields/collections/Lexical/blocks.ts +++ b/test/fields/collections/Lexical/blocks.ts @@ -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) diff --git a/test/fields/collections/Lexical/generateLexicalRichText.ts b/test/fields/collections/Lexical/generateLexicalRichText.ts index b38d2fd61b..2ec4bac0f4 100644 --- a/test/fields/collections/Lexical/generateLexicalRichText.ts +++ b/test/fields/collections/Lexical/generateLexicalRichText.ts @@ -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 { diff --git a/test/fields/int.spec.ts b/test/fields/int.spec.ts index 03ecbdedd0..cdde2aae84 100644 --- a/test/fields/int.spec.ts +++ b/test/fields/int.spec.ts @@ -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 expect(docWithIDs.group.subGroup.arrayWithinGroup[0].id).toBeDefined() }) diff --git a/test/fields/lexical.e2e.spec.ts b/test/fields/lexical.e2e.spec.ts index 4c4e561c28..c7f9d42201 100644 --- a/test/fields/lexical.e2e.spec.ts +++ b/test/fields/lexical.e2e.spec.ts @@ -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.') }) }) diff --git a/test/fields/payload-types.ts b/test/fields/payload-types.ts index 3eecb4c3aa..186fbd9de6 100644 --- a/test/fields/payload-types.ts +++ b/test/fields/payload-types.ts @@ -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 {} diff --git a/test/graphql-schema-gen/config.ts b/test/graphql-schema-gen/config.ts index 01cabbfd70..331176982d 100644 --- a/test/graphql-schema-gen/config.ts +++ b/test/graphql-schema-gen/config.ts @@ -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: [ { diff --git a/test/graphql-schema-gen/schema.graphql b/test/graphql-schema-gen/schema.graphql index 0ddf1ff56d..5cc6e7a917 100644 --- a/test/graphql-schema-gen/schema.graphql +++ b/test/graphql-schema-gen/schema.graphql @@ -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_metaArray_Create { + permission: Boolean! +} + +type Collection2DocAccessFields_metaArray_Read { + permission: Boolean! +} + +type Collection2DocAccessFields_metaArray_Update { + permission: Boolean! +} + +type Collection2DocAccessFields_metaArray_Delete { + permission: Boolean! +} + +type Collection2DocAccessFields_metaArray_Fields { + title: Collection2DocAccessFields_metaArray_title + description: Collection2DocAccessFields_metaArray_description + id: Collection2DocAccessFields_metaArray_id +} + +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_Create { +type Collection2DocAccessFields_metaArray_title_Create { permission: Boolean! } -type Collection2DocAccessFields_meta_Read { +type Collection2DocAccessFields_metaArray_title_Read { permission: Boolean! } -type Collection2DocAccessFields_meta_Update { +type Collection2DocAccessFields_metaArray_title_Update { permission: Boolean! } -type Collection2DocAccessFields_meta_Delete { +type Collection2DocAccessFields_metaArray_title_Delete { permission: Boolean! } -type Collection2DocAccessFields_meta_Fields { - title: Collection2DocAccessFields_meta_title - description: Collection2DocAccessFields_meta_description +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_title { - create: Collection2DocAccessFields_meta_title_Create - read: Collection2DocAccessFields_meta_title_Read - update: Collection2DocAccessFields_meta_title_Update - delete: Collection2DocAccessFields_meta_title_Delete +type Collection2DocAccessFields_metaArray_description_Create { + permission: Boolean! } -type Collection2DocAccessFields_meta_title_Create { +type Collection2DocAccessFields_metaArray_description_Read { permission: Boolean! } -type Collection2DocAccessFields_meta_title_Read { +type Collection2DocAccessFields_metaArray_description_Update { permission: Boolean! } -type Collection2DocAccessFields_meta_title_Update { +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_meta_title_Delete { +type Collection2DocAccessFields_metaArray_id_Read { 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_id_Update { + permission: Boolean! } -type Collection2DocAccessFields_meta_description_Create { +type Collection2DocAccessFields_metaArray_id_Delete { permission: Boolean! } -type Collection2DocAccessFields_meta_description_Read { +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_meta_description_Update { +type Collection2DocAccessFields_metaGroup_Read { permission: Boolean! } -type Collection2DocAccessFields_meta_description_Delete { +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_metaArray_title { + create: Collection2Fields_metaArray_title_Create + read: Collection2Fields_metaArray_title_Read + update: Collection2Fields_metaArray_title_Update + delete: Collection2Fields_metaArray_title_Delete +} + +type Collection2Fields_metaArray_title_Create { + permission: Boolean! +} + +type Collection2Fields_metaArray_title_Read { + permission: Boolean! +} + +type Collection2Fields_metaArray_title_Update { + permission: Boolean! +} + +type Collection2Fields_metaArray_title_Delete { + permission: Boolean! } -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_description { + create: Collection2Fields_metaArray_description_Create + read: Collection2Fields_metaArray_description_Read + update: Collection2Fields_metaArray_description_Update + delete: Collection2Fields_metaArray_description_Delete } -type Collection2Fields_meta_title_Create { +type Collection2Fields_metaArray_description_Create { permission: Boolean! } -type Collection2Fields_meta_title_Read { +type Collection2Fields_metaArray_description_Read { permission: Boolean! } -type Collection2Fields_meta_title_Update { +type Collection2Fields_metaArray_description_Update { permission: Boolean! } -type Collection2Fields_meta_title_Delete { +type Collection2Fields_metaArray_description_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_id { + create: Collection2Fields_metaArray_id_Create + read: Collection2Fields_metaArray_id_Read + update: Collection2Fields_metaArray_id_Update + delete: Collection2Fields_metaArray_id_Delete } -type Collection2Fields_meta_description_Create { +type Collection2Fields_metaArray_id_Create { permission: Boolean! } -type Collection2Fields_meta_description_Read { +type Collection2Fields_metaArray_id_Read { permission: Boolean! } -type Collection2Fields_meta_description_Update { +type Collection2Fields_metaArray_id_Update { permission: Boolean! } -type Collection2Fields_meta_description_Delete { +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 }