mirror of
https://github.com/wassname/talk.git
synced 2026-08-01 13:00:55 +08:00
Merge branch 'next' into next-auth
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
import DataLoader from "dataloader";
|
||||
|
||||
import TenantContext from "talk-server/graph/tenant/context";
|
||||
import {
|
||||
Asset,
|
||||
FindOrCreateAssetInput,
|
||||
retrieveManyAssets,
|
||||
} from "talk-server/models/asset";
|
||||
import { findOrCreate } from "talk-server/services/assets";
|
||||
|
||||
export default (ctx: TenantContext) => ({
|
||||
findOrCreate: (input: FindOrCreateAssetInput) =>
|
||||
findOrCreate(ctx.mongo, ctx.tenant, input, ctx.queue.scraper),
|
||||
asset: new DataLoader<string, Asset | null>(ids =>
|
||||
retrieveManyAssets(ctx.mongo, ctx.tenant.id, ids)
|
||||
),
|
||||
});
|
||||
@@ -2,11 +2,11 @@ import DataLoader from "dataloader";
|
||||
|
||||
import Context from "talk-server/graph/tenant/context";
|
||||
import {
|
||||
AssetToCommentsArgs,
|
||||
CommentToParentsArgs,
|
||||
CommentToRepliesArgs,
|
||||
GQLActionPresence,
|
||||
GQLCOMMENT_SORT,
|
||||
StoryToCommentsArgs,
|
||||
} from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
import {
|
||||
ACTION_ITEM_TYPE,
|
||||
@@ -14,9 +14,9 @@ import {
|
||||
} from "talk-server/models/action";
|
||||
import {
|
||||
Comment,
|
||||
retrieveCommentAssetConnection,
|
||||
retrieveCommentParentsConnection,
|
||||
retrieveCommentRepliesConnection,
|
||||
retrieveCommentStoryConnection,
|
||||
retrieveCommentUserConnection,
|
||||
retrieveManyComments,
|
||||
} from "talk-server/models/comment";
|
||||
@@ -61,29 +61,29 @@ export default (ctx: Context) => ({
|
||||
first = 10,
|
||||
orderBy = GQLCOMMENT_SORT.CREATED_AT_DESC,
|
||||
after,
|
||||
}: AssetToCommentsArgs
|
||||
}: StoryToCommentsArgs
|
||||
) =>
|
||||
retrieveCommentUserConnection(ctx.mongo, ctx.tenant.id, userID, {
|
||||
first,
|
||||
orderBy,
|
||||
after,
|
||||
}),
|
||||
forAsset: (
|
||||
assetID: string,
|
||||
forStory: (
|
||||
storyID: string,
|
||||
// Apply the graph schema defaults at the loader.
|
||||
{
|
||||
first = 10,
|
||||
orderBy = GQLCOMMENT_SORT.CREATED_AT_DESC,
|
||||
after,
|
||||
}: AssetToCommentsArgs
|
||||
}: StoryToCommentsArgs
|
||||
) =>
|
||||
retrieveCommentAssetConnection(ctx.mongo, ctx.tenant.id, assetID, {
|
||||
retrieveCommentStoryConnection(ctx.mongo, ctx.tenant.id, storyID, {
|
||||
first,
|
||||
orderBy,
|
||||
after,
|
||||
}).then(primeCommentsFromConnection(ctx)),
|
||||
forParent: (
|
||||
assetID: string,
|
||||
storyID: string,
|
||||
parentID: string,
|
||||
// Apply the graph schema defaults at the loader.
|
||||
{
|
||||
@@ -95,7 +95,7 @@ export default (ctx: Context) => ({
|
||||
retrieveCommentRepliesConnection(
|
||||
ctx.mongo,
|
||||
ctx.tenant.id,
|
||||
assetID,
|
||||
storyID,
|
||||
parentID,
|
||||
{
|
||||
first,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import Context from "talk-server/graph/tenant/context";
|
||||
import Assets from "./assets";
|
||||
|
||||
import Auth from "./auth";
|
||||
import Comments from "./comments";
|
||||
import Stories from "./stories";
|
||||
import Users from "./users";
|
||||
|
||||
export default (ctx: Context) => ({
|
||||
Auth: Auth(ctx),
|
||||
Assets: Assets(ctx),
|
||||
Stories: Stories(ctx),
|
||||
Comments: Comments(ctx),
|
||||
Users: Users(ctx),
|
||||
});
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import DataLoader from "dataloader";
|
||||
|
||||
import TenantContext from "talk-server/graph/tenant/context";
|
||||
import {
|
||||
FindOrCreateStoryInput,
|
||||
retrieveManyStories,
|
||||
Story,
|
||||
} from "talk-server/models/story";
|
||||
import { findOrCreate } from "talk-server/services/stories";
|
||||
|
||||
export default (ctx: TenantContext) => ({
|
||||
findOrCreate: (input: FindOrCreateStoryInput) =>
|
||||
findOrCreate(ctx.mongo, ctx.tenant, input, ctx.queue.scraper),
|
||||
story: new DataLoader<string, Story | null>(ids =>
|
||||
retrieveManyStories(ctx.mongo, ctx.tenant.id, ids)
|
||||
),
|
||||
});
|
||||
@@ -27,7 +27,7 @@ export default (ctx: TenantContext) => ({
|
||||
ctx.user!,
|
||||
{
|
||||
author_id: ctx.user!.id,
|
||||
asset_id: input.assetID,
|
||||
story_id: input.storyID,
|
||||
body: input.body,
|
||||
parent_id: input.parentID,
|
||||
},
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { GQLAssetTypeResolver } from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
import { decodeActionCounts } from "talk-server/models/action";
|
||||
import { Asset } from "talk-server/models/asset";
|
||||
|
||||
const Asset: GQLAssetTypeResolver<Asset> = {
|
||||
comments: (asset, input, ctx) =>
|
||||
ctx.loaders.Comments.forAsset(asset.id, input),
|
||||
// TODO: implement this.
|
||||
isClosed: () => false,
|
||||
actionCounts: asset => decodeActionCounts(asset.action_counts),
|
||||
commentCounts: asset => asset.comment_counts,
|
||||
};
|
||||
|
||||
export default Asset;
|
||||
@@ -23,7 +23,7 @@ const Comment: GQLCommentTypeResolver<Comment> = {
|
||||
ctx.loaders.Users.user.load(comment.author_id),
|
||||
replies: (comment, input, ctx) =>
|
||||
comment.reply_count > 0
|
||||
? ctx.loaders.Comments.forParent(comment.asset_id, comment.id, input)
|
||||
? ctx.loaders.Comments.forParent(comment.story_id, comment.id, input)
|
||||
: createConnection(),
|
||||
actionCounts: comment => decodeActionCounts(comment.action_counts),
|
||||
myActionPresence: (comment, input, ctx) =>
|
||||
@@ -84,8 +84,8 @@ const Comment: GQLCommentTypeResolver<Comment> = {
|
||||
comment.parent_id
|
||||
? ctx.loaders.Comments.parents(comment, input)
|
||||
: createConnection(),
|
||||
asset: (comment, input, ctx) =>
|
||||
ctx.loaders.Assets.asset.load(comment.asset_id),
|
||||
story: (comment, input, ctx) =>
|
||||
ctx.loaders.Stories.story.load(comment.story_id),
|
||||
};
|
||||
|
||||
export default Comment;
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
GQLCOMMENT_STATUS,
|
||||
GQLCommentCountsTypeResolver,
|
||||
} from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
import { CommentStatusCounts } from "talk-server/models/asset";
|
||||
import { CommentStatusCounts } from "talk-server/models/story";
|
||||
|
||||
const CommentCounts: GQLCommentCountsTypeResolver<CommentStatusCounts> = {
|
||||
totalVisible: commentCounts =>
|
||||
|
||||
@@ -3,7 +3,6 @@ import Time from "talk-server/graph/common/scalars/time";
|
||||
|
||||
import { GQLResolver } from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
|
||||
import Asset from "./asset";
|
||||
import AuthIntegrations from "./auth_integrations";
|
||||
import Comment from "./comment";
|
||||
import CommentCounts from "./comment_counts";
|
||||
@@ -11,10 +10,10 @@ import Mutation from "./mutation";
|
||||
import OIDCAuthIntegration from "./oidc_auth_integration";
|
||||
import Profile from "./profile";
|
||||
import Query from "./query";
|
||||
import Story from "./story";
|
||||
import User from "./user";
|
||||
|
||||
const Resolvers: GQLResolver = {
|
||||
Asset,
|
||||
AuthIntegrations,
|
||||
Comment,
|
||||
CommentCounts,
|
||||
@@ -24,6 +23,7 @@ const Resolvers: GQLResolver = {
|
||||
Profile,
|
||||
Query,
|
||||
Time,
|
||||
Story,
|
||||
User,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { GQLQueryTypeResolver } from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
|
||||
const Query: GQLQueryTypeResolver<void> = {
|
||||
asset: (source, args, ctx) => ctx.loaders.Assets.findOrCreate(args),
|
||||
story: (source, args, ctx) => ctx.loaders.Stories.findOrCreate(args),
|
||||
comment: (source, { id }, ctx) =>
|
||||
id ? ctx.loaders.Comments.comment.load(id) : null,
|
||||
settings: (source, args, ctx) => ctx.tenant,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { GQLStoryTypeResolver } from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
import { decodeActionCounts } from "talk-server/models/action";
|
||||
import { Story } from "talk-server/models/story";
|
||||
|
||||
const Story: GQLStoryTypeResolver<Story> = {
|
||||
comments: (story, input, ctx) =>
|
||||
ctx.loaders.Comments.forStory(story.id, input),
|
||||
// TODO: implement this.
|
||||
isClosed: () => false,
|
||||
actionCounts: story => decodeActionCounts(story.action_counts),
|
||||
commentCounts: story => story.comment_counts,
|
||||
};
|
||||
|
||||
export default Story;
|
||||
@@ -735,7 +735,7 @@ type Settings {
|
||||
domains: [String!] @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
moderation is the moderation mode for all Asset's on the site.
|
||||
moderation is the moderation mode for all Stories on the site.
|
||||
"""
|
||||
moderation: MODERATION_MODE @auth(roles: [ADMIN])
|
||||
|
||||
@@ -789,12 +789,12 @@ type Settings {
|
||||
|
||||
"""
|
||||
closedTimeout is the amount of seconds from the created_at timestamp that a
|
||||
given asset will be considered closed.
|
||||
given story will be considered closed.
|
||||
"""
|
||||
closedTimeout: Int!
|
||||
|
||||
"""
|
||||
closedMessage is the message shown to the user when the given Asset is
|
||||
closedMessage is the message shown to the user when the given Story is
|
||||
closed.
|
||||
"""
|
||||
closedMessage: String
|
||||
@@ -997,7 +997,7 @@ enum COMMENT_STATUS {
|
||||
REJECTED
|
||||
|
||||
"""
|
||||
The comment was created while the asset's premoderation option was on, and
|
||||
The comment was created while the stories premoderation option was on, and
|
||||
new comments that haven't been moderated yet are referred to as
|
||||
"premoderated" or "premod" comments.
|
||||
"""
|
||||
@@ -1011,7 +1011,7 @@ enum COMMENT_STATUS {
|
||||
}
|
||||
|
||||
"""
|
||||
Comment is a comment left by a User on an Asset or another Comment as a reply.
|
||||
Comment is a comment left by a User on an Story or another Comment as a reply.
|
||||
"""
|
||||
type Comment {
|
||||
"""
|
||||
@@ -1072,7 +1072,7 @@ type Comment {
|
||||
|
||||
"""
|
||||
rootParent is the highest level parent Comment. This Comment would have been
|
||||
left on the Asset itself.
|
||||
left on the Story itself.
|
||||
"""
|
||||
rootParent: Comment
|
||||
|
||||
@@ -1099,9 +1099,9 @@ type Comment {
|
||||
myActionPresence: ActionPresence
|
||||
|
||||
"""
|
||||
asset is the Asset that the Comment was written on.
|
||||
story is the Story that the Comment was written on.
|
||||
"""
|
||||
asset: Asset!
|
||||
story: Story!
|
||||
}
|
||||
|
||||
type PageInfo {
|
||||
@@ -1178,7 +1178,7 @@ type CommentStatusCounts {
|
||||
REJECTED: Int!
|
||||
|
||||
"""
|
||||
The comment was created while the asset's premoderation option was on, and
|
||||
The comment was created while the stories premoderation option was on, and
|
||||
new comments that haven't been moderated yet are referred to as
|
||||
"premoderated" or "premod" comments.
|
||||
"""
|
||||
@@ -1201,7 +1201,7 @@ type CommentCounts {
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## Asset
|
||||
## Story
|
||||
################################################################################
|
||||
|
||||
enum COMMENT_SORT {
|
||||
@@ -1212,26 +1212,26 @@ enum COMMENT_SORT {
|
||||
}
|
||||
|
||||
"""
|
||||
Asset is an Article or Page where Comments are written on by Users.
|
||||
Story is an Article or Page where Comments are written on by Users.
|
||||
"""
|
||||
type Asset {
|
||||
type Story {
|
||||
"""
|
||||
id is the identifier of the Asset.
|
||||
id is the identifier of the Story.
|
||||
"""
|
||||
id: ID!
|
||||
|
||||
"""
|
||||
url is the url that the Asset is located on.
|
||||
url is the url that the Story is located on.
|
||||
"""
|
||||
url: String!
|
||||
|
||||
"""
|
||||
title is the title of the scraped Asset.
|
||||
title is the title of the scraped Story.
|
||||
"""
|
||||
title: String
|
||||
|
||||
"""
|
||||
comments are the comments on the Asset.
|
||||
comments are the comments on the Story.
|
||||
"""
|
||||
comments(
|
||||
first: Int = 10
|
||||
@@ -1240,23 +1240,23 @@ type Asset {
|
||||
): CommentsConnection!
|
||||
|
||||
"""
|
||||
actionCounts stores the counts of all the actions against this Asset and it's
|
||||
actionCounts stores the counts of all the actions against this Story and it's
|
||||
Comments.
|
||||
"""
|
||||
actionCounts: ActionCounts! @auth(roles: [ADMIN, MODERATOR])
|
||||
|
||||
"""
|
||||
author is the authors listed in the meta tags for the Asset.
|
||||
author is the authors listed in the meta tags for the Story.
|
||||
"""
|
||||
author: String
|
||||
|
||||
"""
|
||||
closedAt is the Time that the Asset is closed for commenting.
|
||||
closedAt is the Time that the Story is closed for commenting.
|
||||
"""
|
||||
closedAt: Time
|
||||
|
||||
"""
|
||||
isClosed returns true when the Asset is currently closed for commenting.
|
||||
isClosed returns true when the Story is currently closed for commenting.
|
||||
"""
|
||||
isClosed: Boolean!
|
||||
|
||||
@@ -1266,19 +1266,19 @@ type Asset {
|
||||
commentCounts: CommentCounts!
|
||||
|
||||
"""
|
||||
createdAt is the date that the Asset was created at.
|
||||
createdAt is the date that the Story was created at.
|
||||
"""
|
||||
createdAt: Time!
|
||||
}
|
||||
|
||||
"""
|
||||
AssetEdge represents a unique Asset in a AssetConnection.
|
||||
StoryEdge represents a unique Story in a StoryConnection.
|
||||
"""
|
||||
type AssetEdge {
|
||||
type StoryEdge {
|
||||
"""
|
||||
node is the Asset for this edge.
|
||||
node is the Story for this edge.
|
||||
"""
|
||||
node: Asset!
|
||||
node: Story!
|
||||
|
||||
"""
|
||||
|
||||
@@ -1287,13 +1287,13 @@ type AssetEdge {
|
||||
}
|
||||
|
||||
"""
|
||||
AssetsConnection represents a subset of a Asset list.
|
||||
StoriesConnection represents a subset of a Story list.
|
||||
"""
|
||||
type AssetsConnection {
|
||||
type StoriesConnection {
|
||||
"""
|
||||
edges are a subset of AssetEdge's.
|
||||
edges are a subset of StoryEdge's.
|
||||
"""
|
||||
edges: [AssetEdge!]!
|
||||
edges: [StoryEdge!]!
|
||||
|
||||
"""
|
||||
pageInfo is
|
||||
@@ -1312,9 +1312,9 @@ type Query {
|
||||
comment(id: ID!): Comment
|
||||
|
||||
"""
|
||||
asset is the Asset specified by its ID/URL.
|
||||
story is the Story specified by its ID/URL.
|
||||
"""
|
||||
asset(id: ID, url: String): Asset
|
||||
story(id: ID, url: String): Story
|
||||
|
||||
"""
|
||||
me is the current logged in User. If no user is currently logged in, it will
|
||||
@@ -1353,9 +1353,9 @@ CreateCommentInput provides the input for the createComment Mutation.
|
||||
"""
|
||||
input CreateCommentInput {
|
||||
"""
|
||||
assetID is the ID of the Asset where we are creating a comment on.
|
||||
storyID is the ID of the Story where we are creating a comment on.
|
||||
"""
|
||||
assetID: ID!
|
||||
storyID: ID!
|
||||
|
||||
"""
|
||||
parentID is the optional ID of the Comment that we are replying to.
|
||||
@@ -1684,7 +1684,7 @@ input SettingsInput {
|
||||
domains: [String!]
|
||||
|
||||
"""
|
||||
moderation is the moderation mode for all Asset's on the site.
|
||||
moderation is the moderation mode for all Stories on the site.
|
||||
"""
|
||||
moderation: MODERATION_MODE
|
||||
|
||||
@@ -1738,12 +1738,12 @@ input SettingsInput {
|
||||
|
||||
"""
|
||||
closedTimeout is the amount of seconds from the created_at timestamp that a
|
||||
given asset will be considered closed.
|
||||
given story will be considered closed.
|
||||
"""
|
||||
closedTimeout: Int
|
||||
|
||||
"""
|
||||
closedMessage is the message shown to the user when the given Asset is
|
||||
closedMessage is the message shown to the user when the given Story is
|
||||
closed.
|
||||
"""
|
||||
closedMessage: String
|
||||
@@ -2364,5 +2364,5 @@ type Mutation {
|
||||
################################################################################
|
||||
|
||||
type Subscription {
|
||||
commentCreated(assetID: ID!): Comment
|
||||
commentCreated(storyID: ID!): Comment
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user