Merge branch 'next' into next-auth

This commit is contained in:
Wyatt Johnson
2018-10-29 17:39:06 -06:00
121 changed files with 904 additions and 972 deletions
+8 -8
View File
@@ -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,
+1 -1
View File
@@ -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;