interface CustomField {
    name: String!
    type: String!
    list: Boolean!
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    ui: JSON
}

type StringCustomFieldConfig implements CustomField {
    name: String!
    type: String!
    list: Boolean!
    length: Int
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    pattern: String
    options: [StringFieldOption!]
    ui: JSON
}

type StringFieldOption {
    value: String!
    label: [LocalizedString!]
}

type LocaleStringCustomFieldConfig implements CustomField {
    name: String!
    type: String!
    list: Boolean!
    length: Int
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    pattern: String
    ui: JSON
}
type IntCustomFieldConfig implements CustomField {
    name: String!
    type: String!
    list: Boolean!
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    min: Int
    max: Int
    step: Int
    ui: JSON
}
type FloatCustomFieldConfig implements CustomField {
    name: String!
    type: String!
    list: Boolean!
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    min: Float
    max: Float
    step: Float
    ui: JSON
}
type BooleanCustomFieldConfig implements CustomField {
    name: String!
    type: String!
    list: Boolean!
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    ui: JSON
}
"""
Expects the same validation formats as the `<input type="datetime-local">` HTML element.
See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local#Additional_attributes
"""
type DateTimeCustomFieldConfig implements CustomField {
    name: String!
    type: String!
    list: Boolean!
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    min: String
    max: String
    step: Int
    ui: JSON
}

type RelationCustomFieldConfig implements CustomField {
    name: String!
    type: String!
    list: Boolean!
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    entity: String!
    scalarFields: [String!]!
    ui: JSON
}

type TextCustomFieldConfig implements CustomField {
    name: String!
    type: String!
    list: Boolean!
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    ui: JSON
}

type LocaleTextCustomFieldConfig implements CustomField {
    name: String!
    type: String!
    list: Boolean!
    label: [LocalizedString!]
    description: [LocalizedString!]
    readonly: Boolean
    internal: Boolean
    nullable: Boolean
    requiresPermission: [Permission!]
    ui: JSON
}

type LocalizedString {
    languageCode: LanguageCode!
    value: String!
}

union CustomFieldConfig =
      StringCustomFieldConfig
    | LocaleStringCustomFieldConfig
    | IntCustomFieldConfig
    | FloatCustomFieldConfig
    | BooleanCustomFieldConfig
    | DateTimeCustomFieldConfig
    | RelationCustomFieldConfig
    | TextCustomFieldConfig
    | LocaleTextCustomFieldConfig
