storage/index.js

import updateAPIEndpoint from "./config.js";
import * as Config from "./config.js";
import axios from "axios";

/**
 * The sCStorage instance communicates with the storage API.
 */
export class sCStorage {
  /**
   * Opens a new schmuckliCloud storage instance. It can be used to manage then all the data in a defined project.
   * @param {String} app_id The APP ID, which was created for a client app in the schmuckliCloud console.
   * @param {String} app_secret The APP Secret, which was created for a client app in the schmuckliCloud console.
   * @param {String} [service_url] If you want to replace the backend url instead of `https://api.schmuckli.cloud/client_api/v1/data/`, provide here the new path.
   */
  constructor(app_id, app_secret, service_url) {
    this.appid = app_id;
    this.appsecret = app_secret;

    if (service_url) {
      updateAPIEndpoint(service_url);
    }
  }

  /**
  Set the dataset, which should be used for the further data operations.
  @param {String} dataset_name The name of the dataset (Do not use the id)
  */
  setDataset(dataset_name) {
    this.dataset = dataset_name;
  }

  /**
   * Binds the authentication token to the storage object, to use the protected dataset, reserved for the user.
   * @param {string} auth_token The authentication session token from the auth library.
   * @param {boolean} [not_reset] By default, it will reset the dataset. If you want to use the authentication dataset, you must provide a empty dataset string.
   */
  setAuthToken(auth_token, not_reset) {
    this.auth_token = auth_token;
    if (not_reset === false || not_reset === undefined) {
      this.dataset = "";
    }
  }

  /**
   * When you plan to use the future requests with a given share password, assign first this password here and call later the requests as usual.
   * @param {string} password The clear password, which should be used.
   */
  setSharePassword(password) {
    this.sharePassword = password;
  }

  /**
  Set the bucket id which later should be used to manage data.
  @param {Number} bucket_id The number of the bucket id
  */
  setBucket(bucket_id) {
    this.bucket_id = bucket_id;
  }

  /**
  This method lets you retrieve all rows from a container.
  @param {String} container_name The container name, created via the schmuckliCloud console
  @param {String|Array|Object} [sorting] Sort the entries ascending ('asc' by default) or descending ('desc').
  @param {Number} [start] Define a start index.
  @param {Number} [limit] Define a maximum of showing results.
  @param {Array} [exclude] Columns, which should be excluded from the results.
  @return {Promise<sCResult>} The function returns you a promise. You can use the 'then' method, to wait for it. Afterwards you get the result.
  */
  getAll(container_name, sorting, start, limit, exclude) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (sorting !== undefined) {
        if (sorting instanceof Array || sorting instanceof Object) {
          sorting = JSON.stringify(sorting);
        }
      } else {
        sorting = "";
      }

      if (start === undefined) {
        start = "";
      }
      if (limit === undefined) {
        limit = "";
      }

      if (exclude !== undefined) {
        exclude = JSON.stringify(exclude);
      } else {
        exclude = JSON.stringify([]);
      }

      axios
        .get(
          Config.API_ENDPOINT +
            "?bucket=" +
            global_this.bucket_id +
            "&dataset=" +
            encodeURI(global_this.dataset) +
            "&container=" +
            container_name +
            "&order=" +
            sorting +
            "&start=" +
            start +
            "&limit=" +
            limit +
            "&exclude=" +
            exclude +
            "&share_password=" +
            (global_this.sharePassword || ""),
          {
            headers: {
              appid: global_this.appid,
              appsecret: global_this.appsecret,
              authtoken: global_this.auth_token,
            },
          }
        )
        .then(function (result) {
          if (result.status === 200) {
            var result = new sCResult(
              result.data.status,
              result.data.message,
              result.data.body
            );
            resolve(result);
          } else {
            reject(new Error("There was a problem with the API endpoint."));
          }
        });
    });
  }

  /**
  This method lets you retrieve data with filters.
  @param {String} container_name The container name, created via the schmuckliCloud console
  @param {Array} filter A filter is an array, defining which entries should be displayed.
  @param {String} [sorting] Sort the entries ascending ('asc' by default) or descending ('desc').
  @param {Number} [start] Define a start index.
  @param {Number} [limit] Define a maximum of showing results.
  @param {Array} [exclude] Columns, which should be excluded from the results.
  @param {String} [filter_connect] Sets the connection between the filters. (Default: OR)
  @return {Promise<sCResult>} The function returns you a promise. You can use the 'then' method, to wait for it.
  */
  get(container_name, filter, sorting, start, limit, exclude, filter_connect) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (filter === undefined || filter == 0) {
        reject(
          new Error(
            "Please define at least one condition. If you want to show all entries, please use the method 'getAll'"
          )
        );
      }

      if (!(filter instanceof Array)) {
        reject(new Error("Please provide an array containing the conditions."));
      }
      var encodedFilter = encodeURI(JSON.stringify(filter));

      if (sorting !== undefined) {
        if (sorting instanceof Array || sorting instanceof Object) {
          sorting = JSON.stringify(sorting);
        }
      } else {
        sorting = "";
      }

      if (start === undefined) {
        start = "";
      }
      if (limit === undefined) {
        limit = "";
      }

      if (filter_connect == undefined) {
        filter_connect = "OR";
      }

      if (exclude !== undefined) {
        exclude = JSON.stringify(exclude);
      } else {
        exclude = JSON.stringify([]);
      }

      axios
        .get(
          Config.API_ENDPOINT +
            "?bucket=" +
            global_this.bucket_id +
            "&dataset=" +
            encodeURI(global_this.dataset) +
            "&container=" +
            encodeURI(container_name) +
            "&filter=" +
            encodedFilter +
            "&filter_connect=" +
            filter_connect +
            "&order=" +
            sorting +
            "&start=" +
            start +
            "&limit=" +
            limit +
            "&exclude=" +
            exclude +
            "&share_password=" +
            (global_this.sharePassword || ""),
          {
            headers: {
              appid: global_this.appid,
              appsecret: global_this.appsecret,
              authtoken: global_this.auth_token,
            },
          }
        )
        .then(function (result) {
          if (result.status === 200) {
            var result = new sCResult(
              result.data.status,
              result.data.message,
              result.data.body
            );
            resolve(result);
          } else {
            reject(
              new Error(
                "There was a problem with the API endpoint. Following error message was sent: " +
                  result.data.message
              )
            );
          }
        });
    });
  }

  /**
     This method returns the amount of data rows with/out filter.
    @param {String} container_name The container name, created via the schmuckliCloud console
    @param {Array} filter A filter is an array, defining which entries should be displayed.
    @param {String} [filter_connect] Sets the connection between the filters. (Default: OR)
    @return {Promise<sCResult>} The function returns you a promise. Get the amount with the `response.data.count` parameter.
    */
  count(container_name, filter, filter_connect) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (!(filter instanceof Array)) {
        reject(new Error("Please provide an array containing the conditions."));
      }
      var encodedFilter = encodeURI(JSON.stringify(filter));

      axios
        .get(
          Config.API_ENDPOINT +
            "?bucket=" +
            global_this.bucket_id +
            "&dataset=" +
            encodeURI(global_this.dataset) +
            "&container=" +
            encodeURI(container_name) +
            "&filter=" +
            encodedFilter +
            "&filter_connect=" +
            filter_connect +
            "&count=true" +
            "&share_password=" +
            (global_this.sharePassword || ""),
          {
            headers: {
              appid: global_this.appid,
              appsecret: global_this.appsecret,
              authtoken: global_this.auth_token,
            },
          }
        )
        .then(function (result) {
          if (result.status === 200) {
            var result = new sCResult(
              result.data.status,
              result.data.message,
              result.data.body
            );
            resolve(result);
          } else {
            reject(
              new Error(
                "There was a problem with the API endpoint. Following error message was sent: " +
                  result.data.message
              )
            );
          }
        });
    });
  }

  /**
     This method returns the SUM of field with/out filter.
    @param {String} container_name The container name, created via the schmuckliCloud console
    @param {Array} filter A filter is an array, defining which entries should be displayed.
    @param {String} field_name The name of the field, which should be used for the result.
    @param {String} [filter_connect] Sets the connection between the filters. (Default: OR)
    @return {Promise<sCResult>} The function returns you a promise. Get the amount with the `response.data.count` parameter.
    */
  sum(container_name, filter, field_name, filter_connect) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (field_name === undefined || field_name === "") {
        reject(new Error("Please define a field name."));
      }

      if (!(filter instanceof Array)) {
        reject(new Error("Please provide an array containing the conditions."));
      }
      var encodedFilter = encodeURI(JSON.stringify(filter));

      axios
        .get(
          Config.API_ENDPOINT +
            "?bucket=" +
            global_this.bucket_id +
            "&dataset=" +
            encodeURI(global_this.dataset) +
            "&container=" +
            encodeURI(container_name) +
            "&filter=" +
            encodedFilter +
            "&filter_connect=" +
            filter_connect +
            "&sum=" +
            field_name +
            "&share_password=" +
            (global_this.sharePassword || ""),
          {
            headers: {
              appid: global_this.appid,
              appsecret: global_this.appsecret,
              authtoken: global_this.auth_token,
            },
          }
        )
        .then(function (result) {
          if (result.status === 200) {
            var result = new sCResult(
              result.data.status,
              result.data.message,
              result.data.body
            );
            resolve(result);
          } else {
            reject(
              new Error(
                "There was a problem with the API endpoint. Following error message was sent: " +
                  result.data.message
              )
            );
          }
        });
    });
  }

  /**
    This method returns the AVG of field with/out filter.
    @param {String} container_name The container name, created via the schmuckliCloud console
    @param {Array} filter A filter is an array, defining which entries should be displayed.
    @param {String} field_name The name of the field, which should be used for the result.
    @param {String} [filter_connect] Sets the connection between the filters. (Default: OR)
    @return {Promise<sCResult>} The function returns you a promise. Get the amount with the `response.data.count` parameter.
    */
  avg(container_name, filter, field_name, filter_connect) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (field_name === undefined || field_name === "") {
        reject(new Error("Please define a field name."));
      }

      if (!(filter instanceof Array)) {
        reject(new Error("Please provide an array containing the conditions."));
      }
      var encodedFilter = encodeURI(JSON.stringify(filter));

      axios
        .get(
          Config.API_ENDPOINT +
            "?bucket=" +
            global_this.bucket_id +
            "&dataset=" +
            encodeURI(global_this.dataset) +
            "&container=" +
            encodeURI(container_name) +
            "&filter=" +
            encodedFilter +
            "&filter_connect=" +
            filter_connect +
            "&avg=" +
            field_name +
            "&share_password=" +
            (global_this.sharePassword || ""),
          {
            headers: {
              appid: global_this.appid,
              appsecret: global_this.appsecret,
              authtoken: global_this.auth_token,
            },
          }
        )
        .then(function (result) {
          if (result.status === 200) {
            var result = new sCResult(
              result.data.status,
              result.data.message,
              result.data.body
            );
            resolve(result);
          } else {
            reject(
              new Error(
                "There was a problem with the API endpoint. Following error message was sent: " +
                  result.data.message
              )
            );
          }
        });
    });
  }

  /**
   * Creates a share link with the containing rows.
   * @param {String} container_name The container name, where the rows are located.
   * @param {Array} rows The row id's, which should be shared via a link.
   * @param {string} [password] Sets a password. Leave blank, if you want don't want to set a password.
   * @param {string} [expire] Sets a expire date. Leave blank, if you want don't want to set a expire date. The link will then be available for an unlimited time.
   * @return {Promise<sCResult>} The function returns you a promise with the result object.
   */
  createShareLink(container_name, rows, password, expire) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (!(rows instanceof Array)) {
        reject(new Error("Please provide an array with row id's."));
      }

      if (password == undefined) {
        password = "";
      }

      if (expire == undefined) {
        expire = "";
      }

      var fRows = rows.join(", ");

      axios({
        url: Config.API_ENDPOINT + "share.php",
        method: "POST",
        headers: {
          appid: global_this.appid,
          appsecret: global_this.appsecret,
          authtoken: global_this.auth_token,
        },
        data: {
          bucket: global_this.bucket_id,
          container: encodeURI(container_name),
          rows: fRows,
          password: password,
          expire: expire,
        },
      }).then(function (response) {
        var data = response.data;
        if (response.status === 200) {
          resolve(new sCResult(data.status, data.message, data.body));
        } else {
          reject(
            new Error(
              "There was an error while creating a share link. Following error message: " +
                data.message
            )
          );
        }
      });
    });
  }

  /**
   * Updates an existing share with rows, password and/or expire date.
   * @param {string} container_name The name of the container, where the rows are stored.
   * @param {number} share_id The id of the share, which should be updated.
   * @param {array} new_rows The ids of the new rows, which should be added.
   * @param {array} remove_rows The ids of the existing rows, which should be removed.
   * @param {string} [password] Sets a new password. Leave blank, if you want to keep the current password.
   * @param {string} [expire] Sets a new expire date. Leave blank, if you want to keep the current expire date.
   * @param {string} [custom_link] Sets an alias (custom link) for the share, that it can be accessed via that.
   * @return {Promise<sCResult>} The function returns you a promise with the result object.
   */
  updateShareLink(
    container_name,
    share_id,
    new_rows,
    remove_rows,
    password,
    expire,
    custom_link
  ) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (share_id == undefined || share_id == "") {
        reject(new Error("Please define a share id."));
      }

      if (!(new_rows instanceof Array) || !(remove_rows instanceof Array)) {
        reject(new Error("Please provide an array with row id's."));
      }

      if (password == undefined) {
        password = "";
      }
      if (expire == undefined) {
        expire = "";
      }
      if (custom_link == undefined) {
        custom_link = "";
      }

      var fNewRows = new_rows.join(", ");
      var fRemoveRows = remove_rows.join(", ");

      axios({
        url: Config.API_ENDPOINT + "share.php",
        method: "PUT",
        headers: {
          appid: global_this.appid,
          appsecret: global_this.appsecret,
          authtoken: global_this.auth_token,
        },
        data: {
          bucket: global_this.bucket_id,
          container: encodeURI(container_name),
          share_id: share_id,
          new_rows: fNewRows,
          remove_rows: fRemoveRows,
          password: password,
          expire: expire,
          custom_link: custom_link,
        },
      }).then(function (response) {
        var data = response.data;
        if (response.status === 200) {
          resolve(new sCResult(data.status, data.message, data.body));
        } else {
          reject(
            new Error(
              "There was an error while creating a share link. Following error message: " +
                data.message
            )
          );
        }
      });
    });
  }

  /**
   * Returns the already shared links by the currently signed in user.
   * @returns {Promise<sCResult>} The link details.
   */
  getShareLinks() {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      axios({
        url: Config.API_ENDPOINT + "share.php",
        method: "GET",
        headers: {
          appid: global_this.appid,
          appsecret: global_this.appsecret,
          authtoken: global_this.auth_token,
        },
      }).then(function (response) {
        var data = response.data;
        if (response.status === 200) {
          resolve(new sCResult(data.status, data.message, data.body));
        } else {
          reject(
            new Error(
              "There was an error while fetching the share links. Following error message: " +
                data.message
            )
          );
        }
      });
    });
  }

  /**
   * Deletes an existing share link from the currently signed in account.
   * @param {Number} share_id The id of the share link, which should be deleted.
   * @returns The status of the operation.
   */
  deleteLink(share_id) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (share_id === undefined || share_id === "") {
        reject(new Error("Please define a container."));
      }

      axios({
        url: Config.API_ENDPOINT + "share.php",
        method: "DELETE",
        headers: {
          appid: global_this.appid,
          appsecret: global_this.appsecret,
          authtoken: global_this.auth_token,
        },
        data: {
          share_id: share_id,
        },
      }).then(function (response) {
        var data = response.data;
        if (response.status === 200) {
          resolve(new sCResult(data.status, data.message, data.body));
        } else {
          reject(
            new Error(
              "There was an error while deleting the share link. Following error message: " +
                data.message
            )
          );
        }
      });
    });
  }

  /**
   * Retrieve a single rowset by it's id.
   * @param {String} container_name The container name, where the ID is contained.
   * @param {Number} row_id The row id, which can be trieved by get or getAll.
   * @param {Array} exclude Columns, which should be excluded from the results.
   * @return {Promise<sCResult>} The function returns a promise.
   */
  getById(container_name, row_id, exclude) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (exclude !== undefined) {
        exclude = JSON.stringify(exclude);
      } else {
        exclude = JSON.stringify([]);
      }

      axios
        .get(
          Config.API_ENDPOINT +
            "?bucket=" +
            global_this.bucket_id +
            "&dataset=" +
            encodeURI(global_this.dataset) +
            "&container=" +
            encodeURI(container_name) +
            "&row=" +
            row_id +
            "&exclude=" +
            exclude,
          {
            headers: {
              appid: global_this.appid,
              appsecret: global_this.appsecret,
              authtoken: global_this.auth_token,
            },
          }
        )
        .then(function (result) {
          if (result.status === 200) {
            var result = new sCResult(
              result.data.status,
              result.data.message,
              result.data.body === undefined ? {} : result.data.body[0]
            );
            resolve(result);
          } else {
            reject(
              new Error(
                "There was a problem with the API endpoint. Following error message was sent: " +
                  result.data.message
              )
            );
          }
        });
    });
  }

  /**
     This methdod can add new rows to you container in the previous set dataset.
    @param {String} container_name The container name, created via the schmuckliCloud console
    @param {String} data A dataobject with a key-value pair. The key represents the columns defined in the schmuckliCloud console.
    @return {Promise<sCResult>} The function returns you a promise. You can use the 'then' method, to wait for it. Afterwards you get a true (when everything was fine) or an error object.
    */
  insert(container_name, data) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      let final_data = "{}";
      if (data === undefined || data === {}) {
        reject(new Error("Please provide a data object."));
      } else {
        final_data = JSON.stringify(data);
      }

      axios({
        url: Config.API_ENDPOINT,
        method: "POST",
        headers: {
          appid: global_this.appid,
          appsecret: global_this.appsecret,
          authtoken: global_this.auth_token,
        },
        data: {
          bucket: global_this.bucket_id,
          dataset: encodeURI(global_this.dataset),
          container: encodeURI(container_name),
          data: final_data,
        },
      }).then(function (response) {
        var data = response.data;
        if (response.status === 200) {
          resolve(new sCResult(data.status, data.message, data.body));
        } else {
          reject(
            new Error(
              "There was an error while inserting data. Following error message: " +
                data.message
            )
          );
        }
      });
    });
  }

  /**
     This method updates a specific row in a container
    @param {String} container_name Define a container name, which should be updated.
    @param {Number} row_id Define a row id which should be updated
    @param {Object} data Define the data object in a key-value pair
    @return {Promise<sCResult>} The function returns you a promise. You can use the 'then' method, to wait for it. Afterwards you get a true (when everything was fine) or an error object.
    */
  update(container_name, row_id, data) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (row_id === undefined || isNaN(row_id)) {
        //Check if the value is a number
        reject(
          new Error("Please provide a row id and make sure it is a number.")
        );
      }

      if (data === undefined || data === [] || data === {} || data === "") {
        reject(
          new Error(
            "Please provide a data array, with data which should be updated."
          )
        );
      } else {
        data = JSON.stringify(data);
      }

      axios({
        url: Config.API_ENDPOINT,
        method: "PUT",
        headers: {
          appid: global_this.appid,
          appsecret: global_this.appsecret,
          authtoken: global_this.auth_token,
        },
        data: {
          bucket: global_this.bucket_id,
          dataset: encodeURI(global_this.dataset),
          container: encodeURI(container_name),
          row: row_id,
          data: data,
        },
      }).then(function (response) {
        var data = response.data;
        if (response.status === 200) {
          resolve(new sCResult(data.status, data.message, data.body));
        } else {
          reject(
            new Error(
              "There was an error while updating the data. Following error message: " +
                data.message
            )
          );
        }
      });
    });
  }

  /**
  This method deletes a specific row in a container or can just delete a column in a specific row.
  @param {String} container_name Define the container name, where the deletion process should take place
  @param {Number} row_id Define a row id, which can be retrieved by the 'get' or 'getAll' method.
  @param {String} column Define a column name, when just this data in this specific column should be deleted.
  @return {Promise<sCResult>} Returns a promise. Once it has finished the deletion process you can fetch the result in the first parameter.
  */
  delete(container_name, row_id, column) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      if (row_id === undefined || isNaN(row_id)) {
        //Check if the value is a number
        reject(
          new Error("Please provide a row id and make sure it is a number.")
        );
      }

      axios({
        url: Config.API_ENDPOINT,
        method: "DELETE",
        headers: {
          appid: global_this.appid,
          appsecret: global_this.appsecret,
          authtoken: global_this.auth_token,
        },
        data: {
          bucket: global_this.bucket_id,
          dataset: encodeURI(global_this.dataset),
          container: encodeURI(container_name),
          row: row_id,
          col: column,
        },
      }).then(function (response) {
        var data = response.data;
        if (response.status === 200) {
          resolve(new sCResult(data.status, data.message, data.body));
        } else {
          reject(
            new Error(
              "There was an error while deleting the data. Following error message was received: " +
                data.message
            )
          );
        }
      });
    });
  }

  /**
   * Fetches the metadata of the given container name.
   * @param {String} container_name The container name
   * @return {Promise<sCResult>} A promise with the metadata
   */
  metadata(container_name) {
    var global_this = this;
    return new Promise(function (resolve, reject) {
      //Check the properties before sending to the API
      if (container_name === undefined || container_name === "") {
        reject(new Error("Please define a container."));
      }

      axios({
        url: Config.API_ENDPOINT + "metadata.php",
        method: "GET",
        headers: {
          appid: global_this.appid,
          appsecret: global_this.appsecret,
          authtoken: global_this.auth_token,
        },
        params: {
          bucket: global_this.bucket_id,
          container: encodeURI(container_name),
        },
      }).then(function (response) {
        var data = response.data;
        if (response.status === 200) {
          resolve(new sCResult(data.status, data.message, data.body));
        } else {
          reject(
            new Error(
              "There was an error while getting the metadata. Following error message was received: " +
                data.message
            )
          );
        }
      });
    });
  }
}

/**
Result object of any operation
*/
export class sCResult {
  /**
   * This constructor is used to deliver the data to the business logic of your project.
   * @param {Number} status_code The status codes tells you if the operation was successful.
   * @param {String} message The message describes more information about the operation.
   * @param {String|Object|Array} body The body contains the useable information for your app.
   */
  constructor(status_code, message, body) {
    /**
     * Returns you a three digit number.
     * @type {number}
     * @public
     */
    this.status_code = status_code;

    /**
     * Returns you the message, received from the backend with detailed information about what happend during the operation.
     * @type {string}
     * @public
     */
    this.message = message;

    /**
     * Returns the actual data, if it exists. Check first with `response.data !== undefined`. It is the equal of the received body property from the backend.
     * @type {string}
     * @public
     */
    this.data = body;
  }

  /**
   * Returns true if everything was fine and no further operation has to be done.
   * @return {boolean} True if everything was okay.
   */
  get isOK() {
    return this.status_code >= 200 && this.status_code <= 299 ? true : false;
  }
}