123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983 |
- import { ConsoleSqlOutlined } from '@ant-design/icons'
- import {
- actionFullProfilePageUser,
- actionFullProfilePage,
- } from '../redux/thunk'
- import { actionFeedTypeCount } from '../redux/reducers/feed/feedReducer'
- import { actionFeedType } from '../redux/reducers/feed/feedReducer'
- import { actionExploreTypeCount } from '../redux/reducers/explore/exploreReducer'
- import { actionClearExplorePosts } from '../redux/reducers/explore/exploreReducer'
- import { actionExploreType } from '../redux/reducers/explore/exploreReducer'
- import { actionClearFeedPosts } from '../redux/reducers/feed/feedReducer'
- import { history } from '../App'
- export const actionAuthLogin = (token) => ({ type: 'AUTH_LOGIN', token })
- export const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
- export const getGQL = (url) => (query, variables) =>
- fetch(url, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- ...(localStorage.authToken
- ? { Authorization: 'Bearer ' + localStorage.authToken }
- : {}),
- },
- body: JSON.stringify({ query, variables }),
- })
- .then((res) => res.json())
- .then((data) => {
- if (data.data) {
- return Object.values(data.data)[0]
- } else {
- throw new Error(JSON.stringify(data.errors))
- }
- })
- export const gql = getGQL('/graphql')
- export const actionPending = (name) => ({
- type: 'PROMISE',
- name,
- status: 'PENDING',
- })
- export const actionFulfilled = (name, payload) => ({
- type: 'PROMISE',
- name,
- status: 'FULFILLED',
- payload,
- })
- export const actionRejected = (name, error) => ({
- type: 'PROMISE',
- name,
- status: 'REJECTED',
- error,
- })
- export const actionPromise = (name, promise) => async (dispatch) => {
- dispatch(actionPending(name))
- try {
- let payload = await promise
- dispatch(actionFulfilled(name, payload))
- return payload
- } catch (error) {
- dispatch(actionRejected(name, error))
- }
- }
- export const actionAboutMe = (_id) =>
- actionPromise(
- 'aboutMe',
- gql(
- `query AboutMe($userId:String){
- UserFindOne(query:$userId)
- {
- _id createdAt login nick avatar{_id url}
- followers{_id login nick avatar{_id url}}
- following{_id login nick avatar{_id url}}
- }
- }`,
- {
- userId: JSON.stringify([{ _id }]),
- },
- ),
- )
- export const actionFullLogin = (login, password) => async (dispatch) => {
- let token = await dispatch(
- actionPromise(
- 'auth',
- gql(
- ` query login($login:String!, $password:String!){
- login(login:$login, password:$password)} `,
- { login, password },
- ),
- ),
- )
- if (token) {
- await dispatch(actionAuthLogin(token))
- }
- }
- export const actionRegister = (login, password) =>
- actionPromise(
- 'register',
- gql(
- `mutation register($login: String!, $password: String!) {
- createUser (login: $login, password: $password) {
- _id login
- }
- }`,
- { login: login, password: password },
- ),
- )
- export const actionChangePassword = (login, password, newPassword) =>
- actionPromise(
- 'newPassword',
- gql(
- `mutation changePassword($login: String!, $password: String!, $newPassword: newPassword) {
- changePassword (login: $login, password: $password$newPassword: newPassword) {
- _id login
- }
- }`,
- { login, password , newPassword},
- ),
- )
- export const actionFullRegister = (login, password) => async (dispatch) => {
- let tokenCheck = await dispatch(actionRegister(login, password))
- if (tokenCheck?.login === login) {
- await dispatch(actionFullLogin(login, password))
- history.push('/feed')
- }
- }
- export const uploadFile = (file) => {
- const myForm = new FormData()
- myForm.append('photo', file)
- return fetch('/upload', {
- method: 'POST',
- headers: localStorage.authToken
- ? { Authorization: 'Bearer ' + localStorage.authToken }
- : {},
- body: myForm,
- }).then((result) => result.json())
- }
- export const actionUploadFile = (file) =>
- actionPromise('uploadFile', uploadFile(file))
- export const actionClearPromise = (name) => (dispatch) => {
- return dispatch(actionClearPromiseForName(name))
- }
- export const actionClearPromiseForName = (name) => ({
- type: 'PROMISE_CLEAR',
- name,
- })
- export const actionUploadFiles = (files) =>
- actionPromise(
- 'uploadFiles',
- Promise.all(files.map((file) => uploadFile(file))),
- )
- export const actionAvatar = (imageId, myId) =>
- actionPromise(
- 'setAvatar',
- gql(
- `mutation setAvatar($imageId:ID, $userId:String){
- UserUpsert(user:{_id: $userId, avatar: {_id: $imageId}}){
- _id, avatar{
- _id
- }
- }
- }`,
- { imageId, userId: myId },
- ),
- )
- export const actionPostUpsert = (post) => async (dispatch) => {
- await dispatch(
- actionPromise(
- 'postUpsert',
- gql(
- `
- mutation PostUpsert($post:PostInput){
- PostUpsert(post:$post){
- _id title text images{_id url}
- }
- }`,
- {
- post: {
- ...post,
- images: post.images.map(({ _id }) => ({ _id })),
- },
- },
- ),
- ),
- )
- }
- export const actionAllPosts = (userId) =>
- actionPromise(
- 'allPostsMe',
- gql(
- `query allPosts($userId:String!){
- PostFind(query:$userId){
- owner{_id} _id title text images{_id url}
- }
- }`,
- {
- userId: JSON.stringify([
- { ___owner: userId },
- {
- sort: [{ _id: -1 }],
- skip: [0],
- limit: [300],
- },
- ]),
- },
- ),
- )
- export const actionPostsCount = (_id) =>
- actionPromise(
- 'countAllPostsUser',
- gql(
- ` query CountAllPostsUser($_id:String!){
- PostCount(query:$_id)
- }`,
- { _id: JSON.stringify([{ ___owner: { $in: [_id] } }]) },
- ),
- )
- // export const actionAllPostsFeed = () =>
- // actionPromise(
- // 'postsAllFeed',
- // gql(
- // ` query allPosts($_id:String){
- // PostFind(query:$_id){
- // owner{_id login avatar{_id url}}
- // _id title text images{_id url}
- // likes{
- // _id
- // owner{
- // _id login avatar {_id url}
- // }
- // }
- // comments{
- // _id, createdAt, text owner{_id login avatar{_id url}}
- // answers{
- // _id, createdAt, text owner{_id login avatar{_id url}}
- // }
- // }
- // }
- // }`,
- // {
- // _id: JSON.stringify([
- // {},
- // {
- // sort: [{ _id: -1 }],
- // skip: [0],
- // limit: [10],
- // },
- // ]),
- // },
- // ),
- // )
- export const actionOnePost = (_id) =>
- actionPromise(
- 'onePost',
- gql(
- `query OneFind($post:String){
- PostFindOne(query:$post){
- _id title text images{_id url}
- owner{_id login avatar{_id url}}
- createdAt
- comments{
- _id, createdAt, text owner{_id login avatar{_id url}}
- answers{
- _id, createdAt, text owner{_id login avatar{_id url}}
-
- }
- owner{_id login avatar{_id url}}}
- likes{
- _id
- owner{
- _id login avatar {_id url}
- }
- }
-
- }
- }
- `,
- {
- post: JSON.stringify([{ _id }]),
- },
- ),
- )
- export const actionFindLikes = (_id) => async (dispatch) => {
- await dispatch(
- actionPromise(
- 'onePostFindLike',
- gql(
- `query OneFind($post:String){
- PostFindOne(query:$post){
- likes{
- _id
- owner{
- _id login avatar {url}
- }
- }
- }
- }`,
- {
- post: JSON.stringify([{ _id }]),
- },
- ),
- ),
- )
- }
- export const actionAllFollowers = (_id) => async (dispatch) => {
- await dispatch(
- actionPromise(
- 'allFollowers',
- gql(
- `query AllFollowers($userId:String){
- UserFindOne(query:$userId)
- {
- followers{_id login}
- }
- }`,
- {
- userId: JSON.stringify([{ _id }]),
- },
- ),
- ),
- )
- }
- export const actionAllFollowing = (_id) => async (dispatch) => {
- await dispatch(
- actionPromise(
- 'allFollowing',
- gql(
- `query AllFollowing($userId:String){
- UserFindOne(query:$userId)
- {
- following{_id login}
- }
- }`,
- {
- userId: JSON.stringify([{ _id }]),
- },
- ),
- ),
- )
- }
- export const actionAddComment = (postId, text) => async (dispatch) => {
- await dispatch(
- actionPromise(
- 'addComment',
- gql(
- `mutation AddComment($comment:CommentInput){
- CommentUpsert(comment:$comment)
- {
- _id
- text
- createdAt
- }
- }`,
- {
- comment: {
- post: {
- _id: postId,
- },
- text: text,
- },
- },
- ),
- ),
- )
- }
- export const actionAddSubComment = (commentId, comment) => async (dispatch) => {
- await dispatch(
- actionPromise(
- 'addSubComment',
- gql(
- `mutation AddComment($comment:CommentInput){
- CommentUpsert(comment:$comment)
- {
- _id
- text
- createdAt
- }
- }`,
- {
- comment: {
- answerTo: {
- _id: commentId,
- },
- text: comment,
- },
- },
- ),
- ),
- )
- }
- // export const actionAddFullComment = (postId,comment) => async(dispatch) => {
- // let addComment = await dispatch(actionAddComment(postId,comment));
- // if(addComment){
- // await dispatch(actionOnePost(postId));
- // }
- // }
- export const actionAddFullComment = (postId, comment) => async (
- dispatch,
- getState,
- ) => {
- await dispatch(actionAddComment(postId, comment))
- const {
- promise: {
- addComment: { status },
- },
- } = getState()
- if (status === 'FULFILLED') {
- await dispatch(actionOnePost(postId))
- }
- // await dispatch(actionOnePost(postId));
- }
- export const actionAddSubFullComment = (postId, commentId, comment) => async (
- dispatch,
- getState,
- ) => {
- await dispatch(actionAddSubComment(commentId, comment))
- const {
- promise: {
- addSubComment: { status },
- },
- } = getState()
- if (status === 'FULFILLED') {
- await dispatch(actionOnePost(postId))
- }
- // await dispatch(actionOnePost(postId));
- }
- // export const actionAddlike = _id =>
- // actionPromise("addLike", gql(`mutation AddLike($like:LikeInput){
- // LikeUpsert(like:$like){
- // _id
- // }
- // }`,{
- // like:{
- // "post":{
- // "_id": _id
- // }
- // }
- // }))
- export const actionAddLike = (postId) =>
- actionPromise(
- 'addLike',
- gql(
- `mutation AddLike($like:LikeInput){
- LikeUpsert(like:$like)
- {
- _id owner{_id login}
- }
- }`,
- {
- like: {
- post: {
- _id: postId,
- },
- },
- },
- ),
- )
- export const actionGetFindLiked = (_id) => async (dispatch) => {
- await dispatch(
- actionPromise(
- 'findLiked',
- gql(
- ` query LikeFindPost($id:String!) {
- LikeFind(query:$id){
- owner { _id nick login
- avatar{_id url}
- }
- }
- } `,
- {
- id: JSON.stringify([{ 'post._id': _id }]),
- },
- ),
- ),
- )
- }
- // export const actionDeleteFullLike = (likeId) => async(dispatch,getState) => {
- // let unLike = await dispatch(actionDeleteLike(likeId));
- // if(unLike){
- // await dispatch(actionOnePost(unLike?.post?._id));
- // }
- // }
- export const actionDeleteFullLike = (likeId, postId) => async (
- dispatch,
- getState,
- ) => {
- await dispatch(actionDeleteLike(likeId, postId))
- const {
- promise: {
- deleteLike: { status },
- },
- } = getState()
- if (status === 'FULFILLED') {
- await dispatch(actionOnePost(postId))
- }
- // await dispatch(actionOnePost(postId));
- }
- export const actionDeleteLike = (likeId, postId) =>
- actionPromise(
- 'deleteLike',
- gql(
- `mutation DeleteLike($like:LikeInput){
- LikeDelete(like: $like)
- {
- _id, post{
- _id owner{_id login avatar{_id url}}
- }
- }
- }`,
- {
- like: {
- _id: likeId,
- post: {
- _id: postId,
- },
- },
- },
- ),
- )
- export const actionSetAvatar = (file, myId) => async (dispatch) => {
- const avatar = await dispatch(actionAvatar(file, myId))
- if (avatar) {
- await dispatch(actionFullProfilePageUser(myId))
- await dispatch(actionFullProfilePage(myId))
- await dispatch(actionClearPromise('setAvatar'))
- await dispatch(actionClearPromise('uploadFile'))
- }
- }
- export const actionPostsFeed = (myFollowing, skip) =>
- actionPromise(
- 'postsFeed',
- gql(
- `query PostsFeed($ownerId:String){
- PostFind(query:$ownerId){
- owner{_id login avatar{url}}
- images{_id url} title text
- _id likesCount
- likes{
- _id
- owner{
- _id login avatar {_id url}
- }
- }
- comments{
- _id, createdAt, text owner{_id login avatar{_id url}}
- answers{
- _id, createdAt, text owner{_id login avatar{_id url}}
-
- }
- }
- }
- }`,
- {
- ownerId: JSON.stringify([
- {
- ___owner: {
- $in: myFollowing,
- },
- },
- {
- sort: [{ _id: -1 }],
- skip: [skip || 0],
- limit: [10],
- },
- ]),
- },
- ),
- )
- export const actionFullAllGetPosts = () => async (dispatch, getState) => {
- const {
- feed: { postsFeed, postsFeedCount },
- profileData: { aboutMe },
- promise,
- } = getState()
- const myFollowing =
- aboutMe?.following && aboutMe?.following?.map(({ _id }) => _id)
- console.log('myFollowing ', myFollowing)
- const myId = aboutMe?._id
- const skip = postsFeed?.length
- // console.log('skip ', skip)
- console.log('postsFeed', postsFeed)
- if (skip !== (postsFeedCount ? postsFeedCount : 1)) {
- const newPosts = await dispatch(
- actionPostsFeed([...(myFollowing || []), myId], skip),
- )
- console.log('newPosts', newPosts)
- const newPostsFeedCount = await dispatch(
- actionPostsFeedCount([...(myFollowing || []), myId]),
- )
- if (newPosts && newPostsFeedCount) {
- console.log('newPosts', newPosts)
- await dispatch(actionFeedType(newPosts, newPostsFeedCount))
- // if(promise?.postsFeed?.status=='PENDING')
- // await dispatch(actionClearFeedPosts())
- // await dispatch(actionClearPromiseForName('postsFeed'))
- // await dispatch(actionFeedTypeCount(postsFeedCount))
- // await dispatch(actionClearPromiseForName('postsFeed'))
- // await dispatch(actionFeedType(newPosts))
- }
- }
- }
- export const actionFullExplorePosts = () => async (dispatch, getState) => {
- const {
- explore: { explorePosts, explorePostsCount },
- promise,
- } = getState()
- console.log('explorePosts', explorePosts)
- if (explorePosts?.length !== (explorePostsCount ? explorePostsCount : 1)) {
- console.log('explorePosts', explorePosts)
- const newPosts = await dispatch(actionExplorePosts(explorePosts?.length))
- console.log('newPosts', newPosts)
- const newPostsExploreCount = await dispatch(actionExplorePostsCount())
- if (newPostsExploreCount && newPosts)
- await dispatch(actionExploreType(newPosts, newPostsExploreCount))
- // if (promise?.explorePosts?.status == 'PENDING')
- // await dispatch(actionClearExplorePosts())
- }
- }
- export const actionPostsFeedCount = (myFollowing) =>
- actionPromise(
- 'postsFeedCount',
- gql(
- ` query CountAllPostsUser($_id:String!){
- PostCount(query:$_id)
- }`,
- {
- _id: JSON.stringify([
- {
- ___owner: {
- $in: myFollowing,
- },
- },
- ]),
- },
- ),
- )
- export const actionExplorePosts = (skip) =>
- actionPromise(
- 'explorePosts',
- gql(
- ` query PostsFeed($_id:String){
- PostFind(query:$_id){
- owner{_id login avatar{url}}
- images{_id url} title text
- _id likesCount
- likes{
- _id
- owner{
- _id login avatar {_id url}
- }
- }
- comments{
- _id, createdAt, text owner{_id login avatar{_id url}}
- answers{
- _id, createdAt, text owner{_id login avatar{_id url}}
-
- }
- }
- }
- }`,
- {
- _id: JSON.stringify([
- {},
- {
- sort: [{ _id: -1 }],
- skip: [skip || 0],
- limit: [10],
- },
- ]),
- },
- ),
- )
- export const actionExplorePostsCount = () =>
- actionPromise(
- 'explorePostsCount',
- gql(
- ` query CountAllPosts($_id:String!){
- PostCount(query:$_id)
- }`,
- {
- _id: JSON.stringify([{}]),
- },
- ),
- )
- export const actionSearchUser = (userName) => async (dispatch) => {
- await dispatch(
- actionPromise(
- 'searchUser',
- gql(
- `
- query gf($query: String){
- UserFind(query: $query){
- _id, login avatar{url}
- }
- }`,
- {
- query: JSON.stringify([
- {
- $or: [{ login: `/${userName}/` }], //регулярки пишутся в строках
- },
- {
- sort: [{ login: 1 }],
- }, //сортируем по title алфавитно
- ]),
- },
- ),
- ),
- )
- }
- export const actionUserUpsert = (user, myId) =>
- actionPromise(
- 'userUpsert',
- gql(
- `mutation UserUpsert($user:UserInput){
- UserUpsert(user:$user){
- _id login nick avatar{_id}
- }
- }`,
- {
- user: {
- _id: myId,
- ...user,
- },
- },
- ),
- )
- // export con
- export const actionAboutUser = (_id) =>
- actionPromise(
- 'aboutUser',
- gql(
- `query AboutMe($userId:String){
- UserFindOne(query:$userId)
- {
- _id createdAt login nick avatar{_id url}
- followers{_id login nick avatar{_id url}}
- following{_id login nick avatar{_id url}}
- }
- }`,
- {
- userId: JSON.stringify([{ _id }]),
- },
- ),
- )
- export const actionAllPostsUser = (userId, skip) =>
- actionPromise(
- 'allPosts',
- gql(
- `query allPosts($userId:String!){
- PostFind(query:$userId){
- owner{_id} _id title text images{_id url}
- }
- }`,
- {
- userId: JSON.stringify([
- { ___owner: userId },
- {
- sort: [{ _id: -1 }],
- skip: [skip || 0],
- limit: [300],
- },
- ]),
- },
- ),
- )
- export const actionSubscribe = (my_Id, followId, oldFollowing) =>
- actionPromise(
- 'subscribe',
- gql(
- `mutation subscribe($user:UserInput) {
- UserUpsert(user: $user) {
- _id following{_id login}
- followers{
- _id login
- }
- }
- }
- `,
- {
- user: {
- _id: my_Id,
- following: [...(oldFollowing || []), { _id: followId }],
- },
- },
- ),
- )
- export const actionUnSubscribe = (my_Id, oldFollowing) =>
- actionPromise(
- 'unSubscribe',
- gql(
- `mutation unSubscribe($user:UserInput) {
- UserUpsert(user: $user) {
- _id following{_id login}
- followers{
- _id login
- }
- }
- }
- `,
- {
- user: {
- _id: my_Id,
- following: oldFollowing || [],
- },
- },
- ),
- )
- export const actionFullSubscribe = (my_Id, followId) => async (
- dispatch,
- getState,
- ) => {
- const oldFollowing = (
- getState().promise.aboutMe?.payload?.following || []
- ).map(({ _id }) => ({ _id }))
- let followingId = await dispatch(
- actionSubscribe(my_Id, followId, oldFollowing),
- )
- if (followingId) {
- Promise.all([
- await dispatch(actionFullProfilePageUser(followId)),
- await dispatch(actionFullProfilePage(my_Id)),
- ])
- await dispatch(actionClearFeedPosts())
- }
- }
- export const actionFullUnSubscribe = (my_Id, followId) => async (
- dispatch,
- getState,
- ) => {
- const oldFollowing = (getState().promise.aboutMe?.payload?.following || [])
- .filter((item) => item._id !== followId)
- .map(({ _id }) => ({ _id }))
- if (oldFollowing) {
- await dispatch(actionUnSubscribe(my_Id, oldFollowing))
- Promise.all([
- await dispatch(actionFullProfilePageUser(followId)),
- await dispatch(actionFullProfilePage(my_Id)),
- ])
- await dispatch(actionClearFeedPosts())
- }
- }
- export const actionAddFullLike = (postId) => async (dispatch, getState) => {
- await dispatch(actionAddLike(postId))
- const {
- promise: {
- addLike: { status },
- },
- } = getState()
- if (status === 'FULFILLED') {
- await dispatch(actionOnePost(postId))
- }
- // await dispatch(actionOnePost(postId));
- }
- export const actionAddFullLikeForFeed = (postId) => async (
- dispatch,
- getState,
- ) => {
- await dispatch(actionAddLike(postId))
- const {
- promise: {
- addLike: { status },
- },
- } = getState()
- if (status === 'FULFILLED') {
- await dispatch(actionOnePost(postId))
- await dispatch(actionFullAllGetPosts())
- }
- // await dispatch(actionOnePost(postId));
- }
- export const actionDeleteFullLikeForFeed = (likeId, postId) => async (
- dispatch,
- getState,
- ) => {
- await dispatch(actionDeleteLike(likeId, postId))
- const {
- promise: {
- deleteLike: { status },
- },
- } = getState()
- if (status === 'FULFILLED') {
- await dispatch(actionOnePost(postId))
- await dispatch(actionFullAllGetPosts())
- }
- // await dispatch(actionOnePost(postId));
- }
- export const actionUserUpdate = (user, myId) => async (dispatch, getState) => {
- await dispatch(actionUserUpsert(user, myId))
- const {
- promise: {
- userUpsert: { status },
- },
- } = getState()
- if (status === 'FULFILLED') {
- await dispatch(actionFullProfilePage(myId))
- await dispatch(actionFullProfilePageUser(myId))
- }
- }
- export const actionFindSubComment = (findId) =>
- actionPromise(
- 'subComments',
- gql(
- `query commentFindOne ($id:String!){
- CommentFindOne(query:$id){
- _id text answers {
- _id text
- post {_id }
- answers { _id}
- createdAt
- likes { _id owner
- {_id avatar{_id url} login nick } }
- owner {
- _id login nick
- avatar { _id url }
- }
- }
- }
- }`,
- {
- id: JSON.stringify([
- {
- _id: findId,
- },
- ]),
- },
- ),
- )
|