Files
omnivore/packages/api/src/services/save_email.ts
2022-03-08 15:10:01 -08:00

115 lines
3.1 KiB
TypeScript

import { PubsubClient } from '../datalayer/pubsub'
import { DataModels } from '../resolvers/types'
import { generateSlug, stringToHash, validatedDate } from '../utils/helpers'
import {
parseUrlMetadata,
parseOriginalContent,
parsePreparedContent,
} from '../utils/parser'
import normalizeUrl from 'normalize-url'
import { kx } from '../datalayer/knex_config'
import { UserArticleData } from '../datalayer/links/model'
import { setClaims } from '../datalayer/helpers'
export type SaveContext = {
pubsub: PubsubClient
models: DataModels
}
export type SaveEmailInput = {
originalContent: string
url: string
title: string
author: string
}
export const saveEmail = async (
ctx: SaveContext,
saverId: string,
input: SaveEmailInput
): Promise<UserArticleData | undefined> => {
const url = input.url
const parseResult = await parsePreparedContent(
url,
{
document: input.originalContent,
pageInfo: {
// can leave this empty for now
},
},
true
)
const title = input.title
const content = parseResult.parsedContent?.content || input.originalContent
const slug = generateSlug(title)
const pageType = parseOriginalContent(url, input.originalContent)
const metadata = await parseUrlMetadata(url)
const articleToSave = {
originalHtml: input.originalContent,
content: content,
description: metadata?.description || parseResult.parsedContent?.excerpt,
title: metadata?.title || parseResult.parsedContent?.title || title,
author:
metadata?.author || parseResult.parsedContent?.byline || input.author,
url: normalizeUrl(parseResult.canonicalUrl || url, {
stripHash: true,
stripWWW: false,
}),
pageType: pageType,
hash: stringToHash(content),
image: metadata?.previewImage || parseResult.parsedContent?.previewImage,
publishedAt: validatedDate(parseResult.parsedContent?.publishedDate),
}
if (parseResult.canonicalUrl && parseResult.domContent) {
await ctx.pubsub.pageSaved(
saverId,
parseResult.canonicalUrl,
parseResult.domContent
)
}
const matchedUserArticleRecord = await ctx.models.userArticle.getByParameters(
saverId,
{
articleUrl: articleToSave.url,
}
)
let result: UserArticleData | undefined = undefined
if (matchedUserArticleRecord) {
await ctx.pubsub.pageCreated(saverId, url, input.originalContent)
await kx.transaction(async (tx) => {
await setClaims(tx, saverId)
result = await ctx.models.userArticle.update(matchedUserArticleRecord.id, {
savedAt: new Date(),
archivedAt: null,
})
})
} else {
await ctx.pubsub.pageCreated(saverId, url, input.originalContent)
await kx.transaction(async (tx) => {
const articleRecord = await ctx.models.article.create(articleToSave, tx)
result = await ctx.models.userArticle.create(
{
userId: saverId,
slug: slug,
articleId: articleRecord.id,
articleUrl: articleRecord.url,
articleHash: articleRecord.hash,
},
tx
)
console.log('save new email result', result)
})
}
return result
}