export type JsonRecord = Record<string, unknown>
export type QueryValue = string | number | boolean | null | undefined
export type QueryInput = Record<string, QueryValue | QueryValue[]>
export type ListingSort = 'best' | 'hot' | 'new' | 'top' | 'rising' | 'controversial'
export type SearchSort = 'relevance' | 'hot' | 'top' | 'new' | 'comments'
export type TimeFilter = 'hour' | 'day' | 'week' | 'month' | 'year' | 'all'
export type UserListing = 'about' | 'submitted' | 'comments' | 'overview'
export type SubmitKind = 'self' | 'link'
export type VoteDirection = 1 | 0 | -1
export type AccountInput = {
/** Exact integration name, e.g. `reddit-work`. Wins over `account`. */
integration?: string
/** Purpose suffix. `work` → `reddit-work`. `default` / `reddit` / omitted → `reddit`. */
account?: string
}
export type RedditRequestInput = AccountInput & {
path: string
method?: string
query?: QueryInput
headers?: Record<string, string>
body?: unknown
dryRun?: boolean
confirm?: boolean
}
export type RedditRequestResult = {
ok: boolean
status: number
statusText: string
headers: Record<string, string>
body: unknown
integration: string
}
export type GetListingInput = AccountInput & {
subreddit?: string
sort?: ListingSort
t?: TimeFilter
limit?: number
after?: string
before?: string
}
export type GetSubredditInput = AccountInput & {
subreddit: string
}
export type SearchInput = AccountInput & {
query: string
subreddit?: string
sort?: SearchSort
t?: TimeFilter
limit?: number
after?: string
restrictToSubreddit?: boolean
}
export type GetUserInput = AccountInput & {
username: string
listing?: UserListing
sort?: ListingSort
t?: TimeFilter
limit?: number
after?: string
}
export type GetPostInput = AccountInput & {
id: string
subreddit?: string
commentLimit?: number
commentSort?: SearchSort | ListingSort
}
export type SubmitPostInput = AccountInput & {
subreddit: string
title: string
kind?: SubmitKind
text?: string
url?: string
nsfw?: boolean
spoiler?: boolean
sendreplies?: boolean
flairId?: string
flairText?: string
dryRun?: boolean
confirm?: boolean
}
export type SubmitCommentInput = AccountInput & {
parentId: string
text: string
dryRun?: boolean
confirm?: boolean
}
export type VoteInput = AccountInput & {
id: string
direction: VoteDirection | 'up' | 'down' | 'clear'
dryRun?: boolean
confirm?: boolean
}
export type ShapedPost = {
id: string
name: string
title: string
author: string
subreddit: string
score: number | null
upvoteRatio: number | null
numComments: number | null
url: string | null
permalink: string | null
createdUtc: number | null
over18: boolean
stickied: boolean
isSelf: boolean
selftext: string | null
selftextTruncated: boolean
linkFlairText: string | null
}
export type ShapedComment = {
id: string
name: string
author: string
body: string | null
bodyTruncated: boolean
score: number | null
permalink: string | null
createdUtc: number | null
parentId: string | null
}
export type ShapedListing = {
kind: 'listing'
after: string | null
before: string | null
posts: ShapedPost[]
}
export type ShapedSubreddit = {
id: string | null
name: string | null
displayName: string | null
title: string | null
publicDescription: string | null
subscribers: number | null
accountsActive: number | null
over18: boolean
url: string | null
createdUtc: number | null
submissionType: string | null
}
export type ShapedUser = {
id: string | null
name: string | null
createdUtc: number | null
commentKarma: number | null
linkKarma: number | null
totalKarma: number | null
isGold: boolean
isMod: boolean
verified: boolean
hasVerifiedEmail: boolean | null
}
export function requireRecord(value: unknown, utilityName: string): JsonRecord {
if (value && typeof value === 'object' && !Array.isArray(value)) {
return value as JsonRecord
}
throw new Error(utilityName + ' requires an object params value.')
}
export function requireStringField(record: JsonRecord, key: string, utilityName: string): string {
const value = record[key]
if (typeof value !== 'string' || value.length === 0) {
throw new Error(utilityName + ' requires params.' + key + '.')
}
return value
}
export function asRecord(value: unknown): JsonRecord | null {
if (value && typeof value === 'object' && !Array.isArray(value)) {
return value as JsonRecord
}
return null
}
export function stringValue(value: unknown): string | undefined {
return typeof value === 'string' && value.length > 0 ? value : undefined
}
export function numberValue(value: unknown): number | null {
return typeof value === 'number' && Number.isFinite(value) ? value : null
}
export function booleanValue(value: unknown, fallback = false): boolean {
return typeof value === 'boolean' ? value : fallback
}