Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/modules / ___dist / oneRequest / index.mock.js
Size: Mime:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Request = void 0;

var _exotic = require("exotic");

var _chainAbleBoost = require("chain-able-boost");

var _queryStringify = require("./deps/queryStringify");

var _config = require("./config");

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

const IS_BROWSER = typeof window === 'object';
/**
 * @type {Map}
 * @alias OneRequest
 */

class Request {
  /**
   * @description map of middleware we can call on lifecycle hooks
   * @typedef {IntersectionObserverCallback}
   *
   * @note could also be .subscribe() to add, since it's quite observable-like
   *
   * ...for now though...
   *
   * @example
   * import Request from 'modules/oneRequest'
   * function middlewareForLocalStorage(request: Request, eventData: {}): void {}
   * Request.middleware.set('name', middlewareForLocalStorage)
   */
  constructor() {
    Object.defineProperty(this, "onBrowser", {
      configurable: true,
      enumerable: true,
      writable: true,
      value: handler => {
        // this.store.onBrowser = handler
        const onBrowser = (oneRequest, arg) => {
          if (IS_BROWSER === false) {
            handler(oneRequest, arg);
          }
        };

        this.use(onBrowser);
        return this;
      }
    });
    Object.defineProperty(this, "onServer", {
      configurable: true,
      enumerable: true,
      writable: true,
      value: handler => {
        // this.store.onServer = handler
        const onServer = (oneRequest, arg) => {
          if (IS_BROWSER === false) {
            handler(oneRequest, arg);
          }
        };

        this.use(onServer);
        return this;
      }
    });
    Object.defineProperty(this, "onSuccess", {
      configurable: true,
      enumerable: true,
      writable: true,
      value: handler => {
        return this._set('onSuccess', handler);
      }
    });
    Object.defineProperty(this, "onError", {
      configurable: true,
      enumerable: true,
      writable: true,
      value: handler => {
        return this._set('onError', handler);
      }
    });
    // store is a standard name for every piece of data being set and get in a class
    this.store = {}; // until we fix, set debug always true manually

    this.setDebug(true); // default to POST -- 50/1 POST TO GET
    // this.setMethod(POST)
    // could be done onCreate

    const POST = _config.config.get('POST');

    this.setMethod(POST);
    this.emit('onCreate');
  }
  /**
   * @event lifecycle middleware called for this event
   * @param {String} eventName
   * @param {Object} [eventData=""]
   * @return {Request} @chainable
   */


  emit(eventName, eventData = _exotic.EMPTY_OBJ) {
    // @todo @perf can use Object.seal
    const type = {
      type: eventName
    };
    const arg = eventData === _exotic.EMPTY_OBJ ? type : _objectSpread({}, eventData, type);

    const callMiddleware = (middleware, index) => {
      // if (isFunction(middleware.when)) / isSatisfied / @todo
      middleware(this, arg);
    };

    Request.middleware.forEach(callMiddleware);

    if ((0, _exotic.isArray)(this.middlewareList)) {
      this.middlewareList.forEach(callMiddleware);
    } // !!!!!!!!!
    // this.setParams(defaultParams)


    return this;
  }

  use(middleware) {
    this.middlewareList.push(middleware);
    return this;
  }
  /**
   * @private
   */


  _set(name, value) {
    this.store[name] = value;
    return this;
  }

  _get(name) {
    return this.store[name];
  }

  _has(name) {
    return !!this.store[name];
  }
  /**
   *
   */


  del() {} //

  /**
   *
   */


  get() {} //

  /**
   * patch, put
   */


  post() {} //

  /**
   *
   */


  then() {} //

  /**
   * ===
   */


  type(type) {
    this._set('type', type);
  } // cert() {}
  // key() {}
  // json() {}
  // xml() {}
  // responseType() {}
  // auth('tobi', 'learnboost')
  // .withCredentials()
  // .redirects(2)
  // .on('error', handle)
  // --- setters


  setDebug(shouldDebug = false) {
    return this._set('debug', shouldDebug);
  }

  url(url) {
    return this.setUrl(url);
  }

  setUrl(url) {
    return this._set('url', url);
  }
  /**
   * === sadly is ALSO for query ===
   * === matters for POST ===
   */


  setParams(params) {
    return this._set('params', params);
  }

  params(params) {
    return this.setParams(params); // return this._set('params', params)
  }
  /**
   * @tutorial https://github.com/node-nock/nock#specifying-request-query-string
   * @param {Object} params
   * @return {Request} @chainable
   */


  setDefaultParams(params) {
    // for now just sets params since we object assign
    // return this._set('params', params)
    return this.setParams(params); // return this._set('_defaultParams', params)
    // return this._set('params', params)
  }
  /**
   * @deprecated - is handled in setData for now
   * @TODO
   * @description for POST calls
   * @param {*} body
   */


  setBody(body) {
    return this._set('body', body);
  }

  setData(fixtureData) {
    return this._set('data', fixtureData);
  }

  setFormData(formData) {
    return this._set('formData', formData);
  }

  transformData(fn, data) {
    return this._set('data', fn(data));
  }

  setMethod(method) {
    return this._set('method', method);
  } // --- helpers


  log() {
    if (this.store.debug === true) {
      console.log.apply(console, arguments);
    }

    return this;
  }

  validateRequestStore() {
    if (!this._has('url')) {
      throw new Error('missing url, use request.setUrl(urlForThisEndpoint)');
    }

    if (!this._has('data')) {
      throw new Error('missing fixture data, use request.setData(fixtureData)');
    } // if (!this._has('params')) {
    //   console.log(
    //     'did not pass in params, might want to disable this log because not every request needs params?'
    //   )
    // }

  } // PATCH, PUT, REQUEST, AXIOSER


  get isPost() {
    const methodName = this.store.method.methodName || this.store.methodName;
    return methodName === 'POST' || methodName === 'REQUEST' || methodName === 'AXIOSER' || methodName === 'post';
  }

  get isGet() {
    const methodName = this.store.method.methodName || this.store.methodName;
    return methodName === 'GET' || methodName === 'get'; // return this.store.method.methodType === 'GET'
  }

  setMethodType(type) {
    console.warn('@deprecated .setMethodType');
    return this;
  }
  /**
   * @deprecated
   */


  setMethodName(methodName) {
    console.warn('@deprecated .setMethodName');
    this.store.methodName = name; // The actual string representation of 'post'|'get'

    return this._set('methodName', methodName);
  }

  stringifyParams(paramArg = undefined) {
    let params = paramArg || this._get('params');
    /**
     * HORRIBLE_BAD_SHOULD_BE_FIXED_BY_BACKEND_SHAME
     */
    // params.storeId = params.storeid
    // @todo @perf


    params = (0, _chainAbleBoost.cloneJSON)(params);
    params = (0, _queryStringify.stringifyParamsRecursively)(params);
    return params;
  }
  /**
   * @event toRequest
   * @event ->onRequest
   *
   * @see https://github.com/mzabriskie/axios
   * @return {AsyncFunction} call to get data
   */


  toRequest() {
    // @todo - add cloning through chaining or scoped props
    // @todo add dynamic url
    // add a property to not create fn each time
    if (this.dynamicRequest) {
      return this.dynamicRequest;
    }

    this.emit('toRequest');
    /**
     * @note could accept string param as first arg
     * @todo could chain set the params or url
     */
    // @lint @todo @fixme @split
    // eslint-disable-next-line

    const dynamicAxiosRequest = async (dynamicParams = undefined, dynamicUrl = undefined) => {
      // @NOTE this is how to return mocks
      // return this.store.data
      let _store = this.store,
          url = _store.url,
          debug = _store.debug,
          method = _store.method,
          onError = _store.onError,
          onSuccess = _store.onSuccess;

      const FETCHREQUEST = _config.config.get('FETCHREQUEST'); // dynamicParams => formBody
      // defaultParams/queryParams => string for the end of the url


      let queryParams = this.store.params;
      let params = queryParams; // merge in dynamic params.. but not everything has params

      if (dynamicParams !== undefined) {
        // if (params !== undefined) {
        //   params = Object.assign(params, dynamicParams)
        // } else {
        //   params = Object.assign({}, dynamicParams)
        // }
        if (params !== undefined) {
          params = _objectSpread({}, queryParams, dynamicParams);
        } else {
          params = _objectSpread({}, dynamicParams);
        }
      }

      const constantParams = _config.config.get('constantParams');

      Object.assign(params, constantParams);
      Object.assign(queryParams, constantParams);

      if (process.env.LOG_REQUEST_PARAMS) {
        console.log('_______constantParams', constantParams);
        console.log('___MERGED_PARAMS', queryParams);
      }

      if (dynamicUrl !== undefined) {
        url = url + '/' + dynamicUrl;
      } // handle the transform


      if ((0, _exotic.isObj)(params)) {
        params = (0, _queryStringify.stringifyProperties)(params);
      } // NOW CHANGED BACK
      // if (clientDomain === 'reactdemo.skavaone.com') {
      //   queryParams.storeId = storeId
      // } else {
      //   queryParams.storeid = storeId
      // }
      // queryParams.storeId = queryParams.storeid


      queryParams = this.stringifyParams(queryParams || _exotic.EMPTY_OBJ); // does it just remove at top level...?

      queryParams = decodeURIComponent(queryParams);
      /**
       * @type {AxiosData}
       */

      const axiosData = {
        params
        /**
         * @todo split here ===
         *
         * @type {Array<Data>}
         */

      };
      const args = [url, axiosData]; // const ENABLE_FOR_POST = true

      if (this.isPost) {
        // @todo - should work for every request get and post
        url = `${url}?${queryParams}`;
        const formData = this.stringifyParams(dynamicParams);
        const axiosPostData = {
          data: formData
          /**
           * @type {AxiosRequestConfig}
           */

        };
        const axiosRequestConfig = {
          withCredentials: true,
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
          }
        };

        const axioserRequestConfig = _objectSpread({
          url,
          method: 'post'
        }, axiosPostData, axiosRequestConfig);

        if (process.env.LOG_REQUEST_PARAMS) {
          console.log('[oneRequest] params: ', axioserRequestConfig);
        }

        const _ref = await FETCHREQUEST.call(this, axioserRequestConfig),
              _ref2 = _slicedToArray(_ref, 2),
              error = _ref2[0],
              response = _ref2[1]; // console.dev({ error, response })


        if (process.env.LOG_REQUEST_RESPONSE) {
          console.log('[oneRequest] response: ', response);
        }

        if (error && onError) {
          if (process.env.LOG_REQUEST_ERROR) {
            console.log('[oneRequest] error: ', error);
          } // , response, this


          return onError(error) || response.data;
        } else if (!error && onSuccess) {
          // or .data...
          onSuccess(response.data, response);
        }

        return response.data;
      } // =========


      if (process.env.LOG_REQUEST_PARAMS) {
        console.log('[oneRequest] params: ', args);
      }
      /**
       * @description do our post call
       * @see chain/lego/oneRequest
       */


      const _ref3 = await method.apply(this, args),
            _ref4 = _slicedToArray(_ref3, 2),
            error = _ref4[0],
            response = _ref4[1];

      if (process.env.LOG_REQUEST_RESPONSE) {
        console.log('[oneRequest] response: ', response);
      }

      if (process.env.LOG_REQUEST_ERROR) {
        console.log('[oneRequest] error: ', error);
      } // if we have an error, for now, log it


      if (error) {
        // this.log({ error, response, ...this.store })
        if (error && onError) {
          // , response, this
          return onError(error) || response.data;
        } else if (!error && onSuccess) {
          // or .data...
          onSuccess(response.data, response);
          return response.data;
        } // return onCall(response.data, response) || response.data


        return response.data;
      } // if (debug) {
      //   this.log({ error, response, params, ...this.store })
      // }
      // autofix(response.data)


      return response.data;
    };

    this.dynamicAxiosRequest = dynamicAxiosRequest;
    dynamicAxiosRequest.toChain = (0, _chainAbleBoost.always)(this);
    dynamicAxiosRequest.onError = this.onError;
    dynamicAxiosRequest.onSuccess = this.onSuccess;
    return dynamicAxiosRequest;
  } // query<T>(options: WatchQueryOptions): Promise<ApolloQueryResult<T>>
  // mutate<T>(options: MutationOptions<T>): Promise<FetchResult<T>>
  // subscribe(options: SubscriptionOptions): Observable<any>
  // readQuery<T>(options: DataProxy.Query): T | null
  // readFragment<T>(options: DataProxy.Fragment): T | null
  // writeQuery(options: DataProxy.WriteQueryOptions): void
  // writeFragment(options: DataProxy.WriteFragmentOptions): void
  // gql = {
  //   // CRUD
  //   query: 'QueryHere',
  //   // dynamic
  //   // variables: {},
  // }

  /* @TODO split this out once it works as it broke all the tests :( */


  toMock() {
    let _store2 = this.store,
        url = _store2.url,
        params = _store2.params,
        data = _store2.data,
        method = _store2.method; // eslint-disable-next-line

    const nock = require("nock");

    const mockUrl = process.env.BASE_URL || 'http://localhost:4000'; // console.log('mock data', this.store)
    // @NOTE naming it apiUrl was better, oops
    // show helpful messages to make sure people use it

    this.validateRequestStore(); // for now, autofix it to include the baseUrl

    if (!url.includes('http')) {
      url = mockUrl + url;
    }

    const handleGet = urlRequested => {
      // `api/${url}`
      const doesRequestIncludeUrl = urlRequested.includes(url) || url.includes(urlRequested); // this.log('getCall', { url, urlRequested, doesRequestIncludeUrl })

      return doesRequestIncludeUrl;
    };

    if (this.isPost) {
      // console.dev(`${this.store.method} MOCKED`)
      return nock(mockUrl).post(url).query(params).reply(201, data);
    } else {
      // console.dev(`${url} GET Crocked`)
      return nock(mockUrl).get(handleGet).query(params).reply(200, data);
    }
  }

  setVariables(variables) {
    return this._set('variables', variables);
  }

  setQuery(Query) {
    return this._set('query', Query);
  }

  gql() {} // all the things

  /**
   * (subscriber)
   * same as () / .call() / .end() / .fetch()
   */


  send() {
    // @todo
    // const response: ApolloQueryResult<Query> = await client.query(args)
    // subscriber
    return this.toRequest().apply(this, arguments);
  }

}

exports.Request = Request;
Object.defineProperty(Request, "middleware", {
  configurable: true,
  enumerable: true,
  writable: true,
  value: new Map()
}); // export default Request