mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2026-02-06 01:46:05 +00:00
refactor(backend): lint graphql (#8473)
This commit is contained in:
parent
8136ec1aba
commit
524c4caf5e
@ -14,7 +14,6 @@ module.exports = {
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'plugin:promise/recommended',
|
||||
'plugin:security/recommended-legacy',
|
||||
'plugin:@eslint-community/eslint-comments/recommended',
|
||||
'prettier',
|
||||
],
|
||||
@ -175,6 +174,10 @@ module.exports = {
|
||||
'@eslint-community/eslint-comments/require-description': 'off',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.js', '*.cjs', '*.ts', '*.tsx'],
|
||||
extends: ['plugin:security/recommended-legacy'],
|
||||
},
|
||||
// only for ts files
|
||||
{
|
||||
files: ['*.ts', '*.tsx'],
|
||||
@ -228,5 +231,33 @@ module.exports = {
|
||||
files: ['*.json', '*.json5', '*.jsonc'],
|
||||
parser: 'jsonc-eslint-parser',
|
||||
},
|
||||
{
|
||||
files: ['*.graphql', '*.gql'],
|
||||
parser: '@graphql-eslint/eslint-plugin',
|
||||
plugins: ['@graphql-eslint'],
|
||||
extends: ['plugin:@graphql-eslint/schema-recommended'],
|
||||
rules: {
|
||||
'@graphql-eslint/description-style': ['error', { style: 'inline' }],
|
||||
'@graphql-eslint/require-description': 'off',
|
||||
'@graphql-eslint/naming-convention': 'off',
|
||||
'@graphql-eslint/strict-id-in-types': 'off',
|
||||
'@graphql-eslint/no-typename-prefix': 'off',
|
||||
// incompatible: `depends on a GraphQL validation rule "XXX" but it's not available in the "graphql" version you are using. Skipping…`
|
||||
'@graphql-eslint/known-directives': 'off',
|
||||
'@graphql-eslint/known-argument-names': 'off',
|
||||
'@graphql-eslint/known-type-names': 'off',
|
||||
'@graphql-eslint/lone-schema-definition': 'off',
|
||||
'@graphql-eslint/provided-required-arguments': 'off',
|
||||
'@graphql-eslint/unique-directive-names': 'off',
|
||||
'@graphql-eslint/unique-directive-names-per-location': 'off',
|
||||
'@graphql-eslint/unique-field-definition-names': 'off',
|
||||
'@graphql-eslint/unique-operation-types': 'off',
|
||||
'@graphql-eslint/unique-type-names': 'off',
|
||||
},
|
||||
parserOptions: {
|
||||
schema: './src/graphql/types/**/*.gql',
|
||||
assumeValid: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
"build": "tsc && tsc-alias && ./scripts/build.copy.files.sh",
|
||||
"dev": "nodemon --exec ts-node --require tsconfig-paths/register src/index.ts -e js,ts,gql",
|
||||
"dev:debug": "nodemon --exec node --inspect=0.0.0.0:9229 build/src/index.js -e js,ts,gql",
|
||||
"lint": "eslint --max-warnings=0 --report-unused-disable-directives --ext .js,.ts,.cjs,.json,.json5,.jsonc .",
|
||||
"lint": "eslint --max-warnings=0 --report-unused-disable-directives --ext .js,.ts,.cjs,.json,.json5,.jsonc,.graphql,.gql .",
|
||||
"test": "cross-env NODE_ENV=test NODE_OPTIONS=--max-old-space-size=8192 jest --runInBand --coverage --forceExit --detectOpenHandles",
|
||||
"db:reset": "ts-node --require tsconfig-paths/register src/db/reset.ts",
|
||||
"db:reset:withmigrations": "ts-node --require tsconfig-paths/register src/db/reset-with-migrations.ts",
|
||||
@ -95,6 +95,7 @@
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "^4.6.0",
|
||||
"@faker-js/faker": "9.9.0",
|
||||
"@graphql-eslint/eslint-plugin": "^3.20.1",
|
||||
"@types/email-templates": "^10.0.4",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/jsonwebtoken": "~8.5.1",
|
||||
|
||||
14
backend/src/graphql/types/directive/neo4j-graphql-js.gql
Normal file
14
backend/src/graphql/types/directive/neo4j-graphql-js.gql
Normal file
@ -0,0 +1,14 @@
|
||||
# directive @MutationMeta on FIELD_DEFINITION
|
||||
# directive @isAuthenticated on FIELD_DEFINITION
|
||||
# directive @hasRole on FIELD_DEFINITION
|
||||
# directive @hasScope on FIELD_DEFINITION
|
||||
# directive @additionalLabels on FIELD_DEFINITION
|
||||
|
||||
directive @cypher(statement: String) on FIELD_DEFINITION
|
||||
directive @relation(
|
||||
name: String
|
||||
from: String
|
||||
to: String
|
||||
direction: String
|
||||
) on FIELD_DEFINITION | OBJECT
|
||||
directive @neo4j_ignore on FIELD_DEFINITION
|
||||
@ -2,4 +2,4 @@ enum EmailNotificationSettingsType {
|
||||
post
|
||||
chat
|
||||
group
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,4 +4,4 @@ enum Emotion {
|
||||
happy
|
||||
angry
|
||||
funny
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
enum ShoutTypeEnum {
|
||||
Post
|
||||
Comment
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,4 +2,4 @@ enum Visibility {
|
||||
public
|
||||
friends
|
||||
private
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,12 +50,16 @@ type Comment {
|
||||
isPostObservedByMe: Boolean!
|
||||
@cypher(
|
||||
statement: "MATCH (this)-[:COMMENTS]->(:Post)<-[obs:OBSERVES]-(u:User {id: $cypherParams.currentUserId}) WHERE obs.active = true RETURN COUNT(u) >= 1"
|
||||
)
|
||||
postObservingUsersCount: Int!
|
||||
@cypher(statement: "MATCH (this)-[:COMMENTS]->(:Post)<-[obs:OBSERVES]-(u:User) WHERE obs.active = true AND NOT u.disabled = true AND NOT u.deleted = true RETURN COUNT(DISTINCT u)")
|
||||
)
|
||||
postObservingUsersCount: Int!
|
||||
@cypher(
|
||||
statement: "MATCH (this)-[:COMMENTS]->(:Post)<-[obs:OBSERVES]-(u:User) WHERE obs.active = true AND NOT u.disabled = true AND NOT u.deleted = true RETURN COUNT(DISTINCT u)"
|
||||
)
|
||||
|
||||
shoutedByCurrentUser: Boolean!
|
||||
@cypher(statement: "MATCH (this) RETURN EXISTS((this)<-[:SHOUTED]-(:User {id: $cypherParams.currentUserId}))")
|
||||
@cypher(
|
||||
statement: "MATCH (this) RETURN EXISTS((this)<-[:SHOUTED]-(:User {id: $cypherParams.currentUserId}))"
|
||||
)
|
||||
|
||||
shoutedCount: Int!
|
||||
@cypher(
|
||||
@ -77,16 +81,7 @@ type Query {
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
CreateComment(
|
||||
id: ID
|
||||
postId: ID!
|
||||
content: String!
|
||||
contentExcerpt: String
|
||||
): Comment
|
||||
UpdateComment(
|
||||
id: ID!
|
||||
content: String!
|
||||
contentExcerpt: String
|
||||
): Comment
|
||||
CreateComment(id: ID, postId: ID!, content: String!, contentExcerpt: String): Comment
|
||||
UpdateComment(id: ID!, content: String!, contentExcerpt: String): Comment
|
||||
DeleteComment(id: ID!): Comment
|
||||
}
|
||||
|
||||
@ -13,4 +13,4 @@ type Query {
|
||||
|
||||
type Mutation {
|
||||
UpdateDonations(showDonations: Boolean, goal: Int, progress: Int): Donations
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,11 +9,7 @@ type Query {
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
Signup(
|
||||
email: String!
|
||||
locale: String!
|
||||
inviteCode: String = null
|
||||
): EmailAddress
|
||||
Signup(email: String!, locale: String!, inviteCode: String = null): EmailAddress
|
||||
SignupVerification(
|
||||
nonce: String!
|
||||
email: String!
|
||||
@ -27,8 +23,5 @@ type Mutation {
|
||||
locationName: String = null
|
||||
): User
|
||||
AddEmailAddress(email: String!): EmailAddress
|
||||
VerifyEmailAddress(
|
||||
nonce: String!
|
||||
email: String!
|
||||
): EmailAddress
|
||||
VerifyEmailAddress(nonce: String!, email: String!): EmailAddress
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ type FILED {
|
||||
submitter: User
|
||||
}
|
||||
|
||||
# this list equals the strings of an array in file "webapp/constants/modals.js"
|
||||
"this list equals the strings of an array in file `webapp/constants/modals.js`"
|
||||
enum ReasonCategory {
|
||||
other
|
||||
discrimination_etc
|
||||
@ -26,5 +26,9 @@ type FiledReport {
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
fileReport(resourceId: ID!, reasonCategory: ReasonCategory!, reasonDescription: String!): FiledReport
|
||||
}
|
||||
fileReport(
|
||||
resourceId: ID!
|
||||
reasonCategory: ReasonCategory!
|
||||
reasonDescription: String!
|
||||
): FiledReport
|
||||
}
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
type File {
|
||||
url: ID!,
|
||||
name: String,
|
||||
#size: Int,
|
||||
type: String,
|
||||
#audio: Boolean,
|
||||
#duration: Float,
|
||||
#preview: String,
|
||||
#progress: Int,
|
||||
url: ID!
|
||||
name: String
|
||||
type: String
|
||||
# size: Int
|
||||
# audio: Boolean
|
||||
# duration: Float
|
||||
# preview: String
|
||||
# progress: Int
|
||||
}
|
||||
|
||||
input FileInput {
|
||||
upload: Upload,
|
||||
name: String,
|
||||
type: String,
|
||||
upload: Upload
|
||||
name: String
|
||||
type: String
|
||||
}
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
enum _GroupOrdering {
|
||||
id_asc
|
||||
id_desc
|
||||
name_asc
|
||||
name_desc
|
||||
slug_asc
|
||||
slug_desc
|
||||
locationName_asc
|
||||
locationName_desc
|
||||
about_asc
|
||||
about_desc
|
||||
createdAt_asc
|
||||
createdAt_desc
|
||||
updatedAt_asc
|
||||
updatedAt_desc
|
||||
}
|
||||
# enum _GroupOrdering {
|
||||
# id_asc
|
||||
# id_desc
|
||||
# name_asc
|
||||
# name_desc
|
||||
# slug_asc
|
||||
# slug_desc
|
||||
# locationName_asc
|
||||
# locationName_desc
|
||||
# about_asc
|
||||
# about_desc
|
||||
# createdAt_asc
|
||||
# createdAt_desc
|
||||
# updatedAt_asc
|
||||
# updatedAt_desc
|
||||
# }
|
||||
|
||||
type Group {
|
||||
id: ID!
|
||||
@ -38,19 +38,21 @@ type Group {
|
||||
|
||||
categories: [Category] @relation(name: "CATEGORIZED", direction: "OUT")
|
||||
|
||||
membersCount: Int! @cypher(statement: "MATCH (this)<-[:MEMBER_OF]-(r:User) RETURN COUNT(DISTINCT r)")
|
||||
membersCount: Int!
|
||||
@cypher(statement: "MATCH (this)<-[:MEMBER_OF]-(r:User) RETURN COUNT(DISTINCT r)")
|
||||
|
||||
myRole: GroupMemberRole # if 'null' then the current user is no member
|
||||
|
||||
posts: [Post] @relation(name: "IN", direction: "IN")
|
||||
|
||||
isMutedByMe: Boolean! @cypher(statement: "MATCH (this) RETURN EXISTS( (this)<-[:MUTED]-(:User {id: $cypherParams.currentUserId}) )")
|
||||
isMutedByMe: Boolean!
|
||||
@cypher(
|
||||
statement: "MATCH (this) RETURN EXISTS( (this)<-[:MUTED]-(:User {id: $cypherParams.currentUserId}) )"
|
||||
)
|
||||
|
||||
"inviteCodes to this group the current user has generated"
|
||||
inviteCodes: [InviteCode]! @neo4j_ignore
|
||||
}
|
||||
|
||||
|
||||
input _GroupFilter {
|
||||
AND: [_GroupFilter!]
|
||||
OR: [_GroupFilter!]
|
||||
@ -74,20 +76,16 @@ type Query {
|
||||
slug: String
|
||||
first: Int
|
||||
offset: Int
|
||||
# orderBy: [_GroupOrdering] # not implemented yet
|
||||
# filter: _GroupFilter # not implemented yet
|
||||
): [Group]
|
||||
# orderBy: [_GroupOrdering] # not implemented yet
|
||||
# filter: _GroupFilter # not implemented yet
|
||||
|
||||
GroupMembers(
|
||||
id: ID!
|
||||
first: Int
|
||||
offset: Int
|
||||
# orderBy: [_UserOrdering] # not implemented yet
|
||||
# filter: _UserFilter # not implemented yet
|
||||
): [User]
|
||||
GroupMembers(id: ID!, first: Int, offset: Int): [User]
|
||||
# orderBy: [_UserOrdering] # not implemented yet
|
||||
# filter: _UserFilter # not implemented yet
|
||||
|
||||
GroupCount(isMember: Boolean): Int
|
||||
|
||||
|
||||
# AvailableGroupTypes: [GroupType]!
|
||||
|
||||
# AvailableGroupActionRadii: [GroupActionRadius]!
|
||||
@ -105,7 +103,9 @@ type Mutation {
|
||||
groupType: GroupType!
|
||||
actionRadius: GroupActionRadius!
|
||||
categoryIds: [ID]
|
||||
|
||||
# avatar: ImageInput # a group can not be created with an avatar
|
||||
|
||||
locationName: String # empty string '' sets it to null
|
||||
): Group
|
||||
|
||||
@ -115,7 +115,9 @@ type Mutation {
|
||||
slug: String
|
||||
about: String
|
||||
description: String
|
||||
|
||||
# groupType: GroupType # is not possible at the moment and has to be discussed. may be in the stronger direction: public → closed → hidden
|
||||
|
||||
actionRadius: GroupActionRadius
|
||||
categoryIds: [ID]
|
||||
avatar: ImageInput # test this as result
|
||||
@ -124,27 +126,14 @@ type Mutation {
|
||||
|
||||
# DeleteGroup(id: ID!): Group
|
||||
|
||||
JoinGroup(
|
||||
groupId: ID!
|
||||
userId: ID!
|
||||
): User
|
||||
JoinGroup(groupId: ID!, userId: ID!): User
|
||||
|
||||
LeaveGroup(
|
||||
groupId: ID!
|
||||
userId: ID!
|
||||
): User
|
||||
LeaveGroup(groupId: ID!, userId: ID!): User
|
||||
|
||||
ChangeGroupMemberRole(
|
||||
groupId: ID!
|
||||
userId: ID!
|
||||
roleInGroup: GroupMemberRole!
|
||||
): User
|
||||
ChangeGroupMemberRole(groupId: ID!, userId: ID!, roleInGroup: GroupMemberRole!): User
|
||||
|
||||
RemoveUserFromGroup(
|
||||
groupId: ID!
|
||||
userId: ID!
|
||||
): User
|
||||
RemoveUserFromGroup(groupId: ID!, userId: ID!): User
|
||||
|
||||
muteGroup(groupId: ID!): Group
|
||||
unmuteGroup(groupId: ID!): Group
|
||||
unmuteGroup(groupId: ID!): Group
|
||||
}
|
||||
|
||||
@ -1,21 +1,23 @@
|
||||
type Image {
|
||||
url: ID!,
|
||||
url: ID!
|
||||
transform(width: Int, height: Int): String
|
||||
|
||||
# urlW34: String,
|
||||
# urlW160: String,
|
||||
# urlW320: String,
|
||||
# urlW640: String,
|
||||
# urlW1024: String,
|
||||
alt: String,
|
||||
sensitive: Boolean,
|
||||
aspectRatio: Float,
|
||||
type: String,
|
||||
|
||||
alt: String
|
||||
sensitive: Boolean
|
||||
aspectRatio: Float
|
||||
type: String
|
||||
}
|
||||
|
||||
input ImageInput {
|
||||
alt: String,
|
||||
upload: Upload,
|
||||
sensitive: Boolean,
|
||||
aspectRatio: Float,
|
||||
type: String,
|
||||
alt: String
|
||||
upload: Upload
|
||||
sensitive: Boolean
|
||||
aspectRatio: Float
|
||||
type: String
|
||||
}
|
||||
|
||||
@ -19,7 +19,11 @@ type Query {
|
||||
|
||||
type Mutation {
|
||||
generatePersonalInviteCode(expiresAt: String = null, comment: String = null): InviteCode!
|
||||
generateGroupInviteCode(groupId: ID!, expiresAt: String = null, comment: String = null): InviteCode!
|
||||
generateGroupInviteCode(
|
||||
groupId: ID!
|
||||
expiresAt: String = null
|
||||
comment: String = null
|
||||
): InviteCode!
|
||||
invalidateInviteCode(code: String!): InviteCode
|
||||
redeemInviteCode(code: String!): Boolean!
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ type Location {
|
||||
}
|
||||
|
||||
# This is not smart - we need one location for everything - use the same type everywhere!
|
||||
|
||||
type LocationMapBox {
|
||||
id: ID!
|
||||
place_name: String!
|
||||
|
||||
@ -19,8 +19,11 @@ type Message {
|
||||
|
||||
senderId: String! @cypher(statement: "MATCH (this)<-[:CREATED]-(user:User) RETURN user.id")
|
||||
username: String! @cypher(statement: "MATCH (this)<-[:CREATED]-(user:User) RETURN user.name")
|
||||
avatar: String @cypher(statement: "MATCH (this)<-[:CREATED]-(:User)-[:AVATAR_IMAGE]->(image:Image) RETURN image.url")
|
||||
date: String! @cypher(statement: "RETURN this.createdAt")
|
||||
avatar: String
|
||||
@cypher(
|
||||
statement: "MATCH (this)<-[:CREATED]-(:User)-[:AVATAR_IMAGE]->(image:Image) RETURN image.url"
|
||||
)
|
||||
date: String! @cypher(statement: "RETURN this.createdAt")
|
||||
|
||||
saved: Boolean
|
||||
distributed: Boolean
|
||||
@ -29,22 +32,13 @@ type Message {
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
CreateMessage(
|
||||
roomId: ID!
|
||||
content: String
|
||||
files: [FileInput]
|
||||
): Message
|
||||
CreateMessage(roomId: ID!, content: String, files: [FileInput]): Message
|
||||
|
||||
MarkMessagesAsSeen(messageIds: [String!]): Boolean
|
||||
}
|
||||
|
||||
type Query {
|
||||
Message(
|
||||
roomId: ID!,
|
||||
first: Int
|
||||
offset: Int
|
||||
orderBy: [_MessageOrdering]
|
||||
): [Message]
|
||||
Message(roomId: ID!, first: Int, offset: Int, orderBy: [_MessageOrdering]): [Message]
|
||||
}
|
||||
|
||||
type Subscription {
|
||||
|
||||
@ -33,7 +33,7 @@ enum NotificationReason {
|
||||
type Query {
|
||||
notifications(read: Boolean, orderBy: NotificationOrdering, first: Int, offset: Int): [NOTIFIED]
|
||||
}
|
||||
|
||||
|
||||
type Mutation {
|
||||
markAsRead(id: ID!): NOTIFIED
|
||||
markAllAsRead: [NOTIFIED]
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
input _CategoryFilter {
|
||||
AND: [_CategoryFilter!]
|
||||
OR: [_CategoryFilter!]
|
||||
}
|
||||
input _PostFilter {
|
||||
AND: [_PostFilter!]
|
||||
OR: [_PostFilter!]
|
||||
@ -113,7 +117,6 @@ enum _PostOrdering {
|
||||
eventStart_desc
|
||||
}
|
||||
|
||||
|
||||
type Post {
|
||||
id: ID!
|
||||
activityId: String
|
||||
@ -132,10 +135,11 @@ type Post {
|
||||
updatedAt: String
|
||||
sortDate: String
|
||||
language: String
|
||||
pinnedAt: String @cypher(
|
||||
pinnedAt: String
|
||||
@cypher(
|
||||
statement: "MATCH (this)<-[pinned:PINNED]-(:User) WHERE NOT this.deleted = true AND NOT this.disabled = true RETURN pinned.createdAt"
|
||||
)
|
||||
pinnedBy: User @relation(name:"PINNED", direction: "IN")
|
||||
pinnedBy: User @relation(name: "PINNED", direction: "IN")
|
||||
relatedContributions: [Post]!
|
||||
@cypher(
|
||||
statement: """
|
||||
@ -160,7 +164,7 @@ type Post {
|
||||
statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)"
|
||||
)
|
||||
|
||||
# Has the currently logged in user shouted that post?
|
||||
"Has the currently logged in user shouted that post?"
|
||||
shoutedByCurrentUser: Boolean!
|
||||
@cypher(
|
||||
statement: "MATCH (this)<-[:SHOUTED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1"
|
||||
@ -173,15 +177,14 @@ type Post {
|
||||
@cypher(
|
||||
statement: "MATCH (this)<-[:VIEWED_TEASER]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1"
|
||||
)
|
||||
|
||||
|
||||
emotions: [EMOTED]
|
||||
emotionsCount: Int!
|
||||
@cypher(statement: "MATCH (this)<-[emoted:EMOTED]-(:User) RETURN COUNT(DISTINCT emoted)")
|
||||
|
||||
group: Group @relation(name: "IN", direction: "OUT")
|
||||
|
||||
postType: [PostType]
|
||||
@cypher(statement: "RETURN [l IN labels(this) WHERE NOT l = 'Post']")
|
||||
postType: [PostType] @cypher(statement: "RETURN [l IN labels(this) WHERE NOT l = 'Post']")
|
||||
|
||||
eventLocationName: String
|
||||
eventLocation: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l")
|
||||
@ -193,9 +196,11 @@ type Post {
|
||||
isObservedByMe: Boolean!
|
||||
@cypher(
|
||||
statement: "MATCH (this)<-[obs:OBSERVES]-(u:User {id: $cypherParams.currentUserId}) WHERE obs.active = true RETURN COUNT(u) >= 1"
|
||||
)
|
||||
)
|
||||
observingUsersCount: Int!
|
||||
@cypher(statement: "MATCH (this)<-[obs:OBSERVES]-(u:User) WHERE obs.active = true AND NOT u.deleted = true AND NOT u.disabled = true RETURN COUNT(DISTINCT u)")
|
||||
@cypher(
|
||||
statement: "MATCH (this)<-[obs:OBSERVES]-(u:User) WHERE obs.active = true AND NOT u.deleted = true AND NOT u.disabled = true RETURN COUNT(DISTINCT u)"
|
||||
)
|
||||
}
|
||||
|
||||
input _PostInput {
|
||||
@ -216,7 +221,7 @@ type Mutation {
|
||||
title: String!
|
||||
slug: String
|
||||
content: String!
|
||||
image: ImageInput,
|
||||
image: ImageInput
|
||||
visibility: Visibility
|
||||
language: String
|
||||
categoryIds: [ID]
|
||||
@ -231,7 +236,7 @@ type Mutation {
|
||||
slug: String
|
||||
content: String!
|
||||
contentExcerpt: String
|
||||
image: ImageInput,
|
||||
image: ImageInput
|
||||
visibility: Visibility
|
||||
language: String
|
||||
categoryIds: [ID]
|
||||
@ -247,9 +252,9 @@ type Mutation {
|
||||
pushPost(id: ID!): Post!
|
||||
unpushPost(id: ID!): Post!
|
||||
|
||||
# Shout the given Type and ID
|
||||
"Shout the given Type and ID"
|
||||
shout(id: ID!, type: ShoutTypeEnum!): Boolean!
|
||||
# Unshout the given Type and ID
|
||||
"Unshout the given Type and ID"
|
||||
unshout(id: ID!, type: ShoutTypeEnum!): Boolean!
|
||||
|
||||
toggleObservePost(id: ID!, value: Boolean!): Post!
|
||||
|
||||
@ -17,7 +17,13 @@ enum ReportRule {
|
||||
}
|
||||
|
||||
type Query {
|
||||
reports(orderBy: ReportOrdering, first: Int, offset: Int, reviewed: Boolean, closed: Boolean): [Report]
|
||||
reports(
|
||||
orderBy: ReportOrdering
|
||||
first: Int
|
||||
offset: Int
|
||||
reviewed: Boolean
|
||||
closed: Boolean
|
||||
): [Report]
|
||||
}
|
||||
|
||||
enum ReportOrdering {
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
# }
|
||||
|
||||
# TODO change this to last message date
|
||||
|
||||
enum _RoomOrdering {
|
||||
lastMessageAt_desc
|
||||
createdAt_desc
|
||||
@ -19,41 +20,48 @@ type Room {
|
||||
users: [User]! @relation(name: "CHATS_IN", direction: "IN")
|
||||
|
||||
roomId: String! @cypher(statement: "RETURN this.id")
|
||||
roomName: String! @cypher(statement: "MATCH (this)<-[:CHATS_IN]-(user:User) WHERE NOT user.id = $cypherParams.currentUserId RETURN user.name")
|
||||
avatar: String @cypher(statement: """
|
||||
MATCH (this)<-[:CHATS_IN]-(user:User)
|
||||
WHERE NOT user.id = $cypherParams.currentUserId
|
||||
OPTIONAL MATCH (user)-[:AVATAR_IMAGE]->(image:Image)
|
||||
RETURN image.url
|
||||
""")
|
||||
roomName: String!
|
||||
@cypher(
|
||||
statement: "MATCH (this)<-[:CHATS_IN]-(user:User) WHERE NOT user.id = $cypherParams.currentUserId RETURN user.name"
|
||||
)
|
||||
avatar: String
|
||||
@cypher(
|
||||
statement: """
|
||||
MATCH (this)<-[:CHATS_IN]-(user:User)
|
||||
WHERE NOT user.id = $cypherParams.currentUserId
|
||||
OPTIONAL MATCH (user)-[:AVATAR_IMAGE]->(image:Image)
|
||||
RETURN image.url
|
||||
"""
|
||||
)
|
||||
|
||||
lastMessageAt: String
|
||||
|
||||
lastMessage: Message @cypher(statement: """
|
||||
MATCH (this)<-[:INSIDE]-(message:Message)
|
||||
WITH message ORDER BY message.indexId DESC LIMIT 1
|
||||
RETURN message
|
||||
""")
|
||||
lastMessage: Message
|
||||
@cypher(
|
||||
statement: """
|
||||
MATCH (this)<-[:INSIDE]-(message:Message)
|
||||
WITH message ORDER BY message.indexId DESC LIMIT 1
|
||||
RETURN message
|
||||
"""
|
||||
)
|
||||
|
||||
unreadCount: Int @cypher(statement: """
|
||||
MATCH (this)<-[:INSIDE]-(message:Message)<-[:CREATED]-(user:User)
|
||||
WHERE NOT user.id = $cypherParams.currentUserId
|
||||
AND NOT message.seen
|
||||
RETURN count(message)
|
||||
""")
|
||||
unreadCount: Int
|
||||
@cypher(
|
||||
statement: """
|
||||
MATCH (this)<-[:INSIDE]-(message:Message)<-[:CREATED]-(user:User)
|
||||
WHERE NOT user.id = $cypherParams.currentUserId
|
||||
AND NOT message.seen
|
||||
RETURN count(message)
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
CreateRoom(
|
||||
userId: ID!
|
||||
): Room
|
||||
CreateRoom(userId: ID!): Room
|
||||
}
|
||||
|
||||
type Query {
|
||||
Room(
|
||||
id: ID
|
||||
orderBy: [_RoomOrdering]
|
||||
): [Room]
|
||||
Room(id: ID, orderBy: [_RoomOrdering]): [Room]
|
||||
UnreadRooms: Int
|
||||
}
|
||||
|
||||
|
||||
@ -25,4 +25,3 @@ type Statistics {
|
||||
usersVerified: Int!
|
||||
reports: Int!
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,8 @@ type Tag {
|
||||
id: ID!
|
||||
taggedPosts: [Post]! @relation(name: "TAGGED", direction: "IN")
|
||||
taggedCount: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p) RETURN COUNT(DISTINCT p)")
|
||||
taggedCountUnique: Int! @cypher(statement: "MATCH (this)<-[:TAGGED]-(p)<-[:WROTE]-(u:User) RETURN COUNT(DISTINCT u)")
|
||||
taggedCountUnique: Int!
|
||||
@cypher(statement: "MATCH (this)<-[:TAGGED]-(p)<-[:WROTE]-(u:User) RETURN COUNT(DISTINCT u)")
|
||||
deleted: Boolean
|
||||
disabled: Boolean
|
||||
}
|
||||
@ -34,11 +35,5 @@ enum _TagOrdering {
|
||||
}
|
||||
|
||||
type Query {
|
||||
Tag(
|
||||
id: ID
|
||||
first: Int
|
||||
offset: Int
|
||||
orderBy: [_TagOrdering]
|
||||
filter: _TagFilter
|
||||
): [Tag]
|
||||
Tag(id: ID, first: Int, offset: Int, orderBy: [_TagOrdering], filter: _TagFilter): [Tag]
|
||||
}
|
||||
|
||||
@ -38,7 +38,8 @@ type User {
|
||||
id: ID!
|
||||
actorId: String
|
||||
name: String
|
||||
email: String! @cypher(statement: "MATCH (this)-[:PRIMARY_EMAIL]->(e:EmailAddress) RETURN e.email")
|
||||
email: String!
|
||||
@cypher(statement: "MATCH (this)-[:PRIMARY_EMAIL]->(e:EmailAddress) RETURN e.email")
|
||||
slug: String!
|
||||
avatar: Image @relation(name: "AVATAR_IMAGE", direction: "OUT")
|
||||
deleted: Boolean
|
||||
@ -64,65 +65,78 @@ type User {
|
||||
emailNotificationSettings: [EmailNotificationSettings]! @neo4j_ignore
|
||||
locale: String
|
||||
friends: [User]! @relation(name: "FRIENDS", direction: "BOTH")
|
||||
friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(DISTINCT r)")
|
||||
friendsCount: Int!
|
||||
@cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(DISTINCT r)")
|
||||
|
||||
following: [User]! @relation(name: "FOLLOWS", direction: "OUT")
|
||||
followingCount: Int! @cypher(statement: "MATCH (this)-[:FOLLOWS]->(r:User) RETURN COUNT(DISTINCT r)")
|
||||
followingCount: Int!
|
||||
@cypher(statement: "MATCH (this)-[:FOLLOWS]->(r:User) RETURN COUNT(DISTINCT r)")
|
||||
|
||||
followedBy: [User]! @relation(name: "FOLLOWS", direction: "IN")
|
||||
followedByCount: Int! @cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(DISTINCT r)")
|
||||
followedByCount: Int!
|
||||
@cypher(statement: "MATCH (this)<-[:FOLLOWS]-(r:User) RETURN COUNT(DISTINCT r)")
|
||||
|
||||
# Is the currently logged in user following that user?
|
||||
followedByCurrentUser: Boolean! @cypher(
|
||||
statement: """
|
||||
MATCH (this)<-[:FOLLOWS]-(u:User { id: $cypherParams.currentUserId})
|
||||
RETURN COUNT(u) >= 1
|
||||
"""
|
||||
)
|
||||
"Is the currently logged in user following that user?"
|
||||
followedByCurrentUser: Boolean!
|
||||
@cypher(
|
||||
statement: "MATCH (this)<-[:FOLLOWS]-(u:User { id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1"
|
||||
)
|
||||
|
||||
isBlocked: Boolean! @cypher(
|
||||
statement: """
|
||||
MATCH (this)<-[:BLOCKED]-(user:User {id: $cypherParams.currentUserId})
|
||||
RETURN COUNT(user) >= 1
|
||||
"""
|
||||
)
|
||||
blocked: Boolean! @cypher(
|
||||
statement: """
|
||||
MATCH (this)-[:BLOCKED]-(user:User {id: $cypherParams.currentUserId})
|
||||
RETURN COUNT(user) >= 1
|
||||
"""
|
||||
)
|
||||
isBlocked: Boolean!
|
||||
@cypher(
|
||||
statement: """
|
||||
MATCH (this)<-[:BLOCKED]-(user:User {id: $cypherParams.currentUserId})
|
||||
RETURN COUNT(user) >= 1
|
||||
"""
|
||||
)
|
||||
blocked: Boolean!
|
||||
@cypher(
|
||||
statement: """
|
||||
MATCH (this)-[:BLOCKED]-(user:User {id: $cypherParams.currentUserId})
|
||||
RETURN COUNT(user) >= 1
|
||||
"""
|
||||
)
|
||||
|
||||
isMuted: Boolean!
|
||||
@cypher(
|
||||
statement: """
|
||||
MATCH (this)<-[:MUTED]-(user:User { id: $cypherParams.currentUserId})
|
||||
RETURN COUNT(user) >= 1
|
||||
"""
|
||||
)
|
||||
|
||||
isMuted: Boolean! @cypher(
|
||||
statement: """
|
||||
MATCH (this)<-[:MUTED]-(user:User { id: $cypherParams.currentUserId})
|
||||
RETURN COUNT(user) >= 1
|
||||
"""
|
||||
)
|
||||
|
||||
# contributions: [WrittenPost]!
|
||||
# contributions2(first: Int = 10, offset: Int = 0): [WrittenPost2]!
|
||||
# @cypher(
|
||||
# statement: "MATCH (this)-[w:WROTE]->(p:Post) RETURN p as Post, w.timestamp as timestamp"
|
||||
# )
|
||||
|
||||
contributions: [Post]! @relation(name: "WROTE", direction: "OUT")
|
||||
contributionsCount: Int! @cypher(
|
||||
statement: """
|
||||
MATCH (this)-[:WROTE]->(r:Post)
|
||||
WHERE NOT r.deleted = true AND NOT r.disabled = true
|
||||
RETURN COUNT(r)
|
||||
"""
|
||||
)
|
||||
contributionsCount: Int!
|
||||
@cypher(
|
||||
statement: """
|
||||
MATCH (this)-[:WROTE]->(r:Post)
|
||||
WHERE NOT r.deleted = true AND NOT r.disabled = true
|
||||
RETURN COUNT(r)
|
||||
"""
|
||||
)
|
||||
|
||||
comments: [Comment]! @relation(name: "WROTE", direction: "OUT")
|
||||
commentedCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(:Comment)-[:COMMENTS]->(p:Post) WHERE NOT p.deleted = true AND NOT p.disabled = true RETURN COUNT(DISTINCT(p))")
|
||||
commentedCount: Int!
|
||||
@cypher(
|
||||
statement: "MATCH (this)-[:WROTE]->(:Comment)-[:COMMENTS]->(p:Post) WHERE NOT p.deleted = true AND NOT p.disabled = true RETURN COUNT(DISTINCT(p))"
|
||||
)
|
||||
|
||||
shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT")
|
||||
shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)")
|
||||
shoutedCount: Int!
|
||||
@cypher(
|
||||
statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)"
|
||||
)
|
||||
|
||||
categories: [Category] @relation(name: "CATEGORIZED", direction: "OUT")
|
||||
|
||||
# Badges
|
||||
|
||||
badgeVerification: Badge! @neo4j_ignore
|
||||
badgeTrophies: [Badge]! @relation(name: "REWARDED", direction: "IN")
|
||||
badgeTrophiesCount: Int! @cypher(statement: "MATCH (this)<-[:REWARDED]-(r:Badge) RETURN COUNT(r)")
|
||||
@ -133,6 +147,7 @@ type User {
|
||||
"personal inviteCodes the user has generated"
|
||||
inviteCodes: [InviteCode]! @neo4j_ignore
|
||||
# inviteCodes: [InviteCode]! @relation(name: "GENERATED", direction: "OUT")
|
||||
|
||||
redeemedInviteCode: InviteCode @relation(name: "REDEEMED", direction: "OUT")
|
||||
|
||||
emotions: [EMOTED]
|
||||
@ -142,7 +157,6 @@ type User {
|
||||
myRoleInGroup: GroupMemberRole
|
||||
}
|
||||
|
||||
|
||||
input _UserFilter {
|
||||
AND: [_UserFilter!]
|
||||
OR: [_UserFilter!]
|
||||
@ -197,7 +211,7 @@ type Query {
|
||||
filter: _UserFilter
|
||||
): [User]
|
||||
|
||||
availableRoles: [UserRole]!
|
||||
availableRoles: [UserRole]!
|
||||
mutedUsers: [User]
|
||||
blockedUsers: [User]
|
||||
currentUser: User!
|
||||
@ -209,7 +223,7 @@ enum Deletable {
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
UpdateUser (
|
||||
UpdateUser(
|
||||
id: ID!
|
||||
name: String
|
||||
email: String
|
||||
@ -239,14 +253,14 @@ type Mutation {
|
||||
switchUserRole(role: UserRole!, id: ID!): User
|
||||
|
||||
saveCategorySettings(activeCategories: [String]): Boolean
|
||||
|
||||
|
||||
updateOnlineStatus(status: OnlineStatus!): Boolean!
|
||||
|
||||
requestPasswordReset(email: String!, locale: String!): Boolean!
|
||||
resetPassword(email: String!, nonce: String!, newPassword: String!): Boolean!
|
||||
changePassword(oldPassword: String!, newPassword: String!): String!
|
||||
|
||||
# Get a JWT Token for the given Email and password
|
||||
"Get a JWT Token for the given Email and password"
|
||||
login(email: String!, password: String!): String!
|
||||
|
||||
setTrophyBadgeSelected(slot: Int!, badgeId: ID): User
|
||||
|
||||
@ -4,7 +4,5 @@ type UserData {
|
||||
}
|
||||
|
||||
type Query {
|
||||
userData(
|
||||
id: ID
|
||||
): UserData
|
||||
userData(id: ID): UserData
|
||||
}
|
||||
|
||||
1082
backend/yarn.lock
1082
backend/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user