text: "use strict";
  /*!
  * @license
  * Copyright 2018 Alfresco Software, Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  Object.defineProperty(exports, "__esModule", { value: true });
  const _Emitter = require("event-emitter");
  const storage_1 = require("./storage");
  const superagent_ = require("superagent");
  const authentication_1 = require("./authentication/authentication");
  const Emitter = _Emitter;
  const superagent = superagent_;
  const process = {};
  class AlfrescoApiClient {
      constructor(host) {
          this.basePath = '';
          this.authentications = new authentication_1.Authentication({
              'basicAuth': {}, type: 'basic'
          });
          this.defaultHeaders = {};
          this.timeout = undefined;
          this.on = Emitter.on;
          this.off = Emitter.off;
          this.once = Emitter.once;
          this.emit = Emitter.emit;
          this.storage = new storage_1.Storage();
          this.host = host;
          this.on = (new Emitter()).on;
          this.off = (new Emitter()).off;
          this.once = (new Emitter()).once;
          this.emit = (new Emitter()).emit;
          Emitter.call(this);
      }
      paramToString(param) {
          if (param === undefined || param === null) {
              return '';
          }
          if (param instanceof Date) {
              return param.toJSON();
          }
          return param.toString();
      }
      buildUrl(path, pathParams) {
          if (!path.match(/^\//)) {
              path = '/' + path;
          }
          let url = this.basePath + path;
          let _this = this;
          url = url.replace(/\{([\w-]+)\}/g, function (fullMatch, key) {
              let value;
              if (pathParams.hasOwnProperty(key)) {
                  value = _this.paramToString(pathParams[key]);
              }
              else {
                  value = fullMatch;
              }
              return encodeURIComponent(value);
          });
          return url;
      }
      isJsonMime(contentType) {
          return Boolean(contentType !== null && contentType.match(/^application\/json(;.*)?$/i));
      }
      jsonPreferredMime(contentTypes) {
          for (let i = 0; i < contentTypes.length; i++) {
              if (this.isJsonMime(contentTypes[i])) {
                  return contentTypes[i];
              }
          }
          return contentTypes[0];
      }
      isFileParam(param) {
          if (typeof Buffer === 'function' && (param instanceof Buffer || param.path)) {
              return true;
          }
          if (typeof Blob === 'function' && param instanceof Blob) {
              return true;
          }
          if (typeof File === 'function' && param instanceof File) {
              return true;
          }
          if (typeof File === 'object' && param instanceof File) {
              return true;
          }
          return false;
      }
      normalizeParams(params) {
          let newParams = {};
          for (let key in params) {
              if (params.hasOwnProperty(key) && params[key] !== undefined && params[key] !== null) {
                  let value = params[key];
                  if (this.isFileParam(value) || Array.isArray(value)) {
                      newParams[key] = value;
                  }
                  else {
                      newParams[key] = this.paramToString(value);
                  }
              }
          }
          return newParams;
      }
      buildCollectionParam(param, collectionFormat) {
          if (!param) {
              return null;
          }
          switch (collectionFormat) {
              case 'csv':
                  return param.map(this.paramToString).join(',');
              case 'ssv':
                  return param.map(this.paramToString).join(' ');
              case 'tsv':
                  return param.map(this.paramToString).join('\t');
              case 'pipes':
                  return param.map(this.paramToString).join('|');
              case 'multi':
                  return param.map(this.paramToString);
              default:
                  throw new Error('Unknown collection format: ' + collectionFormat);
          }
      }
      isWithCredentials() {
          if (this.config) {
              return this.config.withCredentials;
          }
          else {
              return false;
          }
      }
      applyAuthToRequest(request) {
          if (this.authentications) {
              switch (this.authentications.type) {
                  case 'basic':
                      let basicAuth = this.authentications.basicAuth;
                      if (basicAuth.username || basicAuth.password) {
                          request.auth(basicAuth.username ? encodeURI(basicAuth.username) : '', basicAuth.password ? encodeURI(basicAuth.password) : '');
                      }
                      break;
                  case 'activiti':
                      if (this.authentications.basicAuth.ticket) {
                          request.set({ 'Authorization': this.authentications.basicAuth.ticket });
                      }
                      break;
                  case 'oauth2':
                      let oauth2 = this.authentications.oauth2;
                      if (oauth2.accessToken) {
                          request.set({ 'Authorization': 'Bearer ' + oauth2.accessToken });
                      }
                      break;
                  default:
                      throw new Error('Unknown authentication type: ' + this.authentications.type);
              }
          }
      }
      deserialize(response, returnType) {
          if (response === null) {
              return null;
          }
          let data = response.body;
          if (data === null) {
              data = response.text;
          }
          if (returnType) {
              if (Array.isArray(data)) {
                  data = data.map((element) => {
                      return new returnType(element);
                  });
              }
              else {
                  data = new returnType(data);
              }
          }
          return data;
      }
      basicAuth(username, password) {
          let str = username + ':' + password;
          let base64;
          if (typeof Buffer === 'function') {
              base64 = Buffer.from(str.toString(), 'binary').toString('base64');
          }
          else {
              base64 = btoa(str);
          }
          return 'Basic ' + base64;
      }
      callApi(path, httpMethod, pathParams, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts, returnType, contextRoot, responseType) {
          let url;
          if (contextRoot) {
              let basePath = `${this.host}/${contextRoot}`;
              url = this.buildUrlCustomBasePath(basePath, path, pathParams);
          }
          else {
              url = this.buildUrl(path, pathParams);
          }
          return this.callHostApi(path, httpMethod, pathParams, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts, returnType, contextRoot, responseType, url);
      }
      callCustomApi(path, httpMethod, pathParams, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts, returnType, contextRoot, responseType) {
          let url = this.buildUrlCustomBasePath(path, '', pathParams);
          return this.callHostApi(path, httpMethod, pathParams, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts, returnType, contextRoot, responseType, url);
      }
      callHostApi(path, httpMethod, pathParams, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts, returnType, contextRoot, responseType, url) {
          let eventEmitter = {};
          Emitter(eventEmitter);
          let request = this.buildRequest(httpMethod, url, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts, responseType, eventEmitter, returnType);
          if (returnType === 'Binary') {
              request = request.buffer(true).parse(superagent.parse['application/octet-stream']);
          }
          let promise = new Promise((resolve, reject) => {
              request.end((error, response) => {
                  if (error) {
                      this.emit('error', error);
                      eventEmitter.emit('error', error);
                      if (error.status === 401) {
                          this.emit('unauthorized');
                          eventEmitter.emit('unauthorized');
                      }
                      if (response && response.text) {
                          error = error || {};
                          reject(Object.assign(error, { message: response.text }));
                      }
                      else {
                          reject({ error: error });
                      }
                  }
                  else {
                      if (this.isBpmRequest()) {
                          if (response.header && response.header.hasOwnProperty('set-cookie')) {
                              this.authentications.cookie = response.header['set-cookie'];
                          }
                      }
                      let data = {};
                      if (response.type === 'text/html') {
                          data = this.deserialize(response);
                      }
                      else {
                          data = this.deserialize(response, returnType);
                      }
                      eventEmitter.emit('success', data);
                      resolve(data);
                  }
              }).on('abort', () => {
                  eventEmitter.emit('abort');
              });
          });
          promise.on = function () {
              eventEmitter.on.apply(eventEmitter, arguments);
              return this;
          };
          promise.once = function () {
              eventEmitter.once.apply(eventEmitter, arguments);
              return this;
          };
          promise.emit = function () {
              eventEmitter.emit.apply(eventEmitter, arguments);
              return this;
          };
          promise.off = function () {
              eventEmitter.off.apply(eventEmitter, arguments);
              return this;
          };
          promise.abort = function () {
              request.abort();
              return this;
          };
          return promise;
      }
      isBpmRequest() {
          return this.className === 'ProcessAuth' || this.className === 'ProcessClient';
      }
      isCsrfEnabled() {
          if (this.config) {
              return !this.config.disableCsrf;
          }
          else {
              return true;
          }
      }
      setCsrfToken(request) {
          let token = this.createCSRFToken();
          request.set('X-CSRF-TOKEN', token);
          if (this.isNodeEnv()) {
              request.set('Cookie', 'CSRF-TOKEN=' + token + ';path=/');
          }
          try {
              document.cookie = 'CSRF-TOKEN=' + token + ';path=/';
          }
          catch (err) {
          }
      }
      isNodeEnv() {
          return (typeof process !== 'undefined') && (process.release && process.release.name === 'node');
      }
      createCSRFToken(a) {
          return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e16] + (1e16).toString()).replace(/[01]/g, this.createCSRFToken);
      }
      progress(event, eventEmitter) {
          if (event.lengthComputable) {
              let percent = Math.round(event.loaded / event.total * 100);
              eventEmitter.emit('progress', {
                  total: event.total,
                  loaded: event.loaded,
                  percent: percent
              });
          }
      }
      buildUrlCustomBasePath(basePath, path, pathParams) {
          if (path && path !== '' && !path.match(/^\//)) {
              path = '/' + path;
          }
          let url = basePath + path;
          let _this = this;
          url = url.replace(/\{([\w-]+)\}/g, function (fullMatch, key) {
              let value;
              if (pathParams.hasOwnProperty(key)) {
                  value = _this.paramToString(pathParams[key]);
              }
              else {
                  value = fullMatch;
              }
              return encodeURIComponent(value);
          });
          return url;
      }
      buildRequest(httpMethod, url, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts, responseType, eventEmitter, returnType) {
          let request = superagent(httpMethod, url);
          this.applyAuthToRequest(request);
          request.query(this.normalizeParams(queryParams));
          request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));
          if (this.isBpmRequest() && this.isCsrfEnabled()) {
              this.setCsrfToken(request);
          }
          if (this.isWithCredentials()) {
              request.withCredentials();
          }
          if (this.isBpmRequest()) {
              request._withCredentials = true;
              if (this.authentications.cookie) {
                  if (this.isNodeEnv()) {
                      request.set('Cookie', this.authentications.cookie);
                  }
              }
          }
          request.timeout(this.timeout);
          let contentType = this.jsonPreferredMime(contentTypes);
          if (contentType && contentType !== 'multipart/form-data') {
              request.type(contentType);
          }
          else if (!request.header['Content-Type'] && contentType !== 'multipart/form-data') {
              request.type('application/json');
          }
          if (contentType === 'application/x-www-form-urlencoded') {
              request.send(this.normalizeParams(formParams)).on('progress', (event) => {
                  this.progress(event, eventEmitter);
              });
          }
          else if (contentType === 'multipart/form-data') {
              let _formParams = this.normalizeParams(formParams);
              for (let key in _formParams) {
                  if (_formParams.hasOwnProperty(key)) {
                      if (this.isFileParam(_formParams[key])) {
                          request.attach(key, _formParams[key]).on('progress', (event) => {
                              this.progress(event, eventEmitter);
                          });
                      }
                      else {
                          request.field(key, _formParams[key]).on('progress', (event) => {
                              this.progress(event, eventEmitter);
                          });
                      }
                  }
              }
          }
          else if (bodyParam) {
              request.send(bodyParam).on('progress', (event) => {
                  this.progress(event, eventEmitter);
              });
          }
          let accept = this.jsonPreferredMime(accepts);
          if (accept) {
              request.accept(accept);
          }
          if (returnType === 'Blob' || responseType === 'blob' || responseType === 'Blob') {
              request.responseType('blob');
          }
          else if (returnType === 'String') {
              request.responseType('string');
          }
          return request;
      }
      getAlfTicket(ticket) {
          let alfTicketFragment = '';
          if (ticket) {
              alfTicketFragment = '&alf_ticket=' + ticket;
          }
          else if (this.config.ticketEcm) {
              alfTicketFragment = '&alf_ticket=' + this.config.ticketEcm;
          }
          return alfTicketFragment;
      }
  }
  exports.AlfrescoApiClient = AlfrescoApiClient;
  //# sourceMappingURL=alfrescoApiClient.js.map