Files
talk/src/core/server/models/asset.ts
T
2018-06-27 11:39:26 -06:00

111 lines
2.5 KiB
TypeScript

import dotize from "dotize";
import { defaults } from "lodash";
import { Db } from "mongodb";
import { Omit } from "talk-common/types";
import { TenantResource } from "talk-server/models/tenant";
import uuid from "uuid";
import Query from "./query";
function collection(db: Db) {
return db.collection<Readonly<Asset>>("assets");
}
export interface Asset extends TenantResource {
readonly id: string;
url: string;
scraped?: Date;
closedAt?: Date;
closedMessage?: string;
title?: string;
description?: string;
image?: string;
section?: string;
subsection?: string;
author?: string;
publication_date?: Date;
modified_date?: Date;
created_at: Date;
}
export type CreateAssetInput = Pick<Asset, "id" | "url">;
export async function createAsset(
db: Db,
tenantID: string,
input: CreateAssetInput
) {
const now = new Date();
// Construct the filter.
const query = new Query<Asset>(collection(db)).where({
tenant_id: tenantID,
});
if (input.id) {
query.where({ id: input.id });
} else {
query.where({ url: input.url });
}
// Craft the update object.
const update: { $setOnInsert: Asset } = {
$setOnInsert: defaults(input, {
id: uuid.v4(),
tenant_id: tenantID,
created_at: now,
}),
};
// Perform the upsert operation.
const result = await collection(db).findOneAndUpdate(query.filter, update, {
// Create the object if it doesn't already exist.
upsert: true,
// False to return the updated document instead of the original
// document.
returnOriginal: false,
});
return result.value || null;
}
export async function retrieveAsset(db: Db, tenantID: string, id: string) {
return await collection(db).findOne({ id, tenant_id: tenantID });
}
export async function retrieveManyAssets(
db: Db,
tenantID: string,
ids: string[]
) {
const cursor = await collection(db).find({
id: { $in: ids },
tenant_id: tenantID,
});
const assets = await cursor.toArray();
return ids.map(id => assets.find(asset => asset.id === id) || null);
}
export type UpdateAssetInput = Omit<
Partial<Asset>,
"id" | "tenant_id" | "url" | "created_at"
>;
export async function updateAsset(
db: Db,
tenantID: string,
id: string,
update: UpdateAssetInput
) {
const result = await collection(db).findOneAndUpdate(
{ id, tenant_id: tenantID },
// Only update fields that have been updated.
{ $set: dotize(update) },
// False to return the updated document instead of the original
// document.
{ returnOriginal: false }
);
return result.value || null;
}