mirror of
https://github.com/wassname/talk.git
synced 2026-08-14 12:50:17 +08:00
111 lines
2.5 KiB
TypeScript
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;
|
|
}
|