diff --git a/src/admin/components/elements/ListDrawer/DrawerContent.tsx b/src/admin/components/elements/ListDrawer/DrawerContent.tsx index feff029232..051ea6c09b 100644 --- a/src/admin/components/elements/ListDrawer/DrawerContent.tsx +++ b/src/admin/components/elements/ListDrawer/DrawerContent.tsx @@ -50,11 +50,11 @@ export const ListDrawerContent: React.FC = ({ const [selectedOption, setSelectedOption] = useState<{ label: string, value: string }>(() => (selectedCollectionConfig ? { label: getTranslation(selectedCollectionConfig.labels.singular, i18n), value: selectedCollectionConfig.slug } : undefined)); - const [fields, setFields] = useState(() => formatFields(selectedCollectionConfig, t)); + const [fields, setFields] = useState(() => formatFields(selectedCollectionConfig)); useEffect(() => { - setFields(formatFields(selectedCollectionConfig, t)); - }, [selectedCollectionConfig, t]); + setFields(formatFields(selectedCollectionConfig)); + }, [selectedCollectionConfig]); // allow external control of selected collection, same as the initial state logic above useEffect(() => { diff --git a/src/admin/components/elements/TableColumns/index.tsx b/src/admin/components/elements/TableColumns/index.tsx index 976ae1c5c6..b4dbea4d41 100644 --- a/src/admin/components/elements/TableColumns/index.tsx +++ b/src/admin/components/elements/TableColumns/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useReducer, createContext, useContext, useRef, useState } from 'react'; +import React, { createContext, useCallback, useContext, useEffect, useReducer, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { SanitizedCollectionConfig } from '../../../../collections/config/types'; import { usePreferences } from '../../utilities/Preferences'; @@ -46,7 +46,7 @@ export const TableColumnsProvider: React.FC<{ const hasInitialized = useRef(false); const { getPreference, setPreference } = usePreferences(); const { t } = useTranslation(); - const [formattedFields] = useState(() => formatFields(collection, t)); + const [formattedFields] = useState(() => formatFields(collection)); const [tableColumns, dispatchTableColumns] = useReducer(columnReducer, {}, () => { const initialColumns = getInitialColumnState(formattedFields, useAsTitle, defaultColumns); @@ -91,7 +91,7 @@ export const TableColumnsProvider: React.FC<{ } return column; }), - collection: { ...collection, fields: formatFields(collection, t) }, + collection: { ...collection, fields: formatFields(collection) }, cellProps, }, }); @@ -101,7 +101,7 @@ export const TableColumnsProvider: React.FC<{ }; sync(); - }, [preferenceKey, setPreference, tableColumns, getPreference, useAsTitle, defaultColumns, collection, cellProps, formattedFields, t]); + }, [preferenceKey, setPreference, tableColumns, getPreference, useAsTitle, defaultColumns, collection, cellProps, formattedFields]); // ///////////////////////////////////// // Set preferences on column change @@ -131,7 +131,7 @@ export const TableColumnsProvider: React.FC<{ dispatchTableColumns({ type: 'set', payload: { - collection: { ...collection, fields: formatFields(collection, t) }, + collection: { ...collection, fields: formatFields(collection) }, columns: columns.map((column) => ({ accessor: column, active: true, @@ -140,7 +140,7 @@ export const TableColumnsProvider: React.FC<{ cellProps, }, }); - }, [collection, t, cellProps]); + }, [collection, cellProps]); const moveColumn = useCallback((args: { fromIndex: number @@ -153,22 +153,22 @@ export const TableColumnsProvider: React.FC<{ payload: { fromIndex, toIndex, - collection: { ...collection, fields: formatFields(collection, t) }, + collection: { ...collection, fields: formatFields(collection) }, cellProps, }, }); - }, [collection, t, cellProps]); + }, [collection, cellProps]); const toggleColumn = useCallback((column: string) => { dispatchTableColumns({ type: 'toggle', payload: { column, - collection: { ...collection, fields: formatFields(collection, t) }, + collection: { ...collection, fields: formatFields(collection) }, cellProps, }, }); - }, [collection, t, cellProps]); + }, [collection, cellProps]); return ( { +const formatFields = (config: SanitizedCollectionConfig): Field[] => { const hasID = config.fields.findIndex((field) => fieldAffectsData(field) && field.name === 'id') > -1; const fields: Field[] = config.fields.reduce((formatted, field) => { if (!fieldIsPresentationalOnly(field) && (field.hidden === true || field?.admin?.disabled === true)) { @@ -23,27 +22,6 @@ const formatFields = (config: SanitizedCollectionConfig, t: TFunction): Field[] }, }]); - if (config.timestamps) { - fields.push( - { - name: 'createdAt', - label: t('general:createdAt'), - type: 'date', - admin: { - disableBulkEdit: true, - }, - }, - { - name: 'updatedAt', - label: t('general:updatedAt'), - type: 'date', - admin: { - disableBulkEdit: true, - }, - }, - ); - } - return fields; }; diff --git a/src/admin/components/views/collections/List/index.tsx b/src/admin/components/views/collections/List/index.tsx index 5ea89e5174..6b03c65348 100644 --- a/src/admin/components/views/collections/List/index.tsx +++ b/src/admin/components/views/collections/List/index.tsx @@ -1,5 +1,5 @@ import { v4 as uuid } from 'uuid'; -import React, { useEffect, useState, useCallback } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { useHistory } from 'react-router-dom'; import queryString from 'qs'; import { useTranslation } from 'react-i18next'; @@ -10,7 +10,7 @@ import DefaultList from './Default'; import RenderCustomComponent from '../../../utilities/RenderCustomComponent'; import { useStepNav } from '../../../elements/StepNav'; import formatFields from './formatFields'; -import { Props, ListIndexProps, ListPreferences } from './types'; +import { ListIndexProps, ListPreferences, Props } from './types'; import { usePreferences } from '../../../utilities/Preferences'; import { useSearchParams } from '../../../utilities/SearchParams'; import { TableColumnsProvider } from '../../../elements/TableColumns'; @@ -46,7 +46,7 @@ const ListView: React.FC = (props) => { const history = useHistory(); const { t } = useTranslation('general'); const [fetchURL, setFetchURL] = useState(''); - const [fields] = useState(() => formatFields(collection, t)); + const [fields] = useState(() => formatFields(collection)); const collectionPermissions = permissions?.collections?.[slug]; const hasCreatePermission = collectionPermissions?.create?.permission; const newDocumentURL = `${admin}/collections/${slug}/create`; diff --git a/src/collections/config/sanitize.ts b/src/collections/config/sanitize.ts index fbf18f4ec1..042ff0f6ad 100644 --- a/src/collections/config/sanitize.ts +++ b/src/collections/config/sanitize.ts @@ -1,6 +1,6 @@ import merge from 'deepmerge'; import { isPlainObject } from 'is-plain-object'; -import { SanitizedCollectionConfig, CollectionConfig } from './types'; +import { CollectionConfig, SanitizedCollectionConfig } from './types'; import sanitizeFields from '../../fields/config/sanitize'; import baseAuthFields from '../../auth/baseFields/auth'; import baseAPIKeyFields from '../../auth/baseFields/apiKey'; @@ -8,11 +8,18 @@ import baseVerificationFields from '../../auth/baseFields/verification'; import baseAccountLockFields from '../../auth/baseFields/accountLock'; import getBaseUploadFields from '../../uploads/getBaseFields'; import { formatLabels } from '../../utilities/formatLabels'; -import { defaults, authDefaults } from './defaults'; +import { authDefaults, defaults } from './defaults'; import { Config } from '../../config/types'; import baseVersionFields from '../../versions/baseFields'; import TimestampsRequired from '../../errors/TimestampsRequired'; import mergeBaseFields from '../../fields/mergeBaseFields'; +import { extractTranslations } from '../../translations/extractTranslations'; +import { fieldAffectsData } from '../../fields/config/types'; + +const translations = extractTranslations([ + 'general:createdAt', + 'general:updatedAt', +]); const sanitizeCollection = (config: Config, collection: CollectionConfig): SanitizedCollectionConfig => { // ///////////////////////////////// @@ -23,6 +30,41 @@ const sanitizeCollection = (config: Config, collection: CollectionConfig): Sanit isMergeableObject: isPlainObject, }); + if (sanitized.timestamps !== false) { + // add default timestamps fields only as needed + let hasUpdatedAt = null; + let hasCreatedAt = null; + sanitized.fields.some((field) => { + if (fieldAffectsData(field)) { + if (field.name === 'updatedAt') hasUpdatedAt = true; + if (field.name === 'createdAt') hasCreatedAt = true; + } + return hasCreatedAt && hasUpdatedAt; + }); + if (!hasUpdatedAt) { + sanitized.fields.push({ + name: 'updatedAt', + label: translations['general:updatedAt'], + type: 'date', + admin: { + hidden: true, + disableBulkEdit: true, + }, + }); + } + if (!hasCreatedAt) { + sanitized.fields.push({ + name: 'createdAt', + label: translations['general:createdAt'], + type: 'date', + admin: { + hidden: true, + disableBulkEdit: true, + }, + }); + } + } + sanitized.labels = sanitized.labels || formatLabels(sanitized.slug); if (sanitized.versions) { diff --git a/src/collections/graphql/init.ts b/src/collections/graphql/init.ts index 179fc19485..88a81d0449 100644 --- a/src/collections/graphql/init.ts +++ b/src/collections/graphql/init.ts @@ -1,12 +1,5 @@ /* eslint-disable no-param-reassign */ -import { DateTimeResolver } from 'graphql-scalars'; -import { - GraphQLString, - GraphQLObjectType, - GraphQLBoolean, - GraphQLNonNull, - GraphQLInt, -} from 'graphql'; +import { GraphQLBoolean, GraphQLInt, GraphQLNonNull, GraphQLObjectType, GraphQLString } from 'graphql'; import formatName from '../../graphql/utilities/formatName'; import buildPaginatedListType from '../../graphql/schema/buildPaginatedListType'; @@ -33,7 +26,7 @@ import { Field, fieldAffectsData } from '../../fields/config/types'; import buildObjectType, { ObjectTypeConfig } from '../../graphql/schema/buildObjectType'; import buildWhereInputType from '../../graphql/schema/buildWhereInputType'; import getDeleteResolver from './resolvers/delete'; -import { toWords, formatNames } from '../../utilities/formatLabels'; +import { formatNames, toWords } from '../../utilities/formatLabels'; import { Collection, SanitizedCollectionConfig } from '../config/types'; import { buildPolicyType } from '../../graphql/schema/buildPoliciesType'; import { docAccessResolver } from './resolvers/docAccess'; @@ -42,13 +35,13 @@ function initCollectionsGraphQL(payload: Payload): void { Object.keys(payload.collections).forEach((slug) => { const collection: Collection = payload.collections[slug]; const { + config, config: { graphQL = {} as SanitizedCollectionConfig['graphQL'], - fields, - timestamps, versions, }, } = collection; + const { fields } = config; let singularName; let pluralName; @@ -75,7 +68,7 @@ function initCollectionsGraphQL(payload: Payload): void { collection.graphQL = {} as Collection['graphQL']; const idField = fields.find((field) => fieldAffectsData(field) && field.name === 'id'); - const idType = getCollectionIDType(collection.config); + const idType = getCollectionIDType(config); const baseFields: ObjectTypeConfig = {}; @@ -91,28 +84,6 @@ function initCollectionsGraphQL(payload: Payload): void { }); } - if (timestamps) { - baseFields.createdAt = { - type: new GraphQLNonNull(DateTimeResolver), - }; - - baseFields.updatedAt = { - type: new GraphQLNonNull(DateTimeResolver), - }; - - whereInputFields.push({ - name: 'createdAt', - label: 'Created At', - type: 'date', - }); - - whereInputFields.push({ - name: 'updatedAt', - label: 'Updated At', - type: 'date', - }); - } - const forceNullableObjectType = Boolean(versions?.drafts); collection.graphQL.type = buildObjectType({ @@ -130,7 +101,7 @@ function initCollectionsGraphQL(payload: Payload): void { singularName, ); - if (collection.config.auth && !collection.config.auth.disableLocalStrategy) { + if (config.auth && !config.auth.disableLocalStrategy) { fields.push({ name: 'password', label: 'Password', @@ -186,7 +157,7 @@ function initCollectionsGraphQL(payload: Payload): void { payload.Query.fields[`docAccess${singularName}`] = { type: buildPolicyType({ typeSuffix: 'DocAccess', - entity: collection.config, + entity: config, type: 'collection', scope: 'docAccess', }), @@ -230,9 +201,9 @@ function initCollectionsGraphQL(payload: Payload): void { resolve: getDeleteResolver(collection), }; - if (collection.config.versions) { + if (config.versions) { const versionCollectionFields: Field[] = [ - ...buildVersionCollectionFields(collection.config), + ...buildVersionCollectionFields(config), { name: 'id', type: 'text', @@ -297,8 +268,8 @@ function initCollectionsGraphQL(payload: Payload): void { }; } - if (collection.config.auth) { - const authFields: Field[] = collection.config.auth.disableLocalStrategy ? [] : [{ + if (config.auth) { + const authFields: Field[] = config.auth.disableLocalStrategy ? [] : [{ name: 'email', type: 'email', required: true, @@ -307,7 +278,7 @@ function initCollectionsGraphQL(payload: Payload): void { payload, name: formatName(`${slug}JWT`), fields: [ - ...collection.config.fields.filter((field) => fieldAffectsData(field) && field.saveToJWT), + ...config.fields.filter((field) => fieldAffectsData(field) && field.saveToJWT), ...authFields, { name: 'collection', @@ -370,8 +341,8 @@ function initCollectionsGraphQL(payload: Payload): void { resolve: logout(collection), }; - if (!collection.config.auth.disableLocalStrategy) { - if (collection.config.auth.maxLoginAttempts > 0) { + if (!config.auth.disableLocalStrategy) { + if (config.auth.maxLoginAttempts > 0) { payload.Mutation.fields[`unlock${singularName}`] = { type: new GraphQLNonNull(GraphQLBoolean), args: { diff --git a/src/graphql/schema/withNullableType.ts b/src/graphql/schema/withNullableType.ts index 4c0259f034..33b90729ed 100644 --- a/src/graphql/schema/withNullableType.ts +++ b/src/graphql/schema/withNullableType.ts @@ -4,8 +4,9 @@ import { FieldAffectingData } from '../../fields/config/types'; const withNullableType = (field: FieldAffectingData, type: GraphQLType, forceNullable = false): GraphQLType => { const hasReadAccessControl = field.access && field.access.read; const condition = field.admin && field.admin.condition; + const isTimestamp = field.name === 'createdAt' || field.name === 'updatedAt'; - if (!forceNullable && 'required' in field && field.required && !field.localized && !condition && !hasReadAccessControl) { + if (!forceNullable && 'required' in field && field.required && !field.localized && !condition && !hasReadAccessControl && !isTimestamp) { return new GraphQLNonNull(type); } diff --git a/src/utilities/entityToJSONSchema.ts b/src/utilities/entityToJSONSchema.ts index 92b80355a4..17047f8335 100644 --- a/src/utilities/entityToJSONSchema.ts +++ b/src/utilities/entityToJSONSchema.ts @@ -1,7 +1,6 @@ - import { singular } from 'pluralize'; import type { JSONSchema4 } from 'json-schema'; -import { fieldAffectsData, Field, Option, FieldAffectingData, tabHasName } from '../fields/config/types'; +import { Field, FieldAffectingData, fieldAffectsData, Option, tabHasName } from '../fields/config/types'; import { SanitizedCollectionConfig } from '../collections/config/types'; import { SanitizedGlobalConfig } from '../globals/config/types'; import deepCopyObject from './deepCopyObject'; @@ -401,19 +400,17 @@ export function entityToJSONSchema(config: SanitizedConfig, incomingEntity: Sani entity.fields.unshift(idField); } + // mark timestamp fields required if ('timestamps' in entity && entity.timestamps !== false) { - entity.fields.push( - { - type: 'text', - name: 'createdAt', - required: true, - }, - { - type: 'text', - name: 'updatedAt', - required: true, - }, - ); + entity.fields = entity.fields.map((field) => { + if (fieldAffectsData(field) && (field.name === 'createdAt' || field.name === 'updatedAt')) { + return { + ...field, + required: true, + }; + } + return field; + }); } if ('auth' in entity && entity.auth && !entity.auth?.disableLocalStrategy) { diff --git a/test/admin/payload-types.ts b/test/admin/payload-types.ts index fa4d331688..5d9d139568 100644 --- a/test/admin/payload-types.ts +++ b/test/admin/payload-types.ts @@ -5,94 +5,88 @@ * 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` "global". - */ -export interface Global { - id: string; - title?: string; +export interface Config { + collections: { + users: User; + 'hidden-collection': HiddenCollection; + posts: Post; + 'group-one-collection-ones': GroupOneCollectionOne; + 'group-one-collection-twos': GroupOneCollectionTwo; + 'group-two-collection-ones': GroupTwoCollectionOne; + 'group-two-collection-twos': GroupTwoCollectionTwo; + }; + globals: { + 'hidden-global': HiddenGlobal; + global: Global; + 'group-globals-one': GroupGlobalsOne; + 'group-globals-two': GroupGlobalsTwo; + }; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "group-globals-one". - */ -export interface GroupGlobalsOne { - id: string; - title?: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "group-globals-two". - */ -export interface GroupGlobalsTwo { - id: string; - title?: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "users". - */ export interface User { id: string; + createdAt: string; + updatedAt: string; email?: string; resetPasswordToken?: string; resetPasswordExpiration?: string; loginAttempts?: number; lockUntil?: string; + password?: string; +} +export interface HiddenCollection { + id: string; + title?: string; createdAt: string; updatedAt: string; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "posts". - */ export interface Post { id: string; title?: string; description?: string; number?: number; + richText?: { + [k: string]: unknown; + }[]; createdAt: string; updatedAt: string; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "group-one-collection-ones". - */ export interface GroupOneCollectionOne { id: string; title?: string; createdAt: string; updatedAt: string; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "group-one-collection-twos". - */ export interface GroupOneCollectionTwo { id: string; title?: string; createdAt: string; updatedAt: string; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "group-two-collection-ones". - */ export interface GroupTwoCollectionOne { id: string; title?: string; createdAt: string; updatedAt: string; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "group-two-collection-twos". - */ export interface GroupTwoCollectionTwo { id: string; title?: string; createdAt: string; updatedAt: string; } +export interface HiddenGlobal { + id: string; + title?: string; +} +export interface Global { + id: string; + title?: string; +} +export interface GroupGlobalsOne { + id: string; + title?: string; +} +export interface GroupGlobalsTwo { + id: string; + title?: string; +} diff --git a/test/fields/int.spec.ts b/test/fields/int.spec.ts index fe76ed4388..21351d4e63 100644 --- a/test/fields/int.spec.ts +++ b/test/fields/int.spec.ts @@ -10,6 +10,7 @@ import { defaultText } from './collections/Text'; import { blocksFieldSeedData } from './collections/Blocks'; import { localizedTextValue, namedTabDefaultValue, namedTabText, tabsDoc, tabsSlug } from './collections/Tabs'; import { defaultNumber, numberDoc } from './collections/Number'; +import { dateDoc } from './collections/Date'; let client; let serverURL; @@ -41,6 +42,45 @@ describe('Fields', () => { }); }); + describe('timestamps', () => { + const tenMinutesAgo = new Date(Date.now() - 1000 * 60 * 10); + let doc; + beforeAll(async () => { + doc = await payload.create({ + collection: 'date-fields', + data: dateDoc, + }); + }); + + it('should query updatedAt', async () => { + const { docs } = await payload.find({ + collection: 'date-fields', + depth: 0, + where: { + updatedAt: { + greater_than_equal: tenMinutesAgo, + }, + }, + }); + + expect(docs.map(({ id }) => id)).toContain(doc.id); + }); + + it('should query createdAt', async () => { + const result = await payload.find({ + collection: 'date-fields', + depth: 0, + where: { + createdAt: { + greater_than_equal: tenMinutesAgo, + }, + }, + }); + + expect(result.docs[0].id).toEqual(doc.id); + }); + }); + describe('select', () => { let doc; beforeAll(async () => { diff --git a/test/graphql-schema-gen/generated-schema.graphql b/test/graphql-schema-gen/generated-schema.graphql index 76cc0e1442..04c152e2d5 100644 --- a/test/graphql-schema-gen/generated-schema.graphql +++ b/test/graphql-schema-gen/generated-schema.graphql @@ -19,8 +19,6 @@ type Query { type Post { id: String - createdAt: DateTime! - updatedAt: DateTime! title: String description: String number: Float @@ -28,6 +26,15 @@ type Post { relationHasManyField: [Relation!] relationMultiRelationTo: Post_RelationMultiRelationTo_Relationship relationMultiRelationToHasMany: [Post_RelationMultiRelationToHasMany_Relationship!] + createdAt: DateTime! + updatedAt: DateTime! +} + +type Relation { + id: String + name: String + createdAt: DateTime! + updatedAt: DateTime! } """ @@ -35,13 +42,6 @@ A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `dat """ scalar DateTime -type Relation { - id: String - createdAt: DateTime! - updatedAt: DateTime! - name: String -} - type Post_RelationMultiRelationTo_Relationship { relationTo: Post_RelationMultiRelationTo_RelationTo value: Post_RelationMultiRelationTo @@ -56,9 +56,9 @@ union Post_RelationMultiRelationTo = Relation | Dummy type Dummy { id: String + name: String createdAt: DateTime! updatedAt: DateTime! - name: String } type Post_RelationMultiRelationToHasMany_Relationship { @@ -95,9 +95,9 @@ input Post_where { relationHasManyField: Post_relationHasManyField_operator relationMultiRelationTo: Post_relationMultiRelationTo_Relation relationMultiRelationToHasMany: Post_relationMultiRelationToHasMany_Relation - id: Post_id_operator createdAt: Post_createdAt_operator updatedAt: Post_updatedAt_operator + id: Post_id_operator OR: [Post_where_or] AND: [Post_where_and] } @@ -172,20 +172,6 @@ enum Post_relationMultiRelationToHasMany_Relation_RelationTo { dummy } -input Post_id_operator { - equals: JSON - not_equals: JSON - in: [JSON] - not_in: [JSON] - all: [JSON] - exists: Boolean -} - -""" -The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). -""" -scalar JSON - input Post_createdAt_operator { equals: DateTime not_equals: DateTime @@ -208,6 +194,20 @@ input Post_updatedAt_operator { exists: Boolean } +input Post_id_operator { + equals: JSON + not_equals: JSON + in: [JSON] + not_in: [JSON] + all: [JSON] + exists: Boolean +} + +""" +The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). +""" +scalar JSON + input Post_where_or { title: Post_title_operator description: Post_description_operator @@ -216,9 +216,9 @@ input Post_where_or { relationHasManyField: Post_relationHasManyField_operator relationMultiRelationTo: Post_relationMultiRelationTo_Relation relationMultiRelationToHasMany: Post_relationMultiRelationToHasMany_Relation - id: Post_id_operator createdAt: Post_createdAt_operator updatedAt: Post_updatedAt_operator + id: Post_id_operator } input Post_where_and { @@ -229,9 +229,9 @@ input Post_where_and { relationHasManyField: Post_relationHasManyField_operator relationMultiRelationTo: Post_relationMultiRelationTo_Relation relationMultiRelationToHasMany: Post_relationMultiRelationToHasMany_Relation - id: Post_id_operator createdAt: Post_createdAt_operator updatedAt: Post_updatedAt_operator + id: Post_id_operator } type postsDocAccess { @@ -250,6 +250,8 @@ type PostsDocAccessFields { relationHasManyField: PostsDocAccessFields_relationHasManyField relationMultiRelationTo: PostsDocAccessFields_relationMultiRelationTo relationMultiRelationToHasMany: PostsDocAccessFields_relationMultiRelationToHasMany + createdAt: PostsDocAccessFields_createdAt + updatedAt: PostsDocAccessFields_updatedAt } type PostsDocAccessFields_title { @@ -413,6 +415,52 @@ type PostsDocAccessFields_relationMultiRelationToHasMany_Delete { permission: Boolean! } +type PostsDocAccessFields_createdAt { + create: PostsDocAccessFields_createdAt_Create + read: PostsDocAccessFields_createdAt_Read + update: PostsDocAccessFields_createdAt_Update + delete: PostsDocAccessFields_createdAt_Delete +} + +type PostsDocAccessFields_createdAt_Create { + permission: Boolean! +} + +type PostsDocAccessFields_createdAt_Read { + permission: Boolean! +} + +type PostsDocAccessFields_createdAt_Update { + permission: Boolean! +} + +type PostsDocAccessFields_createdAt_Delete { + permission: Boolean! +} + +type PostsDocAccessFields_updatedAt { + create: PostsDocAccessFields_updatedAt_Create + read: PostsDocAccessFields_updatedAt_Read + update: PostsDocAccessFields_updatedAt_Update + delete: PostsDocAccessFields_updatedAt_Delete +} + +type PostsDocAccessFields_updatedAt_Create { + permission: Boolean! +} + +type PostsDocAccessFields_updatedAt_Read { + permission: Boolean! +} + +type PostsDocAccessFields_updatedAt_Update { + permission: Boolean! +} + +type PostsDocAccessFields_updatedAt_Delete { + permission: Boolean! +} + type PostsCreateDocAccess { permission: Boolean! where: JSONObject @@ -454,9 +502,9 @@ type Relations { input Relation_where { name: Relation_name_operator - id: Relation_id_operator createdAt: Relation_createdAt_operator updatedAt: Relation_updatedAt_operator + id: Relation_id_operator OR: [Relation_where_or] AND: [Relation_where_and] } @@ -472,15 +520,6 @@ input Relation_name_operator { exists: Boolean } -input Relation_id_operator { - equals: JSON - not_equals: JSON - in: [JSON] - not_in: [JSON] - all: [JSON] - exists: Boolean -} - input Relation_createdAt_operator { equals: DateTime not_equals: DateTime @@ -503,18 +542,27 @@ input Relation_updatedAt_operator { exists: Boolean } +input Relation_id_operator { + equals: JSON + not_equals: JSON + in: [JSON] + not_in: [JSON] + all: [JSON] + exists: Boolean +} + input Relation_where_or { name: Relation_name_operator - id: Relation_id_operator createdAt: Relation_createdAt_operator updatedAt: Relation_updatedAt_operator + id: Relation_id_operator } input Relation_where_and { name: Relation_name_operator - id: Relation_id_operator createdAt: Relation_createdAt_operator updatedAt: Relation_updatedAt_operator + id: Relation_id_operator } type relationDocAccess { @@ -527,6 +575,8 @@ type relationDocAccess { type RelationDocAccessFields { name: RelationDocAccessFields_name + createdAt: RelationDocAccessFields_createdAt + updatedAt: RelationDocAccessFields_updatedAt } type RelationDocAccessFields_name { @@ -552,6 +602,52 @@ type RelationDocAccessFields_name_Delete { permission: Boolean! } +type RelationDocAccessFields_createdAt { + create: RelationDocAccessFields_createdAt_Create + read: RelationDocAccessFields_createdAt_Read + update: RelationDocAccessFields_createdAt_Update + delete: RelationDocAccessFields_createdAt_Delete +} + +type RelationDocAccessFields_createdAt_Create { + permission: Boolean! +} + +type RelationDocAccessFields_createdAt_Read { + permission: Boolean! +} + +type RelationDocAccessFields_createdAt_Update { + permission: Boolean! +} + +type RelationDocAccessFields_createdAt_Delete { + permission: Boolean! +} + +type RelationDocAccessFields_updatedAt { + create: RelationDocAccessFields_updatedAt_Create + read: RelationDocAccessFields_updatedAt_Read + update: RelationDocAccessFields_updatedAt_Update + delete: RelationDocAccessFields_updatedAt_Delete +} + +type RelationDocAccessFields_updatedAt_Create { + permission: Boolean! +} + +type RelationDocAccessFields_updatedAt_Read { + permission: Boolean! +} + +type RelationDocAccessFields_updatedAt_Update { + permission: Boolean! +} + +type RelationDocAccessFields_updatedAt_Delete { + permission: Boolean! +} + type RelationCreateDocAccess { permission: Boolean! where: JSONObject @@ -588,9 +684,9 @@ type Dummies { input Dummy_where { name: Dummy_name_operator - id: Dummy_id_operator createdAt: Dummy_createdAt_operator updatedAt: Dummy_updatedAt_operator + id: Dummy_id_operator OR: [Dummy_where_or] AND: [Dummy_where_and] } @@ -606,15 +702,6 @@ input Dummy_name_operator { exists: Boolean } -input Dummy_id_operator { - equals: JSON - not_equals: JSON - in: [JSON] - not_in: [JSON] - all: [JSON] - exists: Boolean -} - input Dummy_createdAt_operator { equals: DateTime not_equals: DateTime @@ -637,18 +724,27 @@ input Dummy_updatedAt_operator { exists: Boolean } +input Dummy_id_operator { + equals: JSON + not_equals: JSON + in: [JSON] + not_in: [JSON] + all: [JSON] + exists: Boolean +} + input Dummy_where_or { name: Dummy_name_operator - id: Dummy_id_operator createdAt: Dummy_createdAt_operator updatedAt: Dummy_updatedAt_operator + id: Dummy_id_operator } input Dummy_where_and { name: Dummy_name_operator - id: Dummy_id_operator createdAt: Dummy_createdAt_operator updatedAt: Dummy_updatedAt_operator + id: Dummy_id_operator } type dummyDocAccess { @@ -661,6 +757,8 @@ type dummyDocAccess { type DummyDocAccessFields { name: DummyDocAccessFields_name + createdAt: DummyDocAccessFields_createdAt + updatedAt: DummyDocAccessFields_updatedAt } type DummyDocAccessFields_name { @@ -686,6 +784,52 @@ type DummyDocAccessFields_name_Delete { permission: Boolean! } +type DummyDocAccessFields_createdAt { + create: DummyDocAccessFields_createdAt_Create + read: DummyDocAccessFields_createdAt_Read + update: DummyDocAccessFields_createdAt_Update + delete: DummyDocAccessFields_createdAt_Delete +} + +type DummyDocAccessFields_createdAt_Create { + permission: Boolean! +} + +type DummyDocAccessFields_createdAt_Read { + permission: Boolean! +} + +type DummyDocAccessFields_createdAt_Update { + permission: Boolean! +} + +type DummyDocAccessFields_createdAt_Delete { + permission: Boolean! +} + +type DummyDocAccessFields_updatedAt { + create: DummyDocAccessFields_updatedAt_Create + read: DummyDocAccessFields_updatedAt_Read + update: DummyDocAccessFields_updatedAt_Update + delete: DummyDocAccessFields_updatedAt_Delete +} + +type DummyDocAccessFields_updatedAt_Create { + permission: Boolean! +} + +type DummyDocAccessFields_updatedAt_Read { + permission: Boolean! +} + +type DummyDocAccessFields_updatedAt_Update { + permission: Boolean! +} + +type DummyDocAccessFields_updatedAt_Delete { + permission: Boolean! +} + type DummyCreateDocAccess { permission: Boolean! where: JSONObject @@ -738,34 +882,14 @@ type Users { } input User_where { - email: User_email_operator - id: User_id_operator createdAt: User_createdAt_operator updatedAt: User_updatedAt_operator + email: User_email_operator + id: User_id_operator OR: [User_where_or] AND: [User_where_and] } -input User_email_operator { - equals: EmailAddress - not_equals: EmailAddress - like: EmailAddress - contains: EmailAddress - in: [EmailAddress] - not_in: [EmailAddress] - all: [EmailAddress] - exists: Boolean -} - -input User_id_operator { - equals: JSON - not_equals: JSON - in: [JSON] - not_in: [JSON] - all: [JSON] - exists: Boolean -} - input User_createdAt_operator { equals: DateTime not_equals: DateTime @@ -788,18 +912,38 @@ input User_updatedAt_operator { exists: Boolean } +input User_email_operator { + equals: EmailAddress + not_equals: EmailAddress + like: EmailAddress + contains: EmailAddress + in: [EmailAddress] + not_in: [EmailAddress] + all: [EmailAddress] + exists: Boolean +} + +input User_id_operator { + equals: JSON + not_equals: JSON + in: [JSON] + not_in: [JSON] + all: [JSON] + exists: Boolean +} + input User_where_or { - email: User_email_operator - id: User_id_operator createdAt: User_createdAt_operator updatedAt: User_updatedAt_operator + email: User_email_operator + id: User_id_operator } input User_where_and { - email: User_email_operator - id: User_id_operator createdAt: User_createdAt_operator updatedAt: User_updatedAt_operator + email: User_email_operator + id: User_id_operator } type usersDocAccess { @@ -812,8 +956,55 @@ type usersDocAccess { } type UsersDocAccessFields { + createdAt: UsersDocAccessFields_createdAt + updatedAt: UsersDocAccessFields_updatedAt email: UsersDocAccessFields_email - password: UsersDocAccessFields_password +} + +type UsersDocAccessFields_createdAt { + create: UsersDocAccessFields_createdAt_Create + read: UsersDocAccessFields_createdAt_Read + update: UsersDocAccessFields_createdAt_Update + delete: UsersDocAccessFields_createdAt_Delete +} + +type UsersDocAccessFields_createdAt_Create { + permission: Boolean! +} + +type UsersDocAccessFields_createdAt_Read { + permission: Boolean! +} + +type UsersDocAccessFields_createdAt_Update { + permission: Boolean! +} + +type UsersDocAccessFields_createdAt_Delete { + permission: Boolean! +} + +type UsersDocAccessFields_updatedAt { + create: UsersDocAccessFields_updatedAt_Create + read: UsersDocAccessFields_updatedAt_Read + update: UsersDocAccessFields_updatedAt_Update + delete: UsersDocAccessFields_updatedAt_Delete +} + +type UsersDocAccessFields_updatedAt_Create { + permission: Boolean! +} + +type UsersDocAccessFields_updatedAt_Read { + permission: Boolean! +} + +type UsersDocAccessFields_updatedAt_Update { + permission: Boolean! +} + +type UsersDocAccessFields_updatedAt_Delete { + permission: Boolean! } type UsersDocAccessFields_email { @@ -839,29 +1030,6 @@ type UsersDocAccessFields_email_Delete { permission: Boolean! } -type UsersDocAccessFields_password { - create: UsersDocAccessFields_password_Create - read: UsersDocAccessFields_password_Read - update: UsersDocAccessFields_password_Update - delete: UsersDocAccessFields_password_Delete -} - -type UsersDocAccessFields_password_Create { - permission: Boolean! -} - -type UsersDocAccessFields_password_Read { - permission: Boolean! -} - -type UsersDocAccessFields_password_Update { - permission: Boolean! -} - -type UsersDocAccessFields_password_Delete { - permission: Boolean! -} - type UsersCreateDocAccess { permission: Boolean! where: JSONObject @@ -925,6 +1093,8 @@ type PostsFields { relationHasManyField: PostsFields_relationHasManyField relationMultiRelationTo: PostsFields_relationMultiRelationTo relationMultiRelationToHasMany: PostsFields_relationMultiRelationToHasMany + createdAt: PostsFields_createdAt + updatedAt: PostsFields_updatedAt } type PostsFields_title { @@ -1088,6 +1258,52 @@ type PostsFields_relationMultiRelationToHasMany_Delete { permission: Boolean! } +type PostsFields_createdAt { + create: PostsFields_createdAt_Create + read: PostsFields_createdAt_Read + update: PostsFields_createdAt_Update + delete: PostsFields_createdAt_Delete +} + +type PostsFields_createdAt_Create { + permission: Boolean! +} + +type PostsFields_createdAt_Read { + permission: Boolean! +} + +type PostsFields_createdAt_Update { + permission: Boolean! +} + +type PostsFields_createdAt_Delete { + permission: Boolean! +} + +type PostsFields_updatedAt { + create: PostsFields_updatedAt_Create + read: PostsFields_updatedAt_Read + update: PostsFields_updatedAt_Update + delete: PostsFields_updatedAt_Delete +} + +type PostsFields_updatedAt_Create { + permission: Boolean! +} + +type PostsFields_updatedAt_Read { + permission: Boolean! +} + +type PostsFields_updatedAt_Update { + permission: Boolean! +} + +type PostsFields_updatedAt_Delete { + permission: Boolean! +} + type PostsCreateAccess { permission: Boolean! where: JSONObject @@ -1118,6 +1334,8 @@ type relationAccess { type RelationFields { name: RelationFields_name + createdAt: RelationFields_createdAt + updatedAt: RelationFields_updatedAt } type RelationFields_name { @@ -1143,6 +1361,52 @@ type RelationFields_name_Delete { permission: Boolean! } +type RelationFields_createdAt { + create: RelationFields_createdAt_Create + read: RelationFields_createdAt_Read + update: RelationFields_createdAt_Update + delete: RelationFields_createdAt_Delete +} + +type RelationFields_createdAt_Create { + permission: Boolean! +} + +type RelationFields_createdAt_Read { + permission: Boolean! +} + +type RelationFields_createdAt_Update { + permission: Boolean! +} + +type RelationFields_createdAt_Delete { + permission: Boolean! +} + +type RelationFields_updatedAt { + create: RelationFields_updatedAt_Create + read: RelationFields_updatedAt_Read + update: RelationFields_updatedAt_Update + delete: RelationFields_updatedAt_Delete +} + +type RelationFields_updatedAt_Create { + permission: Boolean! +} + +type RelationFields_updatedAt_Read { + permission: Boolean! +} + +type RelationFields_updatedAt_Update { + permission: Boolean! +} + +type RelationFields_updatedAt_Delete { + permission: Boolean! +} + type RelationCreateAccess { permission: Boolean! where: JSONObject @@ -1173,6 +1437,8 @@ type dummyAccess { type DummyFields { name: DummyFields_name + createdAt: DummyFields_createdAt + updatedAt: DummyFields_updatedAt } type DummyFields_name { @@ -1198,6 +1464,52 @@ type DummyFields_name_Delete { permission: Boolean! } +type DummyFields_createdAt { + create: DummyFields_createdAt_Create + read: DummyFields_createdAt_Read + update: DummyFields_createdAt_Update + delete: DummyFields_createdAt_Delete +} + +type DummyFields_createdAt_Create { + permission: Boolean! +} + +type DummyFields_createdAt_Read { + permission: Boolean! +} + +type DummyFields_createdAt_Update { + permission: Boolean! +} + +type DummyFields_createdAt_Delete { + permission: Boolean! +} + +type DummyFields_updatedAt { + create: DummyFields_updatedAt_Create + read: DummyFields_updatedAt_Read + update: DummyFields_updatedAt_Update + delete: DummyFields_updatedAt_Delete +} + +type DummyFields_updatedAt_Create { + permission: Boolean! +} + +type DummyFields_updatedAt_Read { + permission: Boolean! +} + +type DummyFields_updatedAt_Update { + permission: Boolean! +} + +type DummyFields_updatedAt_Delete { + permission: Boolean! +} + type DummyCreateAccess { permission: Boolean! where: JSONObject @@ -1228,8 +1540,55 @@ type usersAccess { } type UsersFields { + createdAt: UsersFields_createdAt + updatedAt: UsersFields_updatedAt email: UsersFields_email - password: UsersFields_password +} + +type UsersFields_createdAt { + create: UsersFields_createdAt_Create + read: UsersFields_createdAt_Read + update: UsersFields_createdAt_Update + delete: UsersFields_createdAt_Delete +} + +type UsersFields_createdAt_Create { + permission: Boolean! +} + +type UsersFields_createdAt_Read { + permission: Boolean! +} + +type UsersFields_createdAt_Update { + permission: Boolean! +} + +type UsersFields_createdAt_Delete { + permission: Boolean! +} + +type UsersFields_updatedAt { + create: UsersFields_updatedAt_Create + read: UsersFields_updatedAt_Read + update: UsersFields_updatedAt_Update + delete: UsersFields_updatedAt_Delete +} + +type UsersFields_updatedAt_Create { + permission: Boolean! +} + +type UsersFields_updatedAt_Read { + permission: Boolean! +} + +type UsersFields_updatedAt_Update { + permission: Boolean! +} + +type UsersFields_updatedAt_Delete { + permission: Boolean! } type UsersFields_email { @@ -1255,29 +1614,6 @@ type UsersFields_email_Delete { permission: Boolean! } -type UsersFields_password { - create: UsersFields_password_Create - read: UsersFields_password_Read - update: UsersFields_password_Update - delete: UsersFields_password_Delete -} - -type UsersFields_password_Create { - permission: Boolean! -} - -type UsersFields_password_Read { - permission: Boolean! -} - -type UsersFields_password_Update { - permission: Boolean! -} - -type UsersFields_password_Delete { - permission: Boolean! -} - type UsersCreateAccess { permission: Boolean! where: JSONObject @@ -1335,6 +1671,8 @@ input mutationPostInput { relationHasManyField: [String] relationMultiRelationTo: Post_RelationMultiRelationToRelationshipInput relationMultiRelationToHasMany: [Post_RelationMultiRelationToHasManyRelationshipInput] + createdAt: String! + updatedAt: String! } input Post_RelationMultiRelationToRelationshipInput { @@ -1365,6 +1703,8 @@ input mutationPostUpdateInput { relationHasManyField: [String] relationMultiRelationTo: PostUpdate_RelationMultiRelationToRelationshipInput relationMultiRelationToHasMany: [PostUpdate_RelationMultiRelationToHasManyRelationshipInput] + createdAt: String + updatedAt: String } input PostUpdate_RelationMultiRelationToRelationshipInput { @@ -1389,21 +1729,31 @@ enum PostUpdate_RelationMultiRelationToHasManyRelationshipInputRelationTo { input mutationRelationInput { name: String + createdAt: String! + updatedAt: String! } input mutationRelationUpdateInput { name: String + createdAt: String + updatedAt: String } input mutationDummyInput { name: String + createdAt: String! + updatedAt: String! } input mutationDummyUpdateInput { name: String + createdAt: String + updatedAt: String } input mutationUserInput { + createdAt: String! + updatedAt: String! email: String resetPasswordToken: String resetPasswordExpiration: String @@ -1413,6 +1763,8 @@ input mutationUserInput { } input mutationUserUpdateInput { + createdAt: String + updatedAt: String email: String resetPasswordToken: String resetPasswordExpiration: String