workshop.service.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { WE_APP_ID } from '@shared/constants'
  2. import type { WorkshopQueryParams, WorkshopQueryResult, WorkshopItem } from '@shared/types'
  3. import { getClient } from './steam.service'
  4. // Maps our string names to steamworks.js UGCQueryType enum values
  5. const QUERY_TYPE_MAP: Record<string, number> = {
  6. RankedByVote: 0,
  7. RankedByPublicationDate: 1,
  8. RankedByTrend: 3,
  9. RankedByTotalUniqueSubscriptions: 12,
  10. RankedByTextSearch: 11,
  11. RankedByLastUpdatedDate: 19
  12. }
  13. export async function queryWorkshop(params: WorkshopQueryParams): Promise<WorkshopQueryResult> {
  14. const client = getClient()
  15. const appId = params.appId ?? WE_APP_ID
  16. const page = params.page ?? 1
  17. const queryType = QUERY_TYPE_MAP[params.queryType ?? 'RankedByPublicationDate'] ?? 1
  18. const result = await client.workshop.getAllItems(
  19. page,
  20. queryType,
  21. 13, // UGCType.All — WE items span multiple subtypes
  22. appId,
  23. appId,
  24. {
  25. searchText: params.searchText,
  26. requiredTags: params.tags,
  27. excludedTags: params.excludedTags,
  28. includeLongDescription: true
  29. }
  30. )
  31. const subscribedSet = new Set(
  32. client.workshop.getSubscribedItems().map((id) => id.toString())
  33. )
  34. return {
  35. items: result.items.filter(Boolean).map((item) => transformItem(item!, subscribedSet)),
  36. page,
  37. totalResults: result.totalResults
  38. }
  39. }
  40. export async function getWorkshopItem(publishedFileId: string): Promise<WorkshopItem | null> {
  41. const client = getClient()
  42. const item = await client.workshop.getItem(BigInt(publishedFileId), {
  43. includeLongDescription: true
  44. })
  45. if (!item) return null
  46. const subscribedSet = new Set(
  47. client.workshop.getSubscribedItems().map((id) => id.toString())
  48. )
  49. return transformItem(item, subscribedSet)
  50. }
  51. function transformItem(
  52. item: NonNullable<Awaited<ReturnType<ReturnType<typeof getClient>['workshop']['getItem']>>>,
  53. subscribedSet: Set<string>
  54. ): WorkshopItem {
  55. return {
  56. publishedFileId: item.publishedFileId.toString(),
  57. title: item.title,
  58. description: item.description,
  59. previewUrl: item.previewUrl ?? '',
  60. creatorSteamId: item.owner.steamId64.toString(),
  61. tags: item.tags ?? [],
  62. timeCreated: item.timeCreated,
  63. timeUpdated: item.timeUpdated,
  64. subscriptions: Number(item.statistics?.numSubscriptions ?? 0),
  65. upvotes: item.numUpvotes,
  66. downvotes: item.numDownvotes,
  67. isSubscribed: subscribedSet.has(item.publishedFileId.toString())
  68. }
  69. }