From 7720f452d3eb52cff42e243a1a59b17e95bb2450 Mon Sep 17 00:00:00 2001 From: Elliot DeNolf Date: Wed, 1 Feb 2023 15:17:48 -0500 Subject: [PATCH] ci: generate graphql schema in GH action --- .github/workflows/tests.yml | 3 + package.json | 1 + test/generateGraphQLSchema.ts | 19 + test/graphql-schema-gen/config.ts | 84 + .../generated-schema.graphql | 1444 +++++++++++++++++ 5 files changed, 1551 insertions(+) create mode 100644 test/generateGraphQLSchema.ts create mode 100644 test/graphql-schema-gen/config.ts create mode 100644 test/graphql-schema-gen/generated-schema.graphql diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a47f93d93e..b2adb432b3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -44,6 +44,9 @@ jobs: - name: Generate Payload Types run: yarn dev:generate-types fields + - name: Generate GraphQL schema file + run: yarn dev:generate-graphql-schema + - name: Install Playwright Browsers run: npx playwright install --with-deps - name: E2E Tests diff --git a/package.json b/package.json index 251cd92801..97fb7bac11 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "build:watch": "nodemon --watch 'src/**' --ext 'ts,tsx' --exec \"yarn build:tsc\"", "dev": "nodemon", "dev:generate-types": "ts-node -T ./test/generateTypes.ts", + "dev:generate-graphql-schema": "cross-env PAYLOAD_CONFIG_PATH=test/graphql-schema-gen/config.ts ts-node -T ./src/bin/generateGraphQLSchema.ts", "pretest": "yarn build", "test": "yarn test:int && yarn test:components && yarn test:e2e", "test:int": "cross-env DISABLE_LOGGING=true jest --forceExit --detectOpenHandles", diff --git a/test/generateGraphQLSchema.ts b/test/generateGraphQLSchema.ts new file mode 100644 index 0000000000..4ede12af24 --- /dev/null +++ b/test/generateGraphQLSchema.ts @@ -0,0 +1,19 @@ +import path from 'path'; +import fs from 'fs'; +import { generateGraphQLSchema } from '../src/bin/generateGraphQLSchema'; + +const [testConfigDir] = process.argv.slice(2); + +const testDir = path.resolve(__dirname, testConfigDir); +setPaths(testDir); +generateGraphQLSchema(); + +// Set config path and TS output path using test dir +function setPaths(dir) { + const configPath = path.resolve(dir, 'config.ts'); + if (fs.existsSync(configPath)) { + process.env.PAYLOAD_CONFIG_PATH = configPath; + return true; + } + return false; +} diff --git a/test/graphql-schema-gen/config.ts b/test/graphql-schema-gen/config.ts new file mode 100644 index 0000000000..f86d80bde7 --- /dev/null +++ b/test/graphql-schema-gen/config.ts @@ -0,0 +1,84 @@ +import path from 'path'; +import type { CollectionConfig } from '../../src/collections/config/types'; +import { buildConfig } from '../buildConfig'; + +export interface Relation { + id: string; + name: string; +} + +const openAccess = { + create: () => true, + read: () => true, + update: () => true, + delete: () => true, +}; + +const collectionWithName = (collectionSlug: string): CollectionConfig => { + return { + slug: collectionSlug, + access: openAccess, + fields: [ + { + name: 'name', + type: 'text', + }, + ], + }; +}; + +export const slug = 'posts'; +export const relationSlug = 'relation'; +export default buildConfig({ + graphQL: { + schemaOutputFile: path.resolve(__dirname, 'generated-schema.graphql'), + }, + collections: [ + { + slug, + access: openAccess, + fields: [ + { + name: 'title', + type: 'text', + }, + { + name: 'description', + type: 'text', + }, + { + name: 'number', + type: 'number', + }, + // Relationship + { + name: 'relationField', + type: 'relationship', + relationTo: relationSlug, + }, + // Relation hasMany + { + name: 'relationHasManyField', + type: 'relationship', + relationTo: relationSlug, + hasMany: true, + }, + // Relation multiple relationTo + { + name: 'relationMultiRelationTo', + type: 'relationship', + relationTo: [relationSlug, 'dummy'], + }, + // Relation multiple relationTo hasMany + { + name: 'relationMultiRelationToHasMany', + type: 'relationship', + relationTo: [relationSlug, 'dummy'], + hasMany: true, + }, + ], + }, + collectionWithName(relationSlug), + collectionWithName('dummy'), + ], +}); diff --git a/test/graphql-schema-gen/generated-schema.graphql b/test/graphql-schema-gen/generated-schema.graphql new file mode 100644 index 0000000000..0f3dbaa17d --- /dev/null +++ b/test/graphql-schema-gen/generated-schema.graphql @@ -0,0 +1,1444 @@ +type Query { + Post(id: String!, draft: Boolean): Post + Posts(where: Post_where, draft: Boolean, page: Int, limit: Int, sort: String): Posts + docAccessPost(id: String!): postsDocAccess + Relation(id: String!, draft: Boolean): Relation + Relations(where: Relation_where, draft: Boolean, page: Int, limit: Int, sort: String): Relations + docAccessRelation(id: String!): relationDocAccess + Dummy(id: String!, draft: Boolean): Dummy + Dummies(where: Dummy_where, draft: Boolean, page: Int, limit: Int, sort: String): Dummies + docAccessDummy(id: String!): dummyDocAccess + User(id: String!, draft: Boolean): User + Users(where: User_where, draft: Boolean, page: Int, limit: Int, sort: String): Users + docAccessUser(id: String!): usersDocAccess + meUser: usersMe + initializedUser: Boolean + Preference(key: String): Preference + Access: Access +} + +type Post { + id: String + createdAt: DateTime! + updatedAt: DateTime! + title: String + description: String + number: Float + relationField: Relation + relationHasManyField: [Relation!] + relationMultiRelationTo: Post_RelationMultiRelationTo_Relationship + relationMultiRelationToHasMany: [Post_RelationMultiRelationToHasMany_Relationship!] +} + +""" +A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. +""" +scalar DateTime + +type Relation { + id: String + createdAt: DateTime! + updatedAt: DateTime! + name: String +} + +type Post_RelationMultiRelationTo_Relationship { + relationTo: Post_RelationMultiRelationTo_RelationTo + value: Post_RelationMultiRelationTo +} + +enum Post_RelationMultiRelationTo_RelationTo { + relation + dummy +} + +union Post_RelationMultiRelationTo = Relation | Dummy + +type Dummy { + id: String + createdAt: DateTime! + updatedAt: DateTime! + name: String +} + +type Post_RelationMultiRelationToHasMany_Relationship { + relationTo: Post_RelationMultiRelationToHasMany_RelationTo + value: Post_RelationMultiRelationToHasMany +} + +enum Post_RelationMultiRelationToHasMany_RelationTo { + relation + dummy +} + +union Post_RelationMultiRelationToHasMany = Relation | Dummy + +type Posts { + docs: [Post] + totalDocs: Int + offset: Int + limit: Int + totalPages: Int + page: Int + pagingCounter: Int + hasPrevPage: Boolean + hasNextPage: Boolean + prevPage: Int + nextPage: Int +} + +input Post_where { + title: Post_title_operator + description: Post_description_operator + number: Post_number_operator + relationField: Post_relationField_operator + relationHasManyField: Post_relationHasManyField_operator + relationMultiRelationTo: Post_relationMultiRelationTo_Relation + relationMultiRelationToHasMany: Post_relationMultiRelationToHasMany_Relation + id: Post_id_operator + createdAt: Post_createdAt_operator + updatedAt: Post_updatedAt_operator + OR: [Post_where_or] + AND: [Post_where_and] +} + +input Post_title_operator { + equals: String + not_equals: String + like: String + contains: String + in: [String] + not_in: [String] + all: [String] + exists: Boolean +} + +input Post_description_operator { + equals: String + not_equals: String + like: String + contains: String + in: [String] + not_in: [String] + all: [String] + exists: Boolean +} + +input Post_number_operator { + equals: Float + not_equals: Float + greater_than_equal: Float + greater_than: Float + less_than_equal: Float + less_than: Float + exists: Boolean +} + +input Post_relationField_operator { + equals: String + not_equals: String + in: [String] + not_in: [String] + all: [String] + exists: Boolean +} + +input Post_relationHasManyField_operator { + equals: String + not_equals: String + in: [String] + not_in: [String] + all: [String] + exists: Boolean +} + +input Post_relationMultiRelationTo_Relation { + relationTo: Post_relationMultiRelationTo_Relation_RelationTo + value: String +} + +enum Post_relationMultiRelationTo_Relation_RelationTo { + relation + dummy +} + +input Post_relationMultiRelationToHasMany_Relation { + relationTo: Post_relationMultiRelationToHasMany_Relation_RelationTo + value: String +} + +enum Post_relationMultiRelationToHasMany_Relation_RelationTo { + relation + 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 + greater_than_equal: DateTime + greater_than: DateTime + less_than_equal: DateTime + less_than: DateTime + like: DateTime + exists: Boolean +} + +input Post_updatedAt_operator { + equals: DateTime + not_equals: DateTime + greater_than_equal: DateTime + greater_than: DateTime + less_than_equal: DateTime + less_than: DateTime + like: DateTime + exists: Boolean +} + +input Post_where_or { + title: Post_title_operator + description: Post_description_operator + number: Post_number_operator + relationField: Post_relationField_operator + relationHasManyField: Post_relationHasManyField_operator + relationMultiRelationTo: Post_relationMultiRelationTo_Relation + relationMultiRelationToHasMany: Post_relationMultiRelationToHasMany_Relation + id: Post_id_operator + createdAt: Post_createdAt_operator + updatedAt: Post_updatedAt_operator +} + +input Post_where_and { + title: Post_title_operator + description: Post_description_operator + number: Post_number_operator + relationField: Post_relationField_operator + relationHasManyField: Post_relationHasManyField_operator + relationMultiRelationTo: Post_relationMultiRelationTo_Relation + relationMultiRelationToHasMany: Post_relationMultiRelationToHasMany_Relation + id: Post_id_operator + createdAt: Post_createdAt_operator + updatedAt: Post_updatedAt_operator +} + +type postsDocAccess { + fields: PostsDocAccessFields + create: PostsCreateDocAccess + read: PostsReadDocAccess + update: PostsUpdateDocAccess + delete: PostsDeleteDocAccess +} + +type PostsDocAccessFields { + title: PostsDocAccessFields_title + description: PostsDocAccessFields_description + number: PostsDocAccessFields_number + relationField: PostsDocAccessFields_relationField + relationHasManyField: PostsDocAccessFields_relationHasManyField + relationMultiRelationTo: PostsDocAccessFields_relationMultiRelationTo + relationMultiRelationToHasMany: PostsDocAccessFields_relationMultiRelationToHasMany +} + +type PostsDocAccessFields_title { + create: PostsDocAccessFields_title_Create + read: PostsDocAccessFields_title_Read + update: PostsDocAccessFields_title_Update + delete: PostsDocAccessFields_title_Delete +} + +type PostsDocAccessFields_title_Create { + permission: Boolean! +} + +type PostsDocAccessFields_title_Read { + permission: Boolean! +} + +type PostsDocAccessFields_title_Update { + permission: Boolean! +} + +type PostsDocAccessFields_title_Delete { + permission: Boolean! +} + +type PostsDocAccessFields_description { + create: PostsDocAccessFields_description_Create + read: PostsDocAccessFields_description_Read + update: PostsDocAccessFields_description_Update + delete: PostsDocAccessFields_description_Delete +} + +type PostsDocAccessFields_description_Create { + permission: Boolean! +} + +type PostsDocAccessFields_description_Read { + permission: Boolean! +} + +type PostsDocAccessFields_description_Update { + permission: Boolean! +} + +type PostsDocAccessFields_description_Delete { + permission: Boolean! +} + +type PostsDocAccessFields_number { + create: PostsDocAccessFields_number_Create + read: PostsDocAccessFields_number_Read + update: PostsDocAccessFields_number_Update + delete: PostsDocAccessFields_number_Delete +} + +type PostsDocAccessFields_number_Create { + permission: Boolean! +} + +type PostsDocAccessFields_number_Read { + permission: Boolean! +} + +type PostsDocAccessFields_number_Update { + permission: Boolean! +} + +type PostsDocAccessFields_number_Delete { + permission: Boolean! +} + +type PostsDocAccessFields_relationField { + create: PostsDocAccessFields_relationField_Create + read: PostsDocAccessFields_relationField_Read + update: PostsDocAccessFields_relationField_Update + delete: PostsDocAccessFields_relationField_Delete +} + +type PostsDocAccessFields_relationField_Create { + permission: Boolean! +} + +type PostsDocAccessFields_relationField_Read { + permission: Boolean! +} + +type PostsDocAccessFields_relationField_Update { + permission: Boolean! +} + +type PostsDocAccessFields_relationField_Delete { + permission: Boolean! +} + +type PostsDocAccessFields_relationHasManyField { + create: PostsDocAccessFields_relationHasManyField_Create + read: PostsDocAccessFields_relationHasManyField_Read + update: PostsDocAccessFields_relationHasManyField_Update + delete: PostsDocAccessFields_relationHasManyField_Delete +} + +type PostsDocAccessFields_relationHasManyField_Create { + permission: Boolean! +} + +type PostsDocAccessFields_relationHasManyField_Read { + permission: Boolean! +} + +type PostsDocAccessFields_relationHasManyField_Update { + permission: Boolean! +} + +type PostsDocAccessFields_relationHasManyField_Delete { + permission: Boolean! +} + +type PostsDocAccessFields_relationMultiRelationTo { + create: PostsDocAccessFields_relationMultiRelationTo_Create + read: PostsDocAccessFields_relationMultiRelationTo_Read + update: PostsDocAccessFields_relationMultiRelationTo_Update + delete: PostsDocAccessFields_relationMultiRelationTo_Delete +} + +type PostsDocAccessFields_relationMultiRelationTo_Create { + permission: Boolean! +} + +type PostsDocAccessFields_relationMultiRelationTo_Read { + permission: Boolean! +} + +type PostsDocAccessFields_relationMultiRelationTo_Update { + permission: Boolean! +} + +type PostsDocAccessFields_relationMultiRelationTo_Delete { + permission: Boolean! +} + +type PostsDocAccessFields_relationMultiRelationToHasMany { + create: PostsDocAccessFields_relationMultiRelationToHasMany_Create + read: PostsDocAccessFields_relationMultiRelationToHasMany_Read + update: PostsDocAccessFields_relationMultiRelationToHasMany_Update + delete: PostsDocAccessFields_relationMultiRelationToHasMany_Delete +} + +type PostsDocAccessFields_relationMultiRelationToHasMany_Create { + permission: Boolean! +} + +type PostsDocAccessFields_relationMultiRelationToHasMany_Read { + permission: Boolean! +} + +type PostsDocAccessFields_relationMultiRelationToHasMany_Update { + permission: Boolean! +} + +type PostsDocAccessFields_relationMultiRelationToHasMany_Delete { + permission: Boolean! +} + +type PostsCreateDocAccess { + permission: Boolean! + where: JSONObject +} + +""" +The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). +""" +scalar JSONObject + +type PostsReadDocAccess { + permission: Boolean! + where: JSONObject +} + +type PostsUpdateDocAccess { + permission: Boolean! + where: JSONObject +} + +type PostsDeleteDocAccess { + permission: Boolean! + where: JSONObject +} + +type Relations { + docs: [Relation] + totalDocs: Int + offset: Int + limit: Int + totalPages: Int + page: Int + pagingCounter: Int + hasPrevPage: Boolean + hasNextPage: Boolean + prevPage: Int + nextPage: Int +} + +input Relation_where { + name: Relation_name_operator + id: Relation_id_operator + createdAt: Relation_createdAt_operator + updatedAt: Relation_updatedAt_operator + OR: [Relation_where_or] + AND: [Relation_where_and] +} + +input Relation_name_operator { + equals: String + not_equals: String + like: String + contains: String + in: [String] + not_in: [String] + all: [String] + 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 + greater_than_equal: DateTime + greater_than: DateTime + less_than_equal: DateTime + less_than: DateTime + like: DateTime + exists: Boolean +} + +input Relation_updatedAt_operator { + equals: DateTime + not_equals: DateTime + greater_than_equal: DateTime + greater_than: DateTime + less_than_equal: DateTime + less_than: DateTime + like: DateTime + exists: Boolean +} + +input Relation_where_or { + name: Relation_name_operator + id: Relation_id_operator + createdAt: Relation_createdAt_operator + updatedAt: Relation_updatedAt_operator +} + +input Relation_where_and { + name: Relation_name_operator + id: Relation_id_operator + createdAt: Relation_createdAt_operator + updatedAt: Relation_updatedAt_operator +} + +type relationDocAccess { + fields: RelationDocAccessFields + create: RelationCreateDocAccess + read: RelationReadDocAccess + update: RelationUpdateDocAccess + delete: RelationDeleteDocAccess +} + +type RelationDocAccessFields { + name: RelationDocAccessFields_name +} + +type RelationDocAccessFields_name { + create: RelationDocAccessFields_name_Create + read: RelationDocAccessFields_name_Read + update: RelationDocAccessFields_name_Update + delete: RelationDocAccessFields_name_Delete +} + +type RelationDocAccessFields_name_Create { + permission: Boolean! +} + +type RelationDocAccessFields_name_Read { + permission: Boolean! +} + +type RelationDocAccessFields_name_Update { + permission: Boolean! +} + +type RelationDocAccessFields_name_Delete { + permission: Boolean! +} + +type RelationCreateDocAccess { + permission: Boolean! + where: JSONObject +} + +type RelationReadDocAccess { + permission: Boolean! + where: JSONObject +} + +type RelationUpdateDocAccess { + permission: Boolean! + where: JSONObject +} + +type RelationDeleteDocAccess { + permission: Boolean! + where: JSONObject +} + +type Dummies { + docs: [Dummy] + totalDocs: Int + offset: Int + limit: Int + totalPages: Int + page: Int + pagingCounter: Int + hasPrevPage: Boolean + hasNextPage: Boolean + prevPage: Int + nextPage: Int +} + +input Dummy_where { + name: Dummy_name_operator + id: Dummy_id_operator + createdAt: Dummy_createdAt_operator + updatedAt: Dummy_updatedAt_operator + OR: [Dummy_where_or] + AND: [Dummy_where_and] +} + +input Dummy_name_operator { + equals: String + not_equals: String + like: String + contains: String + in: [String] + not_in: [String] + all: [String] + 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 + greater_than_equal: DateTime + greater_than: DateTime + less_than_equal: DateTime + less_than: DateTime + like: DateTime + exists: Boolean +} + +input Dummy_updatedAt_operator { + equals: DateTime + not_equals: DateTime + greater_than_equal: DateTime + greater_than: DateTime + less_than_equal: DateTime + less_than: DateTime + like: DateTime + exists: Boolean +} + +input Dummy_where_or { + name: Dummy_name_operator + id: Dummy_id_operator + createdAt: Dummy_createdAt_operator + updatedAt: Dummy_updatedAt_operator +} + +input Dummy_where_and { + name: Dummy_name_operator + id: Dummy_id_operator + createdAt: Dummy_createdAt_operator + updatedAt: Dummy_updatedAt_operator +} + +type dummyDocAccess { + fields: DummyDocAccessFields + create: DummyCreateDocAccess + read: DummyReadDocAccess + update: DummyUpdateDocAccess + delete: DummyDeleteDocAccess +} + +type DummyDocAccessFields { + name: DummyDocAccessFields_name +} + +type DummyDocAccessFields_name { + create: DummyDocAccessFields_name_Create + read: DummyDocAccessFields_name_Read + update: DummyDocAccessFields_name_Update + delete: DummyDocAccessFields_name_Delete +} + +type DummyDocAccessFields_name_Create { + permission: Boolean! +} + +type DummyDocAccessFields_name_Read { + permission: Boolean! +} + +type DummyDocAccessFields_name_Update { + permission: Boolean! +} + +type DummyDocAccessFields_name_Delete { + permission: Boolean! +} + +type DummyCreateDocAccess { + permission: Boolean! + where: JSONObject +} + +type DummyReadDocAccess { + permission: Boolean! + where: JSONObject +} + +type DummyUpdateDocAccess { + permission: Boolean! + where: JSONObject +} + +type DummyDeleteDocAccess { + permission: Boolean! + where: JSONObject +} + +type User { + id: String + createdAt: DateTime! + updatedAt: DateTime! + email: EmailAddress + resetPasswordToken: String + resetPasswordExpiration: DateTime + loginAttempts: Float + lockUntil: DateTime + password: String! +} + +""" +A field whose value conforms to the standard internet email address format as specified in RFC822: https://www.w3.org/Protocols/rfc822/. +""" +scalar EmailAddress @specifiedBy(url: "https://www.w3.org/Protocols/rfc822/") + +type Users { + docs: [User] + totalDocs: Int + offset: Int + limit: Int + totalPages: Int + page: Int + pagingCounter: Int + hasPrevPage: Boolean + hasNextPage: Boolean + prevPage: Int + nextPage: Int +} + +input User_where { + email: User_email_operator + id: User_id_operator + createdAt: User_createdAt_operator + updatedAt: User_updatedAt_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 + greater_than_equal: DateTime + greater_than: DateTime + less_than_equal: DateTime + less_than: DateTime + like: DateTime + exists: Boolean +} + +input User_updatedAt_operator { + equals: DateTime + not_equals: DateTime + greater_than_equal: DateTime + greater_than: DateTime + less_than_equal: DateTime + less_than: DateTime + like: DateTime + exists: Boolean +} + +input User_where_or { + email: User_email_operator + id: User_id_operator + createdAt: User_createdAt_operator + updatedAt: User_updatedAt_operator +} + +input User_where_and { + email: User_email_operator + id: User_id_operator + createdAt: User_createdAt_operator + updatedAt: User_updatedAt_operator +} + +type usersDocAccess { + fields: UsersDocAccessFields + create: UsersCreateDocAccess + read: UsersReadDocAccess + update: UsersUpdateDocAccess + delete: UsersDeleteDocAccess + unlock: UsersUnlockDocAccess +} + +type UsersDocAccessFields { + email: UsersDocAccessFields_email + password: UsersDocAccessFields_password +} + +type UsersDocAccessFields_email { + create: UsersDocAccessFields_email_Create + read: UsersDocAccessFields_email_Read + update: UsersDocAccessFields_email_Update + delete: UsersDocAccessFields_email_Delete +} + +type UsersDocAccessFields_email_Create { + permission: Boolean! +} + +type UsersDocAccessFields_email_Read { + permission: Boolean! +} + +type UsersDocAccessFields_email_Update { + permission: Boolean! +} + +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 +} + +type UsersReadDocAccess { + permission: Boolean! + where: JSONObject +} + +type UsersUpdateDocAccess { + permission: Boolean! + where: JSONObject +} + +type UsersDeleteDocAccess { + permission: Boolean! + where: JSONObject +} + +type UsersUnlockDocAccess { + permission: Boolean! + where: JSONObject +} + +type usersMe { + token: String + user: User + exp: Int + collection: String +} + +type Preference { + key: String! + value: JSON + createdAt: DateTime! + updatedAt: DateTime! +} + +type Access { + canAccessAdmin: Boolean! + posts: postsAccess + relation: relationAccess + dummy: dummyAccess + users: usersAccess +} + +type postsAccess { + fields: PostsFields + create: PostsCreateAccess + read: PostsReadAccess + update: PostsUpdateAccess + delete: PostsDeleteAccess +} + +type PostsFields { + title: PostsFields_title + description: PostsFields_description + number: PostsFields_number + relationField: PostsFields_relationField + relationHasManyField: PostsFields_relationHasManyField + relationMultiRelationTo: PostsFields_relationMultiRelationTo + relationMultiRelationToHasMany: PostsFields_relationMultiRelationToHasMany +} + +type PostsFields_title { + create: PostsFields_title_Create + read: PostsFields_title_Read + update: PostsFields_title_Update + delete: PostsFields_title_Delete +} + +type PostsFields_title_Create { + permission: Boolean! +} + +type PostsFields_title_Read { + permission: Boolean! +} + +type PostsFields_title_Update { + permission: Boolean! +} + +type PostsFields_title_Delete { + permission: Boolean! +} + +type PostsFields_description { + create: PostsFields_description_Create + read: PostsFields_description_Read + update: PostsFields_description_Update + delete: PostsFields_description_Delete +} + +type PostsFields_description_Create { + permission: Boolean! +} + +type PostsFields_description_Read { + permission: Boolean! +} + +type PostsFields_description_Update { + permission: Boolean! +} + +type PostsFields_description_Delete { + permission: Boolean! +} + +type PostsFields_number { + create: PostsFields_number_Create + read: PostsFields_number_Read + update: PostsFields_number_Update + delete: PostsFields_number_Delete +} + +type PostsFields_number_Create { + permission: Boolean! +} + +type PostsFields_number_Read { + permission: Boolean! +} + +type PostsFields_number_Update { + permission: Boolean! +} + +type PostsFields_number_Delete { + permission: Boolean! +} + +type PostsFields_relationField { + create: PostsFields_relationField_Create + read: PostsFields_relationField_Read + update: PostsFields_relationField_Update + delete: PostsFields_relationField_Delete +} + +type PostsFields_relationField_Create { + permission: Boolean! +} + +type PostsFields_relationField_Read { + permission: Boolean! +} + +type PostsFields_relationField_Update { + permission: Boolean! +} + +type PostsFields_relationField_Delete { + permission: Boolean! +} + +type PostsFields_relationHasManyField { + create: PostsFields_relationHasManyField_Create + read: PostsFields_relationHasManyField_Read + update: PostsFields_relationHasManyField_Update + delete: PostsFields_relationHasManyField_Delete +} + +type PostsFields_relationHasManyField_Create { + permission: Boolean! +} + +type PostsFields_relationHasManyField_Read { + permission: Boolean! +} + +type PostsFields_relationHasManyField_Update { + permission: Boolean! +} + +type PostsFields_relationHasManyField_Delete { + permission: Boolean! +} + +type PostsFields_relationMultiRelationTo { + create: PostsFields_relationMultiRelationTo_Create + read: PostsFields_relationMultiRelationTo_Read + update: PostsFields_relationMultiRelationTo_Update + delete: PostsFields_relationMultiRelationTo_Delete +} + +type PostsFields_relationMultiRelationTo_Create { + permission: Boolean! +} + +type PostsFields_relationMultiRelationTo_Read { + permission: Boolean! +} + +type PostsFields_relationMultiRelationTo_Update { + permission: Boolean! +} + +type PostsFields_relationMultiRelationTo_Delete { + permission: Boolean! +} + +type PostsFields_relationMultiRelationToHasMany { + create: PostsFields_relationMultiRelationToHasMany_Create + read: PostsFields_relationMultiRelationToHasMany_Read + update: PostsFields_relationMultiRelationToHasMany_Update + delete: PostsFields_relationMultiRelationToHasMany_Delete +} + +type PostsFields_relationMultiRelationToHasMany_Create { + permission: Boolean! +} + +type PostsFields_relationMultiRelationToHasMany_Read { + permission: Boolean! +} + +type PostsFields_relationMultiRelationToHasMany_Update { + permission: Boolean! +} + +type PostsFields_relationMultiRelationToHasMany_Delete { + permission: Boolean! +} + +type PostsCreateAccess { + permission: Boolean! + where: JSONObject +} + +type PostsReadAccess { + permission: Boolean! + where: JSONObject +} + +type PostsUpdateAccess { + permission: Boolean! + where: JSONObject +} + +type PostsDeleteAccess { + permission: Boolean! + where: JSONObject +} + +type relationAccess { + fields: RelationFields + create: RelationCreateAccess + read: RelationReadAccess + update: RelationUpdateAccess + delete: RelationDeleteAccess +} + +type RelationFields { + name: RelationFields_name +} + +type RelationFields_name { + create: RelationFields_name_Create + read: RelationFields_name_Read + update: RelationFields_name_Update + delete: RelationFields_name_Delete +} + +type RelationFields_name_Create { + permission: Boolean! +} + +type RelationFields_name_Read { + permission: Boolean! +} + +type RelationFields_name_Update { + permission: Boolean! +} + +type RelationFields_name_Delete { + permission: Boolean! +} + +type RelationCreateAccess { + permission: Boolean! + where: JSONObject +} + +type RelationReadAccess { + permission: Boolean! + where: JSONObject +} + +type RelationUpdateAccess { + permission: Boolean! + where: JSONObject +} + +type RelationDeleteAccess { + permission: Boolean! + where: JSONObject +} + +type dummyAccess { + fields: DummyFields + create: DummyCreateAccess + read: DummyReadAccess + update: DummyUpdateAccess + delete: DummyDeleteAccess +} + +type DummyFields { + name: DummyFields_name +} + +type DummyFields_name { + create: DummyFields_name_Create + read: DummyFields_name_Read + update: DummyFields_name_Update + delete: DummyFields_name_Delete +} + +type DummyFields_name_Create { + permission: Boolean! +} + +type DummyFields_name_Read { + permission: Boolean! +} + +type DummyFields_name_Update { + permission: Boolean! +} + +type DummyFields_name_Delete { + permission: Boolean! +} + +type DummyCreateAccess { + permission: Boolean! + where: JSONObject +} + +type DummyReadAccess { + permission: Boolean! + where: JSONObject +} + +type DummyUpdateAccess { + permission: Boolean! + where: JSONObject +} + +type DummyDeleteAccess { + permission: Boolean! + where: JSONObject +} + +type usersAccess { + fields: UsersFields + create: UsersCreateAccess + read: UsersReadAccess + update: UsersUpdateAccess + delete: UsersDeleteAccess + unlock: UsersUnlockAccess +} + +type UsersFields { + email: UsersFields_email + password: UsersFields_password +} + +type UsersFields_email { + create: UsersFields_email_Create + read: UsersFields_email_Read + update: UsersFields_email_Update + delete: UsersFields_email_Delete +} + +type UsersFields_email_Create { + permission: Boolean! +} + +type UsersFields_email_Read { + permission: Boolean! +} + +type UsersFields_email_Update { + permission: Boolean! +} + +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 +} + +type UsersReadAccess { + permission: Boolean! + where: JSONObject +} + +type UsersUpdateAccess { + permission: Boolean! + where: JSONObject +} + +type UsersDeleteAccess { + permission: Boolean! + where: JSONObject +} + +type UsersUnlockAccess { + permission: Boolean! + where: JSONObject +} + +type Mutation { + createPost(data: mutationPostInput!, draft: Boolean): Post + updatePost(id: String!, data: mutationPostUpdateInput!, draft: Boolean, autosave: Boolean): Post + deletePost(id: String!): Post + createRelation(data: mutationRelationInput!, draft: Boolean): Relation + updateRelation(id: String!, data: mutationRelationUpdateInput!, draft: Boolean, autosave: Boolean): Relation + deleteRelation(id: String!): Relation + createDummy(data: mutationDummyInput!, draft: Boolean): Dummy + updateDummy(id: String!, data: mutationDummyUpdateInput!, draft: Boolean, autosave: Boolean): Dummy + deleteDummy(id: String!): Dummy + createUser(data: mutationUserInput!, draft: Boolean): User + updateUser(id: String!, data: mutationUserUpdateInput!, draft: Boolean, autosave: Boolean): User + deleteUser(id: String!): User + refreshTokenUser(token: String): usersRefreshedUser + logoutUser: String + unlockUser(email: String!): Boolean! + loginUser(email: String, password: String): usersLoginResult + forgotPasswordUser(email: String!, disableEmail: Boolean, expiration: Int): Boolean! + resetPasswordUser(token: String, password: String): usersResetPassword + verifyEmailUser(token: String): Boolean + updatePreference(key: String!, value: JSON): Preference + deletePreference(key: String!): Preference +} + +input mutationPostInput { + title: String + description: String + number: Float + relationField: String + relationHasManyField: [String] + relationMultiRelationTo: Post_RelationMultiRelationToRelationshipInput + relationMultiRelationToHasMany: [Post_RelationMultiRelationToHasManyRelationshipInput] +} + +input Post_RelationMultiRelationToRelationshipInput { + relationTo: Post_RelationMultiRelationToRelationshipInputRelationTo + value: JSON +} + +enum Post_RelationMultiRelationToRelationshipInputRelationTo { + relation + dummy +} + +input Post_RelationMultiRelationToHasManyRelationshipInput { + relationTo: Post_RelationMultiRelationToHasManyRelationshipInputRelationTo + value: JSON +} + +enum Post_RelationMultiRelationToHasManyRelationshipInputRelationTo { + relation + dummy +} + +input mutationPostUpdateInput { + title: String + description: String + number: Float + relationField: String + relationHasManyField: [String] + relationMultiRelationTo: PostUpdate_RelationMultiRelationToRelationshipInput + relationMultiRelationToHasMany: [PostUpdate_RelationMultiRelationToHasManyRelationshipInput] +} + +input PostUpdate_RelationMultiRelationToRelationshipInput { + relationTo: PostUpdate_RelationMultiRelationToRelationshipInputRelationTo + value: JSON +} + +enum PostUpdate_RelationMultiRelationToRelationshipInputRelationTo { + relation + dummy +} + +input PostUpdate_RelationMultiRelationToHasManyRelationshipInput { + relationTo: PostUpdate_RelationMultiRelationToHasManyRelationshipInputRelationTo + value: JSON +} + +enum PostUpdate_RelationMultiRelationToHasManyRelationshipInputRelationTo { + relation + dummy +} + +input mutationRelationInput { + name: String +} + +input mutationRelationUpdateInput { + name: String +} + +input mutationDummyInput { + name: String +} + +input mutationDummyUpdateInput { + name: String +} + +input mutationUserInput { + email: String + resetPasswordToken: String + resetPasswordExpiration: String + loginAttempts: Float + lockUntil: String + password: String! +} + +input mutationUserUpdateInput { + email: String + resetPasswordToken: String + resetPasswordExpiration: String + loginAttempts: Float + lockUntil: String + password: String +} + +type usersRefreshedUser { + user: usersJWT + refreshedToken: String + exp: Int +} + +type usersJWT { + email: EmailAddress! + collection: String! +} + +type usersLoginResult { + token: String + user: User + exp: Int +} + +type usersResetPassword { + token: String + user: User +} \ No newline at end of file