mirror of
https://github.com/wassname/talk.git
synced 2026-07-28 11:27:05 +08:00
Merge branch 'next' into next-auth
This commit is contained in:
@@ -38,7 +38,7 @@ export interface Comment extends TenantResource {
|
||||
readonly id: string;
|
||||
parent_id?: string;
|
||||
author_id: string;
|
||||
asset_id: string;
|
||||
story_id: string;
|
||||
body: string;
|
||||
body_history: BodyHistoryItem[];
|
||||
status: GQLCOMMENT_STATUS;
|
||||
@@ -288,14 +288,14 @@ function cursorGetterFactory(
|
||||
export async function retrieveCommentRepliesConnection(
|
||||
db: Db,
|
||||
tenantID: string,
|
||||
assetID: string,
|
||||
storyID: string,
|
||||
parentID: string,
|
||||
input: ConnectionInput
|
||||
) {
|
||||
// Create the query.
|
||||
const query = new Query(collection(db)).where({
|
||||
tenant_id: tenantID,
|
||||
asset_id: assetID,
|
||||
story_id: storyID,
|
||||
parent_id: parentID,
|
||||
});
|
||||
|
||||
@@ -400,23 +400,23 @@ export async function retrieveCommentParentsConnection(
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieveAssetConnection returns a Connection<Comment> for a given Asset's
|
||||
* retrieveStoryConnection returns a Connection<Comment> for a given Stories
|
||||
* comments.
|
||||
*
|
||||
* @param db database connection
|
||||
* @param assetID the Asset id for the comment to retrieve
|
||||
* @param storyID the Story id for the comment to retrieve
|
||||
* @param input connection configuration
|
||||
*/
|
||||
export async function retrieveCommentAssetConnection(
|
||||
export async function retrieveCommentStoryConnection(
|
||||
db: Db,
|
||||
tenantID: string,
|
||||
assetID: string,
|
||||
storyID: string,
|
||||
input: ConnectionInput
|
||||
) {
|
||||
// Create the query.
|
||||
const query = new Query(collection(db)).where({
|
||||
tenant_id: tenantID,
|
||||
asset_id: assetID,
|
||||
story_id: storyID,
|
||||
parent_id: null,
|
||||
});
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ModerationSettings } from "talk-server/models/settings";
|
||||
import { TenantResource } from "talk-server/models/tenant";
|
||||
|
||||
function collection(db: Db) {
|
||||
return db.collection<Readonly<Asset>>("assets");
|
||||
return db.collection<Readonly<Story>>("stories");
|
||||
}
|
||||
|
||||
// TODO: (wyattjoh) write a test to verify that this set of counts is always in sync with GQLCOMMENT_STATUS.
|
||||
@@ -21,7 +21,7 @@ export interface CommentStatusCounts {
|
||||
[GQLCOMMENT_STATUS.SYSTEM_WITHHELD]: number;
|
||||
}
|
||||
|
||||
export interface Asset extends TenantResource {
|
||||
export interface Story extends TenantResource {
|
||||
readonly id: string;
|
||||
url: string;
|
||||
scraped?: Date;
|
||||
@@ -39,40 +39,40 @@ export interface Asset extends TenantResource {
|
||||
publication_date?: Date;
|
||||
|
||||
/**
|
||||
* action_counts stores all the action counts for all Comment's on this Asset.
|
||||
* action_counts stores all the action counts for all Comment's on this Story.
|
||||
*/
|
||||
action_counts: EncodedActionCounts;
|
||||
|
||||
/**
|
||||
* comment_counts stores the different counts for each comment on the Asset
|
||||
* comment_counts stores the different counts for each comment on the Story
|
||||
* according to their statuses.
|
||||
*/
|
||||
comment_counts: CommentStatusCounts;
|
||||
|
||||
/**
|
||||
* settings provides a point where the settings can be overridden for a
|
||||
* specific Asset.
|
||||
* specific Story.
|
||||
*/
|
||||
settings?: Partial<ModerationSettings>;
|
||||
}
|
||||
|
||||
export interface UpsertAssetInput {
|
||||
export interface UpsertStoryInput {
|
||||
id?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export async function upsertAsset(
|
||||
export async function upsertStory(
|
||||
db: Db,
|
||||
tenantID: string,
|
||||
{ id, url }: UpsertAssetInput
|
||||
{ id, url }: UpsertStoryInput
|
||||
) {
|
||||
const now = new Date();
|
||||
|
||||
// TODO: verify that the url for the given Asset is whitelisted by the tenant.
|
||||
// TODO: verify that the url for the given Story is whitelisted by the tenant.
|
||||
|
||||
// Create the asset, optionally sourcing the id from the input, additionally
|
||||
// Create the story, optionally sourcing the id from the input, additionally
|
||||
// porting in the tenant_id.
|
||||
const update: { $setOnInsert: Asset } = {
|
||||
const update: { $setOnInsert: Story } = {
|
||||
$setOnInsert: {
|
||||
id: id ? id : uuid.v4(),
|
||||
url,
|
||||
@@ -84,8 +84,8 @@ export async function upsertAsset(
|
||||
};
|
||||
|
||||
// Perform the find and update operation to try and find and or create the
|
||||
// asset.
|
||||
const { value: asset } = await collection(db).findOneAndUpdate(
|
||||
// story.
|
||||
const { value: story } = await collection(db).findOneAndUpdate(
|
||||
{
|
||||
url,
|
||||
tenant_id: tenantID,
|
||||
@@ -100,26 +100,26 @@ export async function upsertAsset(
|
||||
returnOriginal: false,
|
||||
}
|
||||
);
|
||||
if (!asset) {
|
||||
if (!story) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!asset.scraped) {
|
||||
// TODO: create scrape job to collect asset metadata
|
||||
if (!story.scraped) {
|
||||
// TODO: create scrape job to collect story metadata
|
||||
}
|
||||
|
||||
return asset;
|
||||
return story;
|
||||
}
|
||||
|
||||
/**
|
||||
* updateCommentStatusCount increments the number of status counts for the
|
||||
* given Asset ID.
|
||||
* given Story ID.
|
||||
*
|
||||
* @param mongo the database handle
|
||||
* @param tenantID the tenant that the Asset is on.
|
||||
* @param id the ID of the Asset.
|
||||
* @param tenantID the tenant that the Story is on.
|
||||
* @param id the ID of the Story.
|
||||
* @param commentStatusCounts the update document that contains a positive or
|
||||
* negative number of comments to increment on the given Asset.
|
||||
* negative number of comments to increment on the given Story.
|
||||
*/
|
||||
export async function updateCommentStatusCount(
|
||||
mongo: Db,
|
||||
@@ -127,7 +127,7 @@ export async function updateCommentStatusCount(
|
||||
id: string,
|
||||
commentStatusCounts: Partial<CommentStatusCounts>
|
||||
) {
|
||||
const { value: asset } = await collection(mongo).findOneAndUpdate(
|
||||
const { value: story } = await collection(mongo).findOneAndUpdate(
|
||||
{
|
||||
id,
|
||||
tenant_id: tenantID,
|
||||
@@ -140,7 +140,7 @@ export async function updateCommentStatusCount(
|
||||
{ returnOriginal: false }
|
||||
);
|
||||
|
||||
return asset;
|
||||
return story;
|
||||
}
|
||||
|
||||
function createEmptyCommentCounts(): CommentStatusCounts {
|
||||
@@ -153,39 +153,39 @@ function createEmptyCommentCounts(): CommentStatusCounts {
|
||||
};
|
||||
}
|
||||
|
||||
export interface FindOrCreateAssetInput {
|
||||
export interface FindOrCreateStoryInput {
|
||||
id?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export async function findOrCreateAsset(
|
||||
export async function findOrCreateStory(
|
||||
db: Db,
|
||||
tenantID: string,
|
||||
{ id, url }: FindOrCreateAssetInput
|
||||
{ id, url }: FindOrCreateStoryInput
|
||||
) {
|
||||
if (id) {
|
||||
if (url) {
|
||||
// The URL was specified, this is an upsert operation.
|
||||
return upsertAsset(db, tenantID, {
|
||||
return upsertStory(db, tenantID, {
|
||||
id,
|
||||
url,
|
||||
});
|
||||
}
|
||||
|
||||
// The URL was not specified, this is a lookup operation.
|
||||
return retrieveAsset(db, tenantID, id);
|
||||
return retrieveStory(db, tenantID, id);
|
||||
}
|
||||
|
||||
// The ID was not specified, this is an upsert operation. Check to see that
|
||||
// the URL exists.
|
||||
if (!url) {
|
||||
throw new Error("cannot upsert an asset without the url");
|
||||
throw new Error("cannot upsert an story without the url");
|
||||
}
|
||||
|
||||
return upsertAsset(db, tenantID, { url });
|
||||
return upsertStory(db, tenantID, { url });
|
||||
}
|
||||
|
||||
export async function retrieveAssetByURL(
|
||||
export async function retrieveStoryByURL(
|
||||
db: Db,
|
||||
tenantID: string,
|
||||
url: string
|
||||
@@ -193,11 +193,11 @@ export async function retrieveAssetByURL(
|
||||
return collection(db).findOne({ url, tenant_id: tenantID });
|
||||
}
|
||||
|
||||
export async function retrieveAsset(db: Db, tenantID: string, id: string) {
|
||||
export async function retrieveStory(db: Db, tenantID: string, id: string) {
|
||||
return collection(db).findOne({ id, tenant_id: tenantID });
|
||||
}
|
||||
|
||||
export async function retrieveManyAssets(
|
||||
export async function retrieveManyStories(
|
||||
db: Db,
|
||||
tenantID: string,
|
||||
ids: string[]
|
||||
@@ -207,12 +207,12 @@ export async function retrieveManyAssets(
|
||||
tenant_id: tenantID,
|
||||
});
|
||||
|
||||
const assets = await cursor.toArray();
|
||||
const stories = await cursor.toArray();
|
||||
|
||||
return ids.map(id => assets.find(asset => asset.id === id) || null);
|
||||
return ids.map(id => stories.find(story => story.id === id) || null);
|
||||
}
|
||||
|
||||
export async function retrieveManyAssetsByURL(
|
||||
export async function retrieveManyStoriesByURL(
|
||||
db: Db,
|
||||
tenantID: string,
|
||||
urls: string[]
|
||||
@@ -222,21 +222,21 @@ export async function retrieveManyAssetsByURL(
|
||||
tenant_id: tenantID,
|
||||
});
|
||||
|
||||
const assets = await cursor.toArray();
|
||||
const stories = await cursor.toArray();
|
||||
|
||||
return urls.map(url => assets.find(asset => asset.url === url) || null);
|
||||
return urls.map(url => stories.find(story => story.url === url) || null);
|
||||
}
|
||||
|
||||
export type UpdateAssetInput = Omit<
|
||||
Partial<Asset>,
|
||||
export type UpdateStoryInput = Omit<
|
||||
Partial<Story>,
|
||||
"id" | "tenant_id" | "url" | "created_at"
|
||||
>;
|
||||
|
||||
export async function updateAsset(
|
||||
export async function updateStory(
|
||||
db: Db,
|
||||
tenantID: string,
|
||||
id: string,
|
||||
input: UpdateAssetInput
|
||||
input: UpdateStoryInput
|
||||
) {
|
||||
// Only update fields that have been updated.
|
||||
const update = {
|
||||
@@ -259,15 +259,15 @@ export async function updateAsset(
|
||||
}
|
||||
|
||||
/**
|
||||
* updateAssetActionCounts will update the given comment's action counts on
|
||||
* the Asset.
|
||||
* updateStoryActionCounts will update the given comment's action counts on
|
||||
* the Story.
|
||||
*
|
||||
* @param mongo the database handle
|
||||
* @param tenantID the id of the Tenant
|
||||
* @param id the id of the Asset being updated
|
||||
* @param actionCounts the action counts to merge into the Asset
|
||||
* @param id the id of the Story being updated
|
||||
* @param actionCounts the action counts to merge into the Story
|
||||
*/
|
||||
export async function updateAssetActionCounts(
|
||||
export async function updateStoryActionCounts(
|
||||
mongo: Db,
|
||||
tenantID: string,
|
||||
id: string,
|
||||
@@ -19,7 +19,7 @@ export interface TenantResource {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tenant describes a given Tenant on Talk that has Assets, Comments, and Users.
|
||||
* Tenant describes a given Tenant on Talk that has Stories, Comments, and Users.
|
||||
*/
|
||||
export interface Tenant extends Settings {
|
||||
readonly id: string;
|
||||
|
||||
Reference in New Issue
Block a user