Type Alias GuildSingleStreamerWithFormatedRole<T>

GuildSingleStreamerWithFormatedRole<T>: T extends ServedPlatform
    ? T extends ResolvesUsersForLiveRole
        ? Omit<GuildSingleStreamer<T>, "usersForLiveRole"> & {
            usersForLiveRole: UsersForLiveRole | string[];
        }
        : GuildSingleStreamer<T>
    : never

A single streamer, as GET /data/guild/:guildId/:platform/:username answers it.

Derived from GuildSingleStreamer<T> so it is held by the same two guards as everything else here. It used to be a FOURTH hand-written list of platform arms, and it was wrong in four ways at once:

  1. It intersected the streamer with an ARRAY. UsersForLiveRole is { id, name }[], so KickStreamer & UsersForLiveRole described an object that is also an array of users. Reading .usersForLiveRole off that resolves to the model's string[], so a consumer was told "ids" while the route sends resolved { id, name } objects. The route REPLACES the field; it does not add an array alongside it.
  2. Club and twitter claimed resolution they never get - see ResolvesUsersForLiveRole.
  3. Whatnot had an arm for a platform the route answers 400 for. See ServedPlatform.
  4. It mixed the two type families, youtube alone being zod where its neighbours were Prisma-derived. GuildSingleStreamer settles that: zod, for the reason written on it.

usersForLiveRole is a union, and that is the route being honest rather than this type hedging. The handler only substitutes the resolved array when it is NON-EMPTY:

data: usersForLiveRole.length ? { ...DBStreamer, usersForLiveRole } : DBStreamer

So a creator whose live-role ids are all absent from the user table comes back with the raw string[], not with []. Discriminate on the element - typeof first === 'string' - rather than on length, because an empty array is a legitimate member of both arms.

Type Parameters