manifold/web/pages/api/v0/_types.ts
Sinclair Chen 9a11f55762
Rich content (#620)
* Add TipTap editor and renderer components

* Change market description editor to rich text

* Type description as JSON, fix string-based logic

- Delete make-predictions.tsx
- Delete feed logic that showed descriptions

* wip Fix API validation

* fix type error

* fix extension import (backend)

In firebase, typescript compiles imports into common js imports
like `const StarterKit = require("@tiptap/starter-kit")`

Even though StarterKit is exported from the cjs file, it gets imported
as undefined. But it magically works if we import *

If you're reading this in the future, consider replacing StarterKit with
the entire list of extensions.

* Stop load on fail create market, improve warning

* Refactor editor as hook / fix infinite submit bug

Move state of editor back up to parent
We have to do this later anyways to allow parent to edit

* Add images - display, paste + uploading

* add uploading state of image

* Fix placeholder, misc styling

min height, quote

* Fix appending to description

* code review fixes: rename, refactor, chop carets

* Add hint & upload button on new lines

- bump to Tailwind 3.1 for arbitrary variants

* clean up, run prettier

* rename FileButton to FileUploadButton

* add image extension as functions dependency
2022-07-13 11:58:22 -07:00

231 lines
4.3 KiB
TypeScript

import { Bet } from 'common/bet'
import { Answer } from 'common/answer'
import { getOutcomeProbability, getProbability } from 'common/calculate'
import { Comment } from 'common/comment'
import { Contract } from 'common/contract'
import { User } from 'common/user'
import { removeUndefinedProps } from 'common/util/object'
import { ENV_CONFIG } from 'common/envs/constants'
import { JSONContent } from '@tiptap/core'
export type LiteMarket = {
// Unique identifer for this market
id: string
// Attributes about the creator
creatorUsername: string
creatorName: string
createdTime: number
creatorAvatarUrl?: string
// Market attributes. All times are in milliseconds since epoch
closeTime?: number
question: string
description: string | JSONContent
tags: string[]
url: string
outcomeType: string
mechanism: string
pool: { [outcome: string]: number }
probability?: number
p?: number
totalLiquidity?: number
volume: number
volume7Days: number
volume24Hours: number
isResolved: boolean
resolution?: string
resolutionTime?: number
resolutionProbability?: number
}
export type ApiAnswer = Answer & {
probability?: number
}
export type FullMarket = LiteMarket & {
bets: Bet[]
comments: Comment[]
answers?: ApiAnswer[]
}
export type ApiError = {
error: string
}
type ValidationErrorDetail = {
field: string | null
error: string
}
export class ValidationError {
details: ValidationErrorDetail[]
constructor(details: ValidationErrorDetail[]) {
this.details = details
}
}
export function toLiteMarket(contract: Contract): LiteMarket {
const {
id,
creatorUsername,
creatorName,
createdTime,
creatorAvatarUrl,
closeTime,
question,
description,
tags,
slug,
pool,
outcomeType,
mechanism,
volume,
volume7Days,
volume24Hours,
isResolved,
resolution,
resolutionTime,
resolutionProbability,
} = contract
const { p, totalLiquidity } = contract as any
const probability =
contract.outcomeType === 'BINARY' ? getProbability(contract) : undefined
return removeUndefinedProps({
id,
creatorUsername,
creatorName,
createdTime,
creatorAvatarUrl,
closeTime:
resolutionTime && closeTime
? Math.min(resolutionTime, closeTime)
: closeTime,
question,
description,
tags,
url: `https://manifold.markets/${creatorUsername}/${slug}`,
pool,
probability,
p,
totalLiquidity,
outcomeType,
mechanism,
volume,
volume7Days,
volume24Hours,
isResolved,
resolution,
resolutionTime,
resolutionProbability,
})
}
export function toFullMarket(
contract: Contract,
comments: Comment[],
bets: Bet[]
): FullMarket {
const liteMarket = toLiteMarket(contract)
const answers =
contract.outcomeType === 'FREE_RESPONSE'
? contract.answers.map((answer) =>
augmentAnswerWithProbability(contract, answer)
)
: undefined
return {
...liteMarket,
answers,
comments,
bets,
}
}
function augmentAnswerWithProbability(
contract: Contract,
answer: Answer
): ApiAnswer {
const probability = getOutcomeProbability(contract, answer.id)
return {
...answer,
probability,
}
}
export type LiteUser = {
id: string
createdTime: number
name: string
username: string
url: string
avatarUrl?: string
bio?: string
bannerUrl?: string
website?: string
twitterHandle?: string
discordHandle?: string
balance: number
totalDeposits: number
profitCached: {
daily: number
weekly: number
monthly: number
allTime: number
}
creatorVolumeCached: {
daily: number
weekly: number
monthly: number
allTime: number
}
}
export function toLiteUser(user: User): LiteUser {
const {
id,
createdTime,
name,
username,
avatarUrl,
bio,
bannerUrl,
website,
twitterHandle,
discordHandle,
balance,
totalDeposits,
profitCached,
creatorVolumeCached,
} = user
return removeUndefinedProps({
id,
createdTime,
name,
username,
url: `https://${ENV_CONFIG.domain}/${username}`,
avatarUrl,
bio,
bannerUrl,
website,
twitterHandle,
discordHandle,
balance,
totalDeposits,
profitCached,
creatorVolumeCached,
})
}