manifold/functions/src/create-fold.ts
2022-05-15 13:39:42 -04:00

96 lines
2.4 KiB
TypeScript

import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { getUser } from './utils'
import { Contract } from '../../common/contract'
import { slugify } from '../../common/util/slugify'
import { randomString } from '../../common/util/random'
import { Fold } from '../../common/fold'
export const createFold = functions.runWith({ minInstances: 1 }).https.onCall(
async (
data: {
name: string
about: string
tags: string[]
},
context
) => {
const userId = context?.auth?.uid
if (!userId) return { status: 'error', message: 'Not authorized' }
const creator = await getUser(userId)
if (!creator) return { status: 'error', message: 'User not found' }
let { name, about, tags } = data
if (!name || typeof name !== 'string')
return { status: 'error', message: 'Name must be a non-empty string' }
name = name.trim().slice(0, 140)
if (typeof about !== 'string')
return { status: 'error', message: 'About must be a string' }
about = about.trim().slice(0, 140)
if (!_.isArray(tags))
return { status: 'error', message: 'Tags must be an array of strings' }
console.log(
'creating fold for',
creator.username,
'named',
name,
'about',
about,
'tags',
tags
)
const slug = await getSlug(name)
const foldRef = firestore.collection('folds').doc()
const fold: Fold = {
id: foldRef.id,
curatorId: userId,
slug,
name,
about,
tags,
lowercaseTags: tags.map((tag) => tag.toLowerCase()),
createdTime: Date.now(),
contractIds: [],
excludedContractIds: [],
excludedCreatorIds: [],
followCount: 0,
}
await foldRef.create(fold)
await foldRef.collection('followers').doc(userId).set({ userId })
return { status: 'success', fold }
}
)
const getSlug = async (name: string) => {
const proposedSlug = slugify(name)
const preexistingFold = await getFoldFromSlug(proposedSlug)
return preexistingFold ? proposedSlug + '-' + randomString() : proposedSlug
}
const firestore = admin.firestore()
export async function getFoldFromSlug(slug: string) {
const snap = await firestore
.collection('folds')
.where('slug', '==', slug)
.get()
return snap.empty ? undefined : (snap.docs[0].data() as Contract)
}