olehmell/subsocial-sdk

View on GitHub
packages/api/src/subsocial/basic.ts

Summary

Maintainability
C
7 hrs
Test Coverage
import { InnerSubsocialApi } from './inner';
import { FindStructsFns, loadAndSetPostRelatedStructs } from '../utils/loadPostStructs';
import { RawPostWithSomeDetails, RawPostWithAllDetails, AnySpaceId, AnyPostId, AnyAccountId } from '../types';
import { bnsToIds, getFirstOrUndefined } from '@subsocial/utils';
import { FindPostsQuery, FindPostsWithDetailsQuery, FindPostWithDetailsQuery } from '../filters';

export class BasicSubsocialApi extends InnerSubsocialApi {

  private structFinders: FindStructsFns = {
    findSpaces: this.findPublicSpaces.bind(this),
    findPosts: this.findPublicPosts.bind(this),
    findProfileSpaces: this.findProfileSpaces.bind(this)
  }

  /**
   * Find and load an array of information about spaces (both for Unlisted and Public spaces) from the Subsocial blockchain and IPFS by a given array of
   * space `ids`.
   *
   * @param ids - An array of the ids of the desired spaces.
   *
   * @returns An array of data about desired spaces aggregated from the Subsocial blockchain and IPFS. If there are no
   * spaces corresponding to the given array of `ids`, an empty array is returned.
   */  
  async findAllSpaces (ids: AnySpaceId[]) {
    return this.findSpaces({ ids })
  }

  /**
   * Find and load an array of information about public spaces from Subsocial blockchain and IPFS by a given array of
   * space `ids`.
   *
   * A space is considered public if it meets the following conditions:
   * - The `hidden` field on its blockchain structure is `false`.
   * - There is a corresponding JSON file that represents the space's content on IPFS.
   *
   * @param ids - An array of the ids of the desired spaces.
   *
   * @returns An array of data about desired spaces aggregated from Subsocial blockchain and IPFS. If no corresponding
   * spaces to given array of `ids`, an empty array is returned.
   */  
  async findPublicSpaces (ids: AnySpaceId[]) {
    return this.findSpaces({ ids, visibility: 'onlyPublic', withContentOnly: true })
  }

  /**
   * Find and load an array of information about unlisted spaces from Subsocial blockchain and IPFS by a given array of
   * space `ids`.
   *
   * Space is considered unlisted if it meets either of these conditions:
   * - The `hidden` field on it's blockchain structure is `true`.
   * - Or there is no corresponding JSON file that represents the space's content on IPFS.
   *
   * @param ids - An array of ids of desired spaces.
   *
   * @returns An array of data about desired spaces aggregated from Subsocial blockchain and IPFS. If no corresponding
   * spaces to given array of `ids`, an empty array is returned.
   */    
  async findUnlistedSpaces (ids: AnySpaceId[]) {
    return this.findSpaces({ ids, visibility: 'onlyUnlisted' })
  }

  /**
   * Find and load an array of information about posts (both Unlisted and Public posts) from the Subsocial blockchain and IPFS by a given array of
   * post `ids`.
   *
   *
   * @param ids - An array of the ids of the desired posts.
   *
   * @returns An array of data about desired posts aggregated from the Subsocial blockchain and IPFS. If there are no
   * posts corresponding to the given array of `ids`, an empty array is returned.
   */    
  async findAllPosts (ids: AnySpaceId[]) {
    return this.findPosts({ ids })
  }

  /**
   * Find and load an array of information about public posts from Subsocial blockchain and IPFS by a given array of
   * post `ids`.
   *
   * A post is considered public if it meets the following conditions:
   * - The `hidden` field on its blockchain structure is `false`.
   * - There is a corresponding JSON file that represents the post's content on IPFS.
   *
   * @param ids - An array of the ids of the desired posts.
   *
   * @returns An array of data about desired posts aggregated from Subsocial blockchain and IPFS. If no corresponding
   * posts to given array of `ids`, an empty array is returned.
   */    
  async findPublicPosts (ids: AnySpaceId[]) {
    return this.findPosts({ ids, visibility: 'onlyPublic', withContentOnly: true })
  }

  /**
   * Find and load an array of information about unlisted posts from Subsocial blockchain and IPFS by a given array of
   * post `ids`.
   *
   * Post is considered unlisted if it meets either of these conditions:
   * - The `hidden` field on it's blockchain structure is `true`.
   * - Or there is no corresponding JSON file that represents the post's content on IPFS.
   *
   * @param ids - An array of ids of desired posts
   *
   * @returns An array of data about desired posts aggregated from Subsocial blockchain and IPFS. If no corresponding
   * posts to given array of `ids`, an empty array is returned.
   */  
  async findUnlistedPosts (ids: AnySpaceId[]) {
    return this.findPosts({ ids, visibility: 'onlyUnlisted' })
  }

  /** Find and load posts with their extension and owner's profile (if defined). */
  async findPostsWithSomeDetails (filter: FindPostsWithDetailsQuery): Promise<RawPostWithSomeDetails[]> {
    const posts = await this.findPosts(filter)
    return loadAndSetPostRelatedStructs(posts, this.structFinders, filter)
  }

  async findPublicPostsWithSomeDetails (filter: FindPostsWithDetailsQuery): Promise<RawPostWithSomeDetails[]> {
    return this.findPostsWithSomeDetails({ ...filter, visibility: 'onlyPublic' })
  }

  async findUnlistedPostsWithSomeDetails (filter: FindPostsWithDetailsQuery): Promise<RawPostWithSomeDetails[]> {
    return this.findPostsWithSomeDetails({ ...filter, visibility: 'onlyUnlisted' })
  }

  async findPostsWithAllDetails ({ ids, visibility }: FindPostsQuery): Promise<RawPostWithAllDetails[]> {
    return this.findPostsWithSomeDetails({ ids, withSpace: true, withOwner: true, visibility }) as Promise<RawPostWithAllDetails[]>
  }

  async findPublicPostsWithAllDetails (ids: AnyPostId[]): Promise<RawPostWithAllDetails[]> {
    return this.findPostsWithAllDetails({ ids, visibility: 'onlyPublic' })
  }

  async findUnlistedPostsWithAllDetails (ids: AnyPostId[]): Promise<RawPostWithAllDetails[]> {
    return this.findPostsWithAllDetails({ ids, visibility: 'onlyUnlisted' })
  }

  /**
   * Find and load an array of information about profile spaces from the Subsocial blockchain and IPFS by a given array of
   * account ids `accountsIds`.
   *
   * A profile space is just a space set to a profile. 
   *
   * @param accountsIds - An array of the account ids related to the desired profile spaces
   *
   * @returns An array of data about desired profile spaces aggregated from the Subsocial blockchain and IPFS. If there are no
   * profile spaces corresponding to the given array of `spaceIds`, an empty array is returned.
   */  
  async findProfileSpaces (accountIds: AnyAccountId[]) {
    const spaceIds = await this.substrate.profileSpaceIdsByAccounts(accountIds)
    return this.findAllSpaces(bnsToIds(spaceIds))
  }

  // Functions that return a single element

  /**
   * Find and load information about a public space from Subsocial blockchain and IPFS using space id.
   *
   * Space is considered public if it meets these conditions:
   * - The `hidden` field on it's blockchain structure is `false`.
   * - And there is a corresponding JSON file that represents the space's content on IPFS.
   *
   * @param id - Id of desired space.
   *
   * @returns Data about desired space aggregated from blockchain and IPFS. If no corresponding space to given id,
   * `undefined` is returned.
   */  
  async findPublicSpace (id: AnySpaceId) {
    return getFirstOrUndefined(await this.findPublicSpaces([ id ]))
  }

  /**
   * Find and load information about an unlisted space from blockchain and from IPFS by a given space id.
   *
   * Space is considered unlisted if it meets either of these conditions:
   * - The `hidden` field on it's blockchain structure is `true`.
   * - Or there is no corresponding JSON file that represents the space's content on IPFS.
   *
   * @param id - Id of desired space.
   *
   * @returns Data about a desired space aggregated from blockchain and IPFS. If no corresponding space to given id,
   * `undefined` is returned.
   */
  async findUnlistedSpace (id: AnySpaceId) {
    return getFirstOrUndefined(await this.findUnlistedSpaces([ id ]))
  }

  /**
   * Find and load information about a public post from Subsocial blockchain and IPFS using post id.
   *
   * Post is considered public if it meets the next conditions:
   * - The `hidden` field on it's blockchain structure is `false`.
   * - And there is a corresponding JSON file that represents the post's content on IPFS.
   *
   * @param id - Id of desired post.
   *
   * @returns Data about desired post aggregated from blockchain and IPFS. If no corresponding post to given id,
   * `undefined` is returned.
   */  
  async findPublicPost (id: AnySpaceId) {
    return getFirstOrUndefined(await this.findPublicPosts([ id ]))
  }

  /**
   * Find and load information about an unlisted post from blockchain and from IPFS by a given post id.
   *
   * Post is considered unlisted if it meets either of these conditions:
   * - The `hidden` field on it's blockchain structure is `true`.
   * - Or there is no corresponding JSON file that represents the post's content on IPFS.
   *
   * @param id - Id of desired post.
   *
   * @returns Data about desired post aggregated from blockchain and IPFS. If no corresponding post to given id,
   * `undefined` is returned.
   */  
  async findUnlistedPost (id: AnySpaceId) {
    return getFirstOrUndefined(await this.findUnlistedPosts([ id ]))
  }

  async findPostWithSomeDetails ({ id, ...opts }: FindPostWithDetailsQuery) {
    return getFirstOrUndefined(await this.findPostsWithSomeDetails({ ids: [ id ], ...opts }))
  }

  async findPublicPostWithSomeDetails ({ id, ...opts }: FindPostWithDetailsQuery) {
    return getFirstOrUndefined(await this.findPublicPostsWithSomeDetails({ ids: [ id ], ...opts }))
  }

  async findUnlistedPostWithSomeDetails ({ id, ...opts }: FindPostWithDetailsQuery) {
    return getFirstOrUndefined(await this.findUnlistedPostsWithSomeDetails({ ids: [ id ], ...opts }))
  }

  async findPostWithAllDetails (id: AnyPostId) {
    return getFirstOrUndefined(await this.findPostsWithAllDetails({ ids: [ id ] }))
  }

  async findPublicPostWithAllDetails (id: AnyPostId) {
    return getFirstOrUndefined(await this.findPublicPostsWithAllDetails([ id ]))
  }

  async findUnlistedPostWithAllDetails (id: AnyPostId) {
    return getFirstOrUndefined(await this.findUnlistedPostsWithAllDetails([ id ]))
  }

  async findProfileSpace (accountId: AnyAccountId) {
    return getFirstOrUndefined(await this.findProfileSpaces([ accountId ]))
  }
}