Source

modules/ProjectManager.ts

import { ProjectAPI } from "../core/apis/project.api";
import { CollectionListResponseData, CreateProjectParams, CreateProjectParamsByAPIKey, ProjectResponse, UpdateProjectParams, UpdateProjectByAPIKey } from "../types/ProjectTypes";
import { EnvTypes } from "../typesBundle";

/**
 * Create ProjectManager module
 * @class ProjectManager
 * @param {EnvTypes} env Environment type (DEV / STAGING / PREPROD / PROD)
 * @example <caption>ProjectManager Instantiation</caption>
  const projectManager = new ProjectManager(EnvTypes.STAGING);
 *
 */
export class ProjectManager {
  private projectAPI: ProjectAPI;

  constructor(env: EnvTypes) {
    this.projectAPI = new ProjectAPI(env);
  }

  /**
   * @summary Get project details information by project ID
   * @param {number} id unique ID of project
   * @returns {ProjectResponse} Project details information (basic info of project, number of collections allow....)
   * @throws {string} Exception: Project id is required
   * @example <caption>Sample of getProjectDetails(id) on Staging env</caption> 
    const projectManager: ProjectManager = new ProjectManager(EnvTypes.STAGING);
    const starkKey: string = config.stark_key; // Your stark key in Myria system

    const projectId = 1;

    console.log("Getting project details information...");
    const data: CollectionListResponseData = await projectManager.getProjectDetail(projectId);

    console.log("Project details response:");
    console.log(JSON.stringify(data, null, 2));
   */
  public async getProjectDetail(id: string): Promise<ProjectResponse | undefined> {
    
    if(!id) {
      throw new Error("Project Id is required");
    }

    const projectDetail = await this.projectAPI.getProjectDetail(id);
    return projectDetail;
  }

  /**
   * @summary Create project by using Myria user Id and API key
   * @param {CreateProjectParamsByAPIKey} payload Create project request params with API Key
   * @returns {ProjectResponse} Project details (project basic info, number of collections allow....)
   * @throws {string} Exception: API Key is required
   * @throws {string} Exception: Company name is required
   * @throws {string} Exception: Contact email is required
   * @throws {string} Exception: Myria User ID is required
   * @throws {string} Exception: Name is required
   * @example <caption>Sample of createProjectByApiKey({}) on Staging env</caption> 
   * 
    const projectManager: ProjectManager = new ProjectManager(EnvTypes.STAGING);

    const params: CreateProjectParamsByAPIKey = {
      name: "Game Project Test",
      companyName: "GamePartnerWithMyria",
      contactEmail: "world.game@myria.com",
      apiKey: 'Your api key', // could generate on the myria portal for partner
      myriaUserID: 'your unique user ID in myria system',
    };

    console.log("Getting project details information...");
    const data: ProjectResponse = await projectManager.createProjectByApiKey(params);

    console.log("New project details response:");
    console.log(JSON.stringify(data, null, 2));
   */
  public async createProjectByApiKey(
    payload: CreateProjectParamsByAPIKey
  ): Promise<ProjectResponse | undefined> {

    if (!payload.apiKey) {
      throw new Error("API Key is required");
    }

    if (!payload.companyName) {
      throw new Error("Company name is required");
    }

    if (!payload.contactEmail) {
      throw new Error("Contact email is required")
    }

    if (!payload.myriaUserID) {
      throw new Error("Myria User ID is required")
    }

    if (!payload.name) {
      throw new Error("Name is required");
    } 

    const createdProjectResponse = await this.projectAPI.createProjectV2(payload);

    if (createdProjectResponse?.status !== 'success') {
      throw new Error('Create project failure => ' + JSON.stringify(createdProjectResponse));
    }

    return createdProjectResponse;
  }

  /**
   * @summary Update project by using Myria user Id and API key
   * @param {UpdateProjectByAPIKey} payload Update project request params
   * @returns {ProjectResponse} Project details information (basic info of project, number of collections allow....)
   * @throws {string} Exception: API Key is required
   * @throws {string} Exception: Company name is required
   * @throws {string} Exception: Contact email is required
   * @throws {string} Exception: Myria User ID is required
   * @throws {string} Exception: Name is required
   * @throws {string} Http Status Code 500: Create project failure => ${server error}
   * @example <caption>Sample of updateProjectByApiKey({}) on Staging env</caption> 
   * 
    const projectManager: ProjectManager = new ProjectManager(EnvTypes.STAGING);

    const params: UpdateProjectByAPIKey = {
      id: 1,
      name: "Game Project Test",
      companyName: "GamePartnerWithMyria",
      contactEmail: "world.game@myria.com",
      apiKey: 'Your api key', // could generate on the myria portal
      myriaUserID: 'your unique user ID in myria system',
    };

    console.log("Getting project details information...");
    const data: ProjectResponse = await projectManager.updateProjectByApiKey(params);

    console.log("New project details response:");
    console.log(JSON.stringify(data, null, 2));
   */
  public async updateProjectByApiKey(
    payload: UpdateProjectByAPIKey
  ): Promise<ProjectResponse | undefined> {

    if (!payload.apiKey) {
      throw new Error("API Key is required");
    }

    if (!payload.companyName) {
      throw new Error("Company name is required");
    }

    if (!payload.contactEmail) {
      throw new Error("Contact email is required")
    }

    if (!payload.myriaUserID) {
      throw new Error("Myria User ID is required")
    }

    if (!payload.name) {
      throw new Error("Name is required");
    } 

    const updatedProjectResponse = await this.projectAPI.updateProjectV2(payload);

    if (updatedProjectResponse?.status !== 'success') {
      throw new Error('Create project failure => ' + JSON.stringify(updatedProjectResponse));
    }

    return updatedProjectResponse;
  }

  /**
   * @summary Get Project List By Myria User ID and API Key
   * @param {string} userID Unique ID (uuid) of myria user
   * @param {string} apiKey Partner's API key
   * @throws {string} Exception: User ID is required
   * @throws {string} Exception: Partner API Key is required 
   * @throws {string} Http Status Code 401: x-api-key is not found (x-api-key is required to secure the call to Myria marketplace service)
   * @throws {string} Http Status Code 403: The API KEY (example: aed.....) is unavailable means the API key is invalid or has been deactivated
   * @example <caption>Sample of getProjectsByUserIDAndApiKey({}) on Staging env</caption> 
   * 
    const projectManager: ProjectManager = new ProjectManager(EnvTypes.STAGING);

    const myriaUserID = 'uuid myria user ID'; // 'your unique user ID in myria system';
    const apiKey = 'Your api key'; // could generate on the myria portal


    console.log("Getting project list data...");
    const data: ProjectResponse = await projectManager.getProjectsByUserIDAndApiKey(myriaUserID, apiKey);

    console.log("Data project list response:");
    console.log(JSON.stringify(data, null, 2));
   */
  public async getProjectsByUserIDAndApiKey(userID: string, apiKey: string):
     Promise<ProjectResponse | undefined> {
    if (!userID) {
      throw new Error('Myria User ID is required');
    }

    if (!apiKey) {
      throw new Error('Partner API Key is required');
    }

    const projectData = await this.projectAPI.getProjectsByUserIDAndApiKey(userID, apiKey);

    if (projectData?.status !== 'success') {
      throw new Error("Cannot get project list - internal server error");
    }

    return projectData;
  }

  /**
   * @summary Create the project by using a Stark key
   * @param {CreateProjectParams} payload create project request input (companyName / name / contactEmail / Stark key)
   * @throws {string} Exception: CompanyName is required
   * @throws {string} Exception: Name is required
   * @throws {string} Exception: Contact email address is required
   * @throws {string} Exception: StarkKey is required
   * @throws {string} Exception: Create project failed with internal server error
   * @returns {ProjectResponse | undefined} Project information data
   * @example <caption>Sample of createProject() on testnet environment</caption>
   * 
    const projectManager: ProjectManager = new ProjectManager(EnvTypes.STAGING);
    const starkKey: string = config.stark_key; // Your stark key in Myria system

    const params: CreateProjectParams = {
      name: "Game Project Test",
      companyName: "GamePartnerWithMyria",
      contactEmail: "world.game@myria.com",
      starkKey: starkKey,
    };

    console.log("Creating the project...");
    const newProjectResponse: ProjectResponse = await projectManager.createProject(params);

    console.log("Created project response:");
    console.log(JSON.stringify(newProjectResponse, null, 2));
   */
  public async createProject(
    payload: CreateProjectParams
  ): Promise<ProjectResponse | undefined> {

    if (!payload.companyName) {
      throw new Error("CompanyName is required");
    }

    if (!payload.name) {
      throw new Error("Name is required");
    }

    if (!payload.contactEmail) {
      throw new Error("Contact email address is required");
    }

    if (!payload.starkKey) {
      throw new Error("StarkKey is required");
    }

    let createProjectData: any;

    try {
      const createProjectResponse = await this.projectAPI.createProject(
        payload
      );
      if (createProjectResponse?.status === "success") {
        createProjectData = createProjectResponse?.data;
      } else {
        throw new Error("Create project failed with internal server error");
      }
    } catch (error) {
      throw new Error(error);
    }

    return createProjectData;
  }

    /**
   * @summary Update the project by using project ID and the stark key
   * @param {UpdateProjectParams} payload update projects request input (id / companyName / name / contactEmail / Stark key)
   * @throws {string} Exception: Project Id is required
   * @throws {string} Exception: Company name is required
   * @throws {string} Exception: Name is required
   * @throws {string} Exception: Contact email address is required
   * @throws {string} Exception: StarkKey is required
   * @returns {ProjectResponse | undefined} Project information data
   * @example <caption>Sample of updateProject({}) on Staging testnet environment</caption>
   * 
    const projectManager: ProjectManager = new ProjectManager(EnvTypes.STAGING);
    const starkKey: string = config.stark_key; // Your stark key in Myria system

    const params: UpdateProjectParams = {
      id: 1,
      name: "Update Game Project Test",
      companyName: "GamePartnerWithMyria",
      contactEmail: "world.game@myria.com",
      starkKey: starkKey,
    };

    console.log("Update the project...");
    const updatedProjectResponse: ProjectResponse = await projectManager.updateProject(params);

    console.log("Updated project response:");
    console.log(JSON.stringify(updatedProjectResponse, null, 2));
   */
  public async updateProject(
    payload: UpdateProjectParams
  ): Promise<ProjectResponse | undefined> {

    if(!payload.id) {
      throw new Error("Project Id is required");
    }

    if(!payload.companyName) {
      throw new Error("Company name is required");
    }

    if(!payload.contactEmail) {
      throw new Error("Contact email address is required");
    }

    if(!payload.name) {
      throw new Error("Name is required!");
    }

    if(!payload.starkKey) {
      throw new Error("StarkKey is required!");
    }

    let updateProject: any;

    try {
      const updateProjectResponse = await this.projectAPI.updateProject(payload);

      if(updateProjectResponse?.status === "success") {
        updateProject = updateProjectResponse?.data;
      } else {
        throw new Error("Update project failed with internal server error");
      }

      return updateProject;
      
    } catch (err) {
      throw new Error(err);
    }
  }

  /**
   * @description Function to get the list of collections by project ID
   * @param {number} id unique ID of project
   * @returns {CollectionListResponseData} Project details information which include collection list
   * @throws {string} Exception: Project id is required
   * @throws {string} Exception: Get collection list failed with internal server error
   * @throws {string} Exception: Get collection list failed with ${serverError}
   * @example <caption>Sample of getCollectionListByProjectId() on Staging env</caption>
    
    const projectManager: ProjectManager = new ProjectManager(EnvTypes.STAGING);
    const starkKey: string = config.stark_key; // Your stark key in Myria system

    const projectId = 1;

    console.log("Getting list of the collection...");
    const data: CollectionListResponseData = await projectManager.getCollectionListByProjectId(projectId);

    console.log("List of collection response:");
    console.log(JSON.stringify(data, null, 2));
   */
  public async getCollectionListByProjectId (id: number): Promise<CollectionListResponseData> {
    if(!id) {
      throw new Error('Project id is required!');
    }

    let collectionListInfo: CollectionListResponseData;

    try {
      const result = await this.projectAPI.getCollectionListByProjectId(id);
      if(result.status === 'success') {
        collectionListInfo = result.data;
      } else {
        throw new Error('Get collection list failed with internal server error');
      }
    } catch (err) {
      throw new Error(`Get collection list failed with ${err}`);
    }

    return collectionListInfo;
  }
}