diff --git a/.vscode/launch.json b/.vscode/launch.json index 46c943165..79b2ff826 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -269,6 +269,27 @@ "outputCapture": "std", "request": "launch", "type": "node-terminal" + }, + { + "name": "Debug GraphQL Schema Generation", + "type": "node", + "request": "launch", + "program": "${workspaceFolder}/test/generateGraphQLSchema.ts", + "args": ["graphql"], + "cwd": "${workspaceFolder}", + "env": { + "NODE_OPTIONS": "--no-deprecation --no-experimental-strip-types" + }, + "runtimeArgs": [ + "--no-deprecation", + "--no-experimental-strip-types", + "--import", + "@swc-node/register/esm-register" + ], + "console": "integratedTerminal", + "outputCapture": "std", + "sourceMaps": true, + "skipFiles": ["/**"] } ], // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 diff --git a/packages/graphql/src/schema/buildPoliciesType.ts b/packages/graphql/src/schema/buildPoliciesType.ts index 0bbb9d0d1..a94a51916 100644 --- a/packages/graphql/src/schema/buildPoliciesType.ts +++ b/packages/graphql/src/schema/buildPoliciesType.ts @@ -69,7 +69,7 @@ const buildFields = (label, fieldsToBuild) => } } - if (!field.name && field.fields) { + if (!field.name && field.fields && field.fields.length) { const subFields = buildFields(label, field.fields) return { @@ -81,6 +81,18 @@ const buildFields = (label, fieldsToBuild) => if (field.type === 'tabs') { return field.tabs.reduce( (fieldsWithTabFields, tab) => { + if ('name' in tab) { + if (tab.fields.length) { + const tabName = formatName(tab.name) + fieldsWithTabFields[tabName] = { + type: new GraphQLObjectType({ + name: `${label}_${tabName}`, + fields: buildFields(`${label}_${tabName}`, tab.fields), + }), + } + } + return fieldsWithTabFields + } return { ...fieldsWithTabFields, ...buildFields(label, tab.fields), diff --git a/packages/graphql/src/schema/recursivelyBuildNestedPaths.ts b/packages/graphql/src/schema/recursivelyBuildNestedPaths.ts index 3415d2381..f33e93fc2 100644 --- a/packages/graphql/src/schema/recursivelyBuildNestedPaths.ts +++ b/packages/graphql/src/schema/recursivelyBuildNestedPaths.ts @@ -22,7 +22,14 @@ export const recursivelyBuildNestedPaths = ({ field, nestedFieldName2, parentNam ...recursivelyBuildNestedPaths({ field: { ...tab, - type: 'name' in tab ? 'group' : 'row', + ...('name' in tab + ? { + name: `${nestedFieldName ? `${nestedFieldName}__` : ''}${tab.name}`, + type: 'group', + } + : { + type: 'row', + }), }, nestedFieldName2: nestedFieldName, parentName, diff --git a/test/graphql/schema.graphql b/test/graphql/schema.graphql index b4a7185f1..ae1f97bc4 100644 --- a/test/graphql/schema.graphql +++ b/test/graphql/schema.graphql @@ -1,21 +1,21 @@ type Query { - Post(id: String!, draft: Boolean): Post - Posts(draft: Boolean, where: Post_where, limit: Int, page: Int, pagination: Boolean, sort: String): Posts - countPosts(draft: Boolean, where: Post_where): countPosts + Post(id: String!, draft: Boolean, trash: Boolean): Post + Posts(draft: Boolean, where: Post_where, limit: Int, page: Int, pagination: Boolean, sort: String, trash: Boolean): Posts + countPosts(draft: Boolean, trash: Boolean, where: Post_where): countPosts docAccessPost(id: String!): postsDocAccess - User(id: String!, draft: Boolean): User - Users(draft: Boolean, where: User_where, limit: Int, page: Int, pagination: Boolean, sort: String): Users - countUsers(draft: Boolean, where: User_where): countUsers + User(id: String!, draft: Boolean, trash: Boolean): User + Users(draft: Boolean, where: User_where, limit: Int, page: Int, pagination: Boolean, sort: String, trash: Boolean): Users + countUsers(draft: Boolean, trash: Boolean, where: User_where): countUsers docAccessUser(id: String!): usersDocAccess meUser: usersMe initializedUser: Boolean - PayloadLockedDocument(id: String!, draft: Boolean): PayloadLockedDocument - PayloadLockedDocuments(draft: Boolean, where: PayloadLockedDocument_where, limit: Int, page: Int, pagination: Boolean, sort: String): PayloadLockedDocuments - countPayloadLockedDocuments(draft: Boolean, where: PayloadLockedDocument_where): countPayloadLockedDocuments + PayloadLockedDocument(id: String!, draft: Boolean, trash: Boolean): PayloadLockedDocument + PayloadLockedDocuments(draft: Boolean, where: PayloadLockedDocument_where, limit: Int, page: Int, pagination: Boolean, sort: String, trash: Boolean): PayloadLockedDocuments + countPayloadLockedDocuments(draft: Boolean, trash: Boolean, where: PayloadLockedDocument_where): countPayloadLockedDocuments docAccessPayloadLockedDocument(id: String!): payload_locked_documentsDocAccess - PayloadPreference(id: String!, draft: Boolean): PayloadPreference - PayloadPreferences(draft: Boolean, where: PayloadPreference_where, limit: Int, page: Int, pagination: Boolean, sort: String): PayloadPreferences - countPayloadPreferences(draft: Boolean, where: PayloadPreference_where): countPayloadPreferences + PayloadPreference(id: String!, draft: Boolean, trash: Boolean): PayloadPreference + PayloadPreferences(draft: Boolean, where: PayloadPreference_where, limit: Int, page: Int, pagination: Boolean, sort: String, trash: Boolean): PayloadPreferences + countPayloadPreferences(draft: Boolean, trash: Boolean, where: PayloadPreference_where): countPayloadPreferences docAccessPayloadPreference(id: String!): payload_preferencesDocAccess Access: Access } @@ -35,17 +35,17 @@ A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `dat scalar DateTime type Posts { - docs: [Post] - hasNextPage: Boolean - hasPrevPage: Boolean - limit: Int + docs: [Post!]! + hasNextPage: Boolean! + hasPrevPage: Boolean! + limit: Int! nextPage: Int offset: Int - page: Int - pagingCounter: Int + page: Int! + pagingCounter: Int! prevPage: Int - totalDocs: Int - totalPages: Int + totalDocs: Int! + totalPages: Int! } input Post_where { @@ -321,6 +321,7 @@ type User { hash: String loginAttempts: Float lockUntil: DateTime + sessions: [User_Sessions!] } """ @@ -328,24 +329,33 @@ A field whose value conforms to the standard internet email address format as sp """ scalar EmailAddress @specifiedBy(url: "https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address") +type User_Sessions { + id: String + createdAt: DateTime + expiresAt: DateTime +} + type Users { - docs: [User] - hasNextPage: Boolean - hasPrevPage: Boolean - limit: Int + docs: [User!]! + hasNextPage: Boolean! + hasPrevPage: Boolean! + limit: Int! nextPage: Int offset: Int - page: Int - pagingCounter: Int + page: Int! + pagingCounter: Int! prevPage: Int - totalDocs: Int - totalPages: Int + totalDocs: Int! + totalPages: Int! } input User_where { updatedAt: User_updatedAt_operator createdAt: User_createdAt_operator email: User_email_operator + sessions__id: User_sessions__id_operator + sessions__createdAt: User_sessions__createdAt_operator + sessions__expiresAt: User_sessions__expiresAt_operator id: User_id_operator AND: [User_where_and] OR: [User_where_or] @@ -383,6 +393,37 @@ input User_email_operator { all: [EmailAddress] } +input User_sessions__id_operator { + equals: String + not_equals: String + like: String + contains: String + in: [String] + not_in: [String] + all: [String] +} + +input User_sessions__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_sessions__expiresAt_operator { + equals: DateTime + not_equals: DateTime + greater_than_equal: DateTime + greater_than: DateTime + less_than_equal: DateTime + less_than: DateTime + like: DateTime +} + input User_id_operator { equals: String not_equals: String @@ -398,6 +439,9 @@ input User_where_and { updatedAt: User_updatedAt_operator createdAt: User_createdAt_operator email: User_email_operator + sessions__id: User_sessions__id_operator + sessions__createdAt: User_sessions__createdAt_operator + sessions__expiresAt: User_sessions__expiresAt_operator id: User_id_operator AND: [User_where_and] OR: [User_where_or] @@ -407,6 +451,9 @@ input User_where_or { updatedAt: User_updatedAt_operator createdAt: User_createdAt_operator email: User_email_operator + sessions__id: User_sessions__id_operator + sessions__createdAt: User_sessions__createdAt_operator + sessions__expiresAt: User_sessions__expiresAt_operator id: User_id_operator AND: [User_where_and] OR: [User_where_or] @@ -429,6 +476,7 @@ type UsersDocAccessFields { updatedAt: UsersDocAccessFields_updatedAt createdAt: UsersDocAccessFields_createdAt email: UsersDocAccessFields_email + sessions: UsersDocAccessFields_sessions } type UsersDocAccessFields_updatedAt { @@ -500,6 +548,105 @@ type UsersDocAccessFields_email_Delete { permission: Boolean! } +type UsersDocAccessFields_sessions { + create: UsersDocAccessFields_sessions_Create + read: UsersDocAccessFields_sessions_Read + update: UsersDocAccessFields_sessions_Update + delete: UsersDocAccessFields_sessions_Delete + fields: UsersDocAccessFields_sessions_Fields +} + +type UsersDocAccessFields_sessions_Create { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_Read { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_Update { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_Delete { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_Fields { + id: UsersDocAccessFields_sessions_id + createdAt: UsersDocAccessFields_sessions_createdAt + expiresAt: UsersDocAccessFields_sessions_expiresAt +} + +type UsersDocAccessFields_sessions_id { + create: UsersDocAccessFields_sessions_id_Create + read: UsersDocAccessFields_sessions_id_Read + update: UsersDocAccessFields_sessions_id_Update + delete: UsersDocAccessFields_sessions_id_Delete +} + +type UsersDocAccessFields_sessions_id_Create { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_id_Read { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_id_Update { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_id_Delete { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_createdAt { + create: UsersDocAccessFields_sessions_createdAt_Create + read: UsersDocAccessFields_sessions_createdAt_Read + update: UsersDocAccessFields_sessions_createdAt_Update + delete: UsersDocAccessFields_sessions_createdAt_Delete +} + +type UsersDocAccessFields_sessions_createdAt_Create { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_createdAt_Read { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_createdAt_Update { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_createdAt_Delete { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_expiresAt { + create: UsersDocAccessFields_sessions_expiresAt_Create + read: UsersDocAccessFields_sessions_expiresAt_Read + update: UsersDocAccessFields_sessions_expiresAt_Update + delete: UsersDocAccessFields_sessions_expiresAt_Delete +} + +type UsersDocAccessFields_sessions_expiresAt_Create { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_expiresAt_Read { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_expiresAt_Update { + permission: Boolean! +} + +type UsersDocAccessFields_sessions_expiresAt_Delete { + permission: Boolean! +} + type UsersCreateDocAccess { permission: Boolean! where: JSONObject @@ -566,17 +713,17 @@ enum PayloadLockedDocument_User_RelationTo { union PayloadLockedDocument_User = User type PayloadLockedDocuments { - docs: [PayloadLockedDocument] - hasNextPage: Boolean - hasPrevPage: Boolean - limit: Int + docs: [PayloadLockedDocument!]! + hasNextPage: Boolean! + hasPrevPage: Boolean! + limit: Int! nextPage: Int offset: Int - page: Int - pagingCounter: Int + page: Int! + pagingCounter: Int! prevPage: Int - totalDocs: Int - totalPages: Int + totalDocs: Int! + totalPages: Int! } input PayloadLockedDocument_where { @@ -851,17 +998,17 @@ enum PayloadPreference_User_RelationTo { union PayloadPreference_User = User type PayloadPreferences { - docs: [PayloadPreference] - hasNextPage: Boolean - hasPrevPage: Boolean - limit: Int + docs: [PayloadPreference!]! + hasNextPage: Boolean! + hasPrevPage: Boolean! + limit: Int! nextPage: Int offset: Int - page: Int - pagingCounter: Int + page: Int! + pagingCounter: Int! prevPage: Int - totalDocs: Int - totalPages: Int + totalDocs: Int! + totalPages: Int! } input PayloadPreference_where { @@ -1287,6 +1434,7 @@ type UsersFields { updatedAt: UsersFields_updatedAt createdAt: UsersFields_createdAt email: UsersFields_email + sessions: UsersFields_sessions } type UsersFields_updatedAt { @@ -1358,6 +1506,105 @@ type UsersFields_email_Delete { permission: Boolean! } +type UsersFields_sessions { + create: UsersFields_sessions_Create + read: UsersFields_sessions_Read + update: UsersFields_sessions_Update + delete: UsersFields_sessions_Delete + fields: UsersFields_sessions_Fields +} + +type UsersFields_sessions_Create { + permission: Boolean! +} + +type UsersFields_sessions_Read { + permission: Boolean! +} + +type UsersFields_sessions_Update { + permission: Boolean! +} + +type UsersFields_sessions_Delete { + permission: Boolean! +} + +type UsersFields_sessions_Fields { + id: UsersFields_sessions_id + createdAt: UsersFields_sessions_createdAt + expiresAt: UsersFields_sessions_expiresAt +} + +type UsersFields_sessions_id { + create: UsersFields_sessions_id_Create + read: UsersFields_sessions_id_Read + update: UsersFields_sessions_id_Update + delete: UsersFields_sessions_id_Delete +} + +type UsersFields_sessions_id_Create { + permission: Boolean! +} + +type UsersFields_sessions_id_Read { + permission: Boolean! +} + +type UsersFields_sessions_id_Update { + permission: Boolean! +} + +type UsersFields_sessions_id_Delete { + permission: Boolean! +} + +type UsersFields_sessions_createdAt { + create: UsersFields_sessions_createdAt_Create + read: UsersFields_sessions_createdAt_Read + update: UsersFields_sessions_createdAt_Update + delete: UsersFields_sessions_createdAt_Delete +} + +type UsersFields_sessions_createdAt_Create { + permission: Boolean! +} + +type UsersFields_sessions_createdAt_Read { + permission: Boolean! +} + +type UsersFields_sessions_createdAt_Update { + permission: Boolean! +} + +type UsersFields_sessions_createdAt_Delete { + permission: Boolean! +} + +type UsersFields_sessions_expiresAt { + create: UsersFields_sessions_expiresAt_Create + read: UsersFields_sessions_expiresAt_Read + update: UsersFields_sessions_expiresAt_Update + delete: UsersFields_sessions_expiresAt_Delete +} + +type UsersFields_sessions_expiresAt_Create { + permission: Boolean! +} + +type UsersFields_sessions_expiresAt_Read { + permission: Boolean! +} + +type UsersFields_sessions_expiresAt_Update { + permission: Boolean! +} + +type UsersFields_sessions_expiresAt_Delete { + permission: Boolean! +} + type UsersCreateAccess { permission: Boolean! where: JSONObject @@ -1687,26 +1934,26 @@ type PayloadPreferencesDeleteAccess { type Mutation { createPost(data: mutationPostInput!, draft: Boolean): Post - updatePost(id: String!, autosave: Boolean, data: mutationPostUpdateInput!, draft: Boolean): Post - deletePost(id: String!): Post + updatePost(id: String!, autosave: Boolean, data: mutationPostUpdateInput!, draft: Boolean, trash: Boolean): Post + deletePost(id: String!, trash: Boolean): Post duplicatePost(id: String!, data: mutationPostInput!): Post createUser(data: mutationUserInput!, draft: Boolean): User - updateUser(id: String!, autosave: Boolean, data: mutationUserUpdateInput!, draft: Boolean): User - deleteUser(id: String!): User + updateUser(id: String!, autosave: Boolean, data: mutationUserUpdateInput!, draft: Boolean, trash: Boolean): User + deleteUser(id: String!, trash: Boolean): User refreshTokenUser: usersRefreshedUser - logoutUser: String + logoutUser(allSessions: Boolean): String unlockUser(email: String!): Boolean! loginUser(email: String!, password: String): usersLoginResult forgotPasswordUser(disableEmail: Boolean, expiration: Int, email: String!): Boolean! resetPasswordUser(password: String, token: String): usersResetPassword verifyEmailUser(token: String): Boolean createPayloadLockedDocument(data: mutationPayloadLockedDocumentInput!, draft: Boolean): PayloadLockedDocument - updatePayloadLockedDocument(id: String!, autosave: Boolean, data: mutationPayloadLockedDocumentUpdateInput!, draft: Boolean): PayloadLockedDocument - deletePayloadLockedDocument(id: String!): PayloadLockedDocument + updatePayloadLockedDocument(id: String!, autosave: Boolean, data: mutationPayloadLockedDocumentUpdateInput!, draft: Boolean, trash: Boolean): PayloadLockedDocument + deletePayloadLockedDocument(id: String!, trash: Boolean): PayloadLockedDocument duplicatePayloadLockedDocument(id: String!, data: mutationPayloadLockedDocumentInput!): PayloadLockedDocument createPayloadPreference(data: mutationPayloadPreferenceInput!, draft: Boolean): PayloadPreference - updatePayloadPreference(id: String!, autosave: Boolean, data: mutationPayloadPreferenceUpdateInput!, draft: Boolean): PayloadPreference - deletePayloadPreference(id: String!): PayloadPreference + updatePayloadPreference(id: String!, autosave: Boolean, data: mutationPayloadPreferenceUpdateInput!, draft: Boolean, trash: Boolean): PayloadPreference + deletePayloadPreference(id: String!, trash: Boolean): PayloadPreference duplicatePayloadPreference(id: String!, data: mutationPayloadPreferenceInput!): PayloadPreference } @@ -1736,9 +1983,16 @@ input mutationUserInput { hash: String loginAttempts: Float lockUntil: String + sessions: [mutationUser_SessionsInput] password: String! } +input mutationUser_SessionsInput { + id: String! + createdAt: String + expiresAt: String! +} + input mutationUserUpdateInput { updatedAt: String createdAt: String @@ -1749,9 +2003,16 @@ input mutationUserUpdateInput { hash: String loginAttempts: Float lockUntil: String + sessions: [mutationUserUpdate_SessionsInput] password: String } +input mutationUserUpdate_SessionsInput { + id: String! + createdAt: String + expiresAt: String! +} + type usersRefreshedUser { exp: Int refreshedToken: String