Source: managers/web-links.ts

/**
 * @fileoverview Manager for the Web Links Resource
 */

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

import BoxClient from '../box-client';
import urlPath from '../util/url-path';

// ------------------------------------------------------------------------------
// Private
// ------------------------------------------------------------------------------

const BASE_PATH = '/web_links';

// ------------------------------------------------------------------------------
// Public
// ------------------------------------------------------------------------------

/**
 * Simple manager for interacting with all 'Weblinks' endpoints and actions.
 *
 * @constructor
 * @param {BoxClient} client - The Box API Client that is responsible for making calls to the API
 * @returns {void}
 */
class WebLinks {
  client: BoxClient;

  constructor(client: BoxClient) {
    this.client = client;
  }

  /**
   * Creates a web link object within a given folder.
   *
   * API Endpoint: '/web_links'
   * Method: POST
   *
   * @param {string} url - URL you want the web link to point to. Must include http:// or https://
   * @param {string} parentID - The ID of the parent folder where you're creating the web link
   * @param {Object} [options] - Additional parameters
   * @param {string} [options.name] - Name for the web link. Will default to the URL if empty.
   * @param {string} [options.description] - Description of the web link. Will provide more context to users about the web link.
   * @param {Function} [callback] - Passed the new web link information if it was acquired successfully, error otherwise
   * @returns {Promise<Object>} A promise resolving to the created weblink object
   */
  create(
    url: string,
    parentID: string,
    options?: {
      name?: string;
      description?: string;
    },
    callback?: Function
  ) {
    var apiPath = urlPath(BASE_PATH),
      params = {
        body: {
          url,
          parent: {
            id: parentID,
          },
        },
      };

    Object.assign(params.body, options);

    return this.client.wrapWithDefaultHandler(this.client.post)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Use to get information about the web link.
   *
   * API Endpoint: '/web_links/:weblinkID'
   * Method: GET
   *
   * @param {string} weblinkID - The Box ID of web link being requested
   * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
   * @param {Function} [callback] - Passed the web-link information if it was acquired successfully, error otherwise
   * @returns {Promise<Object>} A promise resolving to the weblink object
   */
  get(weblinkID: string, options?: Record<string, any>, callback?: Function) {
    var apiPath = urlPath(BASE_PATH, weblinkID),
      params = {
        qs: options,
      };

    return this.client.wrapWithDefaultHandler(this.client.get)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Updates information for a web link.
   *
   * API Endpoint: '/web_links/:weblinkID'
   * Method: PUT
   *
   * @param {string} weblinkID - The Box ID of the web link being updated
   * @param {Object} updates - Fields of the weblink to update
   * @param {string} [updates.name] - Name for the web link. Will default to the URL if empty.
   * @param {string} [updates.description] - Description of the web link. Will provide more context to users about the web link.
   * @param {Function} [callback] - Passed the updated web link information if it was acquired successfully, error otherwise
   * @returns {Promise<Object>} A promise resolving to the updated web link object
   */
  update(
    weblinkID: string,
    updates?: {
      name?: string;
      description?: string;
      collections?: string[];
    },
    callback?: Function
  ) {
    var apiPath = urlPath(BASE_PATH, weblinkID),
      params = {
        body: updates,
      };

    return this.client.wrapWithDefaultHandler(this.client.put)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Deletes a web link and moves it to the trash
   *
   * API Endpoint: '/web_links/:weblinkID'
   * Method: DELETE
   *
   * @param {string} weblinkID - The Box ID of the web link being moved to the trash
   * @param {Function} [callback] - Empty body passed if successful, error otherwise
   * @returns {Promise<Object>} A promise resolving to nothing
   */
  delete(weblinkID: string, callback?: Function) {
    var apiPath = urlPath(BASE_PATH, weblinkID);

    return this.client.wrapWithDefaultHandler(this.client.del)(
      apiPath,
      null,
      callback
    );
  }

  /**
   * Move a web link into a new parent folder.
   *
   * API Endpoint: '/web_links/:webLinkID'
   * Method: PUT
   *
   * @param {string} webLinkID - The Box ID of the web link being requested
   * @param {string} newParentID - The Box ID for the new parent folder. '0' to move to All Files.
   * @param {Function} [callback] - Passed the updated web link information if it was acquired successfully
   * @returns {Promise<Object>} A promise resolving to the updated web link object
   */
  move(webLinkID: string, newParentID: string, callback?: Function) {
    var params = {
      body: {
        parent: {
          id: newParentID,
        },
      },
    };
    var apiPath = urlPath(BASE_PATH, webLinkID);
    return this.client.wrapWithDefaultHandler(this.client.put)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Copy a web link into a new, different folder
   *
   * API Endpoint: '/web_links/:webLinkID/copy
   * Method: POST
   *
   * @param {string} webLinkID - The Box ID of the web link being requested
   * @param {string} newParentID - The Box ID for the new parent folder. '0' to copy to All Files.
   * @param {Object} [options] - Optional parameters for the copy operation, can be left null in most cases
   * @param {string} [options.name] - A new name to use if there is an identically-named item in the new parent folder
   * @param {Function} [callback] - passed the new web link info if call was successful
   * @returns {Promise<Object>} A promise resolving to the new web link object
   */
  copy(
    webLinkID: string,
    newParentID: string,
    options?: {
      name?: string;
    },
    callback?: Function
  ) {
    options = options || {};

    (options as Record<string, any>).parent = {
      id: newParentID,
    };

    var params = {
      body: options,
    };
    var apiPath = urlPath(BASE_PATH, webLinkID, '/copy');
    return this.client.wrapWithDefaultHandler(this.client.post)(
      apiPath,
      params,
      callback
    );
  }

  /**
   * Add a web link to a given collection
   *
   * API Endpoint: '/web_links/:webLinkID'
   * Method: PUT
   *
   * @param {string} webLinkID - The web link to add to the collection
   * @param {string} collectionID - The collection to add the web link to
   * @param {Function} [callback] - Passed the updated web link if successful, error otherwise
   * @returns {Promise<Object>} A promise resolving to the updated web link object
   */
  addToCollection(
    webLinkID: string,
    collectionID: string,
    callback?: Function
  ) {
    return this.get(webLinkID, { fields: 'collections' })
      .then((data: any /* FIXME */) => {
        var collections = data.collections || [];

        // Convert to correct format
        collections = collections.map((c: any /* FIXME */) => ({
          id: c.id,
        }));

        if (!collections.find((c: any /* FIXME */) => c.id === collectionID)) {
          collections.push({ id: collectionID });
        }

        return this.update(webLinkID, { collections });
      })
      .asCallback(callback);
  }

  /**
   * Remove a web link from a given collection
   *
   * API Endpoint: '/web_links/:webLinkID'
   * Method: PUT
   *
   * @param {string} webLinkID - The web link to remove from the collection
   * @param {string} collectionID - The collection to remove the web link from
   * @param {Function} [callback] - Passed the updated web link if successful, error otherwise
   * @returns {Promise<Object>} A promise resolving to the updated web link object
   */
  removeFromCollection(
    webLinkID: string,
    collectionID: string,
    callback?: Function
  ) {
    return this.get(webLinkID, { fields: 'collections' })
      .then((data: any /* FIXME */) => {
        var collections = data.collections || [];
        // Convert to correct object format and remove the specified collection
        collections = collections
          .map((c: any /* FIXME */) => ({ id: c.id }))
          .filter((c: any /* FIXME */) => c.id !== collectionID);

        return this.update(webLinkID, { collections });
      })
      .asCallback(callback);
  }
}

export = WebLinks;