Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kentcdodds/producthunt

src/types.ts

225 lines · 5.5 KB · TypeScript
/**
 * Shared TypeScript types for the Product Hunt GraphQL API and this package's helpers.
 */

/** Saved Kody OAuth integration name. Default `producthunt`. */
export type ProductHuntIntegrationOptions = {
	/** Override the saved integration name when it is not `producthunt`. */
	integration?: string
}

/** Product Hunt GraphQL error object. */
export type ProductHuntGraphQLError = {
	message: string
	path?: Array<string | number>
	locations?: Array<{ line: number; column: number }>
	extensions?: Record<string, unknown>
}

/** Options for the generic GraphQL `request` helper. */
export type ProductHuntRequestInput = ProductHuntIntegrationOptions & {
	/** GraphQL query or mutation document. */
	query: string
	/** GraphQL variables object. */
	variables?: Record<string, unknown>
	/** Optional GraphQL operation name. */
	operationName?: string
	/** Throw `ProductHuntRequestError` on HTTP or GraphQL errors. Default true. */
	throwOnError?: boolean
}

/** Parsed Product Hunt GraphQL response. */
export type ProductHuntRequestResult<T = unknown> = {
	ok: boolean
	status: number
	statusText: string
	data: T | null
	errors: ProductHuntGraphQLError[] | null
}

/** Relay-style pagination info. */
export type ProductHuntPageInfo = {
	endCursor: string | null
	hasNextPage: boolean
	hasPreviousPage: boolean
	startCursor: string | null
}

/** Generic connection wrapper used by list helpers. */
export type ProductHuntConnection<T> = {
	nodes: T[]
	pageInfo: ProductHuntPageInfo
}

export type ProductHuntPostsOrder = 'FEATURED_AT' | 'VOTES' | 'RANKING' | 'NEWEST'
export type ProductHuntTopicsOrder = 'NEWEST' | 'FOLLOWERS_COUNT'
export type ProductHuntCollectionsOrder = 'NEWEST' | 'FOLLOWERS_COUNT' | 'FEATURED_AT'
export type ProductHuntCommentsOrder = 'NEWEST' | 'VOTES_COUNT'

/** Compact hunter summary. */
export type ProductHuntUserSummary = {
	id: string
	name: string
	username: string
	headline: string | null
	url: string
	profileImage: string | null
	twitterUsername: string | null
	websiteUrl: string | null
	isMaker: boolean
	followersCount: number
	followingCount: number
}

/** Compact topic summary. */
export type ProductHuntTopicSummary = {
	id: string
	name: string
	slug: string
	description?: string
	url?: string
	followersCount?: number
	postsCount?: number
	isFollowing?: boolean
}

/** Compact collection summary. */
export type ProductHuntCollectionSummary = {
	id: string
	name: string
	tagline: string
	description: string | null
	url: string
	coverImage: string | null
	followersCount: number
	featuredAt: string | null
	createdAt: string
	isFollowing: boolean
	user?: ProductHuntUserSummary
}

/** Compact post summary used by list and lookup helpers. */
export type ProductHuntPostSummary = {
	id: string
	name: string
	slug: string
	tagline: string
	description: string | null
	url: string
	website: string
	votesCount: number
	commentsCount: number
	reviewsCount: number
	reviewsRating: number
	createdAt: string
	featuredAt: string | null
	dailyRank: number | null
	weeklyRank: number | null
	isVoted: boolean
	thumbnailUrl: string | null
	user: ProductHuntUserSummary
	makers: ProductHuntUserSummary[]
	topics: ProductHuntTopicSummary[]
}

/** Compact comment summary. */
export type ProductHuntCommentSummary = {
	id: string
	body: string
	url: string
	createdAt: string
	votesCount: number
	isVoted: boolean
	parentId: string | null
	user: ProductHuntUserSummary
}

export type ProductHuntListPostsOptions = ProductHuntIntegrationOptions & {
	featured?: boolean
	postedAfter?: string
	postedBefore?: string
	topic?: string
	order?: ProductHuntPostsOrder
	first?: number
	after?: string
}

export type ProductHuntGetPostOptions = ProductHuntIntegrationOptions & {
	id?: string
	slug?: string
}

export type ProductHuntGetUserOptions = ProductHuntIntegrationOptions & {
	id?: string
	username?: string
}

export type ProductHuntListCommentsOptions = ProductHuntIntegrationOptions & {
	postId?: string
	slug?: string
	order?: ProductHuntCommentsOrder
	first?: number
	after?: string
}

export type ProductHuntGetCollectionOptions = ProductHuntIntegrationOptions & {
	id?: string
	slug?: string
}

export type ProductHuntListCollectionsOptions = ProductHuntIntegrationOptions & {
	postId?: string
	userId?: string
	featured?: boolean
	order?: ProductHuntCollectionsOrder
	first?: number
	after?: string
}

export type ProductHuntGetTopicOptions = ProductHuntIntegrationOptions & {
	id?: string
	slug?: string
}

export type ProductHuntListTopicsOptions = ProductHuntIntegrationOptions & {
	query?: string
	followedByUserid?: string
	order?: ProductHuntTopicsOrder
	first?: number
	after?: string
}

/**
 * Return exported Product Hunt TypeScript type names for agent discovery.
 * @example
 * import types from 'kody:@kentcdodds/producthunt/types'
 * const names = await types()
 * // => ['ProductHuntPostSummary', 'ProductHuntRequestInput', ...]
 */
export default function describeProductHuntTypes() {
	return [
		'ProductHuntIntegrationOptions',
		'ProductHuntGraphQLError',
		'ProductHuntRequestInput',
		'ProductHuntRequestResult',
		'ProductHuntPageInfo',
		'ProductHuntConnection',
		'ProductHuntPostsOrder',
		'ProductHuntTopicsOrder',
		'ProductHuntCollectionsOrder',
		'ProductHuntCommentsOrder',
		'ProductHuntUserSummary',
		'ProductHuntTopicSummary',
		'ProductHuntCollectionSummary',
		'ProductHuntPostSummary',
		'ProductHuntCommentSummary',
		'ProductHuntListPostsOptions',
		'ProductHuntGetPostOptions',
		'ProductHuntGetUserOptions',
		'ProductHuntListCommentsOptions',
		'ProductHuntGetCollectionOptions',
		'ProductHuntListCollectionsOptions',
		'ProductHuntGetTopicOptions',
		'ProductHuntListTopicsOptions',
	]
}