wmakeev/moysklad

View on GitHub
bundle/umd/moysklad.js

Summary

Maintainability
F
1 mo
Test Coverage
/******/ (() => { // webpackBootstrap
/******/     var __webpack_modules__ = ({

/***/ 52:
/***/ ((module) => {

"use strict";


let encode

// node
if (typeof process !== 'undefined' && process.version) {
  encode = function (value) {
    return Buffer.from(value).toString('base64')
  }
}

// browser
else if (typeof btoa !== 'undefined') {
  encode = function (value) {
    return btoa(value)
  }
}

// GAS
else if (typeof Utilities !== 'undefined' && Utilities.base64Encode) {
  encode = function (value) {
    return Utilities.base64Encode(value)
  }
}

// unknown context
else {
  throw new Error("base64encode: Can't determine environment")
}

module.exports = function base64encode(value) {
  return encode(String(value))
}


/***/ }),

/***/ 91:
/***/ ((module) => {

"use strict";


var ARR_RX = /^(.+) a(rr(ay)?)?$/i
var OR_RX = /^(.+) or (.+)$/i
var OPT_RX = /^opt(ional)? (.+)$/i

var isArray = function (value) { return Array.isArray(value) }
var isObject = function (value) { return value != null && typeof value === 'object' }
var isPlainObject = function (value) {
  return Object.prototype.toString.call(value) === '[object Object]'
}
var isArguments = function (value) {
  return isObject(value) && value.hasOwnProperty('callee') && !value.propertyIsEnumerable('callee')
}

var BUILT_IN_MATCHERS = {
  // string
  'string': function (value) {
    return typeof value === 'string'
  },
  's|str': 'string',

  // number
  'number': function (value) {
    return typeof value === 'number'
  },
  'n|num': 'number',

  // boolean
  'boolean': function (value) {
    return typeof value === 'boolean'
  },
  'b|bool': 'boolean',

  // function
  'function': function (value) {
    return typeof value === 'function'
  },
  'f|fun|func': 'function',

  // array
  'array': isArray,
  'a|arr': 'array',

  // object
  'object': isObject,
  'o|obj': 'object',

  // regexp
  'regexp': function (value) {
    return value && value instanceof RegExp
  },
  'r|rx|regex': 'regexp',

  // date
  'date': function (value) {
    return value && value instanceof Date
  },
  'd': 'date',

  // Object
  'Object': isPlainObject,
  'Obj': 'Object'
}
// TODO Add "any" matcher


var customAssert = function (test, msg) {
  if (!test) {
    if (msg === void 0) throw new Error(test + ' == true')
    else throw new Error(msg)
  }
}

var HAVE_ARGUMENTS_OBJECT = '@@have/argumentsObject'
var HAVE_DEFAULT_MATCHER = '@@have/defaultMatcher'
var ARGUMENTS_OBJECT_MATCHER = {}
var DEFAULT_MATCHER = {}
ARGUMENTS_OBJECT_MATCHER[HAVE_ARGUMENTS_OBJECT] = 'Object'
DEFAULT_MATCHER[HAVE_DEFAULT_MATCHER] = function () { return false }

// Object assign
function assign () {
  var args = Array.prototype.slice.call(arguments, 0)
  var target = args[0]
  var source = args.slice(1)
  var i, len, p

  for (i = 0, len = source.length; i < len; i++) {
    for (p in source[i]) {
      if (source[i].hasOwnProperty(p)) {
        target[p] = source[i][p]
      }
    }
  }
  return target
}

// { 's|str': val1 } -> { 's': val1, 'str': val1 }
function unfoldMatchers (matchers) {
  var unfolded = {}
  var variants, p, i, len

  for (p in matchers) {
    if (matchers.hasOwnProperty(p)) {
      variants = p.split(/\|/)
      for (i = 0, len = variants.length; i < len; i++) {
        unfolded[variants[i]] = matchers[p]
      }
    }
  }
  return unfolded
}

// core recursive check
function ensure (matchers, argName, argType, value, check) {
  var memberType = null
  var valid = true
  var reason = null
  var match = null
  var typeValidator = null
  var i = 0

  function softAssert (cond, reason_) {
    if (!(valid = cond)) reason = reason_
  }

  match = argType.match(OPT_RX)
  if (match) {
    memberType = match[2]
    ensure(matchers, argName, memberType, value, softAssert)
    return valid || value === null || value === void 0
  }

  match = argType.match(OR_RX)
  if (match) {
    memberType = match[1]
    ensure(matchers, argName, memberType, value, softAssert)
    if (valid) return true
    valid = true // reset previous softAssert

    memberType = match[2]
    ensure(matchers, argName, memberType, value, softAssert)
    check(valid, '`' + argName + '` is neither a ' + match[1] + ' nor ' + match[2])
    return true
  }

  match = argType.match(ARR_RX)
  if (match) {
    ensure(matchers, argName, 'array', value, softAssert)
    if (!valid) {
      check(false, reason)
      return false
    }
    memberType = match[1]
    for (i = 0; i < value.length; i++) {
      ensure(matchers, argName, memberType, value[i], softAssert)
      if (!valid) {
        check(false, '`' + argName + '` element is falsy or not a ' + memberType)
        return false
      }
    }
    return true
  }

  typeValidator = (function getValidator (t) {
    var validator = null
    argType = t
    if (matchers.hasOwnProperty(t)) validator = matchers[t]
    return typeof validator === 'string' ? getValidator(validator) : validator
  })(argType)

  valid = typeValidator ? typeValidator(value) : matchers[HAVE_DEFAULT_MATCHER](value)

  check(valid, '`' + argName + '` is not ' + argType)
  return true
}

function ensureArgs (args, schema, matchers, strict) {
  var ensureResults = []
  var parsedArgs = {}
  var argIndex = 0
  var argsKeys = []
  var fail = null
  var p, i, len, argName, ensured, argStr

  // have schema check
  if (schema instanceof Array) {
    if (!schema.length) { throw new Error('have() called with empty schema list') }

    for (i = 0, len = schema.length; i < len; i++) {
      ensureResults[i] = ensureArgs(args, schema[i], matchers, strict)
    }

    ensureResults.sort(function (a, b) {
      if (a.argIndex > b.argIndex) return -1
      if (a.argIndex < b.argIndex) return 1
      return 0
    })

    for (i = 0; i < ensureResults.length; i++) {
      if (!ensureResults[i].fail) return ensureResults[i]
    }

    return ensureResults[0]
  } else if (isPlainObject(schema)) {
    // have `arguments` check
    if (isArguments(args) || isArray(args)) {
      for (i = 0, len = args.length; i < len; i++) { argsKeys[i] = i }
    } else if (isPlainObject(args)) {
      i = 0
      for (p in args) {
        if (args.hasOwnProperty(p)) { argsKeys[i++] = p }
      }
    } else {
      throw new Error('have() `arguments` argument should be function arguments, array or object')
    }

    for (argName in schema) {
      if (schema.hasOwnProperty(argName)) {
        ensured = ensure(matchers, argName, schema[argName], args[argsKeys[argIndex]],
          function (cond, fail_) { if (!cond) fail = fail_ })
        if (fail) break
        if (ensured) {
          parsedArgs[argName] = args[argsKeys[argIndex]]
          argIndex++
        }
      }
    }

    if (strict && !fail && argIndex < argsKeys.length) {
      if (typeof argsKeys[argIndex] === 'string') {
        fail = 'Unexpected `' + argsKeys[argIndex] + '` argument'
      } else {
        argStr = '' + args[argsKeys[argIndex]]
        fail = 'Unexpected argument "' + (argStr.length > 15
            ? argStr.substring(0, 15) + '..'
            : argStr) + '"'
      }
    }

    return { fail: fail, parsedArgs: parsedArgs, argIndex: argIndex }
  } else {
    throw new Error('have() `schema` should be an array or an object')
  }
}

// have.js - Main have.js exports
module.exports = (function () {
  var assert = customAssert

  function have (args, schema, strict) {
    var res = ensureArgs(args, schema, this.matchers, strict)
    if (HAVE_ARGUMENTS_OBJECT in res.parsedArgs) {
      return have.call(this, res.parsedArgs[HAVE_ARGUMENTS_OBJECT], schema, strict)
    }
    assert(!res.fail, res.fail)
    return res.parsedArgs
  }

  have.assert = function (assert_) {
    return (assert_ === void 0) ? assert : (assert = assert_)
  }

  have.strict = function (args, schema) {
    return this(args, schema, true)
  }

  have.matchers = assign({}, ARGUMENTS_OBJECT_MATCHER, DEFAULT_MATCHER)

  have.argumentsObject = ARGUMENTS_OBJECT_MATCHER

  have.with = function (matchers) {
    var _have = function () { return have.apply(_have, arguments) } // TODO Test

    if (!isPlainObject(matchers)) {
      throw new Error('`checkers` argument must to be an object')
    }

    return assign(_have, {
      assert: have.assert,
      strict: have.strict.bind(_have),
      with: have.with,
      matchers: assign({}, unfoldMatchers(this.matchers), unfoldMatchers(matchers)),
      argumentsObject: have.argumentsObject
    })
  }

  return have.with(BUILT_IN_MATCHERS)
})()



/***/ }),

/***/ 992:
/***/ ((module) => {

!function(){"use strict";var u,c,a,s,f,y="properties",l="deepProperties",b="propertyDescriptors",d="staticProperties",O="staticDeepProperties",h="staticPropertyDescriptors",g="configuration",m="deepConfiguration",P="deepProps",A="deepStatics",j="deepConf",v="initializers",_="methods",w="composers",D="compose";function S(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(r):[])}function r(r,t){return Array.prototype.slice.call(arguments,2).reduce(r,t)}var x=r.bind(0,function r(t,e){if(e)for(var n=S(e),o=0;o<n.length;o+=1)Object.defineProperty(t,n[o],Object.getOwnPropertyDescriptor(e,n[o]));return t});function C(r){return"function"==typeof r}function N(r){return r&&"object"==typeof r||C(r)}function z(r){return r&&"object"==typeof r&&r.__proto__==Object.prototype}var E=r.bind(0,function r(t,e){if(e===u)return t;if(Array.isArray(e))return(Array.isArray(t)?t:[]).concat(e);if(!z(e))return e;for(var n,o,i=S(e),p=0;p<i.length;)n=i[p++],(o=Object.getOwnPropertyDescriptor(e,n)).hasOwnProperty("value")?o.value!==u&&(t[n]=r(z(t[n])||Array.isArray(e[n])?t[n]:{},e[n])):Object.defineProperty(t,n,o);return t});function I(){return(c=Array.prototype.concat.apply([],arguments).filter(function(r,t,e){return C(r)&&e.indexOf(r)===t})).length?c:u}function t(r){return c=function r(){return function r(t){var e,n,o=r[D]||{},i={__proto__:o[_]},p=o[v],c=Array.prototype.slice.apply(arguments),a=o[l];if(a&&E(i,a),(a=o[y])&&x(i,a),(a=o[b])&&Object.defineProperties(i,a),!p||!p.length)return i;for(t===u&&(t={}),o=0;o<p.length;)C(e=p[o++])&&(i=(n=e.call(i,t,{instance:i,stamp:r,args:c}))===u?i:n);return i}}(),(a=r[O])&&E(c,a),(a=r[d])&&x(c,a),(a=r[h])&&Object.defineProperties(c,a),a=C(c[D])?c[D]:R,x(c[D]=function(){return a.apply(this,arguments)},r),c}function e(e,n){function r(r,t){N(n[r])&&(N(e[r])||(e[r]={}),(t||x)(e[r],n[r]))}function t(r){(c=I(e[r],n[r]))&&(e[r]=c)}return n&&N(n=n[D]||n)&&(r(_),r(y),r(l,E),r(b),r(d),r(O,E),r(h),r(g),r(m,E),t(v),t(w)),e}function R(){return t(Array.prototype.concat.apply([this],arguments).reduce(e,{}))}function V(r){return C(r)&&C(r[D])}var n={};function o(r,t){return function(){return(s={})[r]=t.apply(u,Array.prototype.concat.apply([{}],arguments)),((c=this)&&c[D]||a).call(c,s)}}n[_]=o(_,x),n[y]=n.props=o(y,x),n[v]=n.init=o(v,I),n[w]=o(w,I),n[l]=n[P]=o(l,E),n[d]=n.statics=o(d,x),n[O]=n[A]=o(O,E),n[g]=n.conf=o(g,x),n[m]=n[j]=o(m,E),n[b]=o(b,x),n[h]=o(h,x),a=n[D]=x(function r(){for(var t,e,n=0,o=[],i=arguments,p=this;n<i.length;)N(t=i[n++])&&o.push(V(t)?t:((s={})[_]=(e=t)[_]||u,a=e.props,s[y]=N((c=e[y])||a)?x({},a,c):u,s[v]=I(e.init,e[v]),s[w]=I(e[w]),a=e[P],s[l]=N((c=e[l])||a)?E({},a,c):u,s[b]=e[b],a=e.statics,s[d]=N((c=e[d])||a)?x({},a,c):u,a=e[A],s[O]=N((c=e[O])||a)?E({},a,c):u,c=e[h],s[h]=N((a=e.name&&{name:{value:e.name}})||c)?x({},c,a):u,a=e.conf,s[g]=N((c=e[g])||a)?x({},a,c):u,a=e[j],s[m]=N((c=e[m])||a)?E({},a,c):u,s));if(t=R.apply(p||f,o),p&&o.unshift(p),Array.isArray(i=t[D][w]))for(n=0;n<i.length;)t=V(p=i[n++]({stamp:t,composables:o}))?p:t;return t},n),n.create=function(){return this.apply(u,arguments)},(s={})[d]=n,f=R(s),a[D]=a.bind(),a.version="4.3.2",typeof u!="object"?module.exports=a:self.stampit=a}();

/***/ }),

/***/ 658:
/***/ ((module) => {

"use strict";


class MoyskladError extends Error {
  constructor(message, ...args) {
    super(message, ...args)
    this.name = this.constructor.name
    /* c8 ignore else  */
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, this.constructor)
    }
  }
}

class MoyskladRequestError extends MoyskladError {
  constructor(message, response) {
    super(message)

    if (response) {
      this.url = response.url
      this.status = response.status
      this.statusText = response.statusText
    }
  }
}

class MoyskladUnexpectedRedirectError extends MoyskladRequestError {
  constructor(response) {
    super(
      `Неожиданное перенаправление запроса с кодом ${response.status}` +
        ' (см. подробнее https://github.com/wmakeev/moysklad#moyskladunexpectedredirecterror)',
      response
    )

    const location = response.headers.get('location')

    if (response) {
      this.url = response.url
      this.status = response.status
      this.statusText = response.statusText
      this.location = location
    }
  }
}

class MoyskladApiError extends MoyskladRequestError {
  constructor(errors, response) {
    const error = errors[0]
    /* c8 ignore next */
    const message = error.error + (error.moreInfo ? ` (${error.moreInfo})` : '')

    super(message, response)

    this.code = error.code
    this.moreInfo = error.moreInfo
    if (error.line != null) this.line = error.line
    if (error.column != null) this.column = error.column
    this.errors = errors
  }
}

class MoyskladCollectionError extends MoyskladApiError {
  constructor(errors, errorsIndexes, response) {
    super(errors, response)
    this.errorsIndexes = errorsIndexes
  }
}

module.exports = {
  MoyskladError,
  MoyskladRequestError,
  MoyskladUnexpectedRedirectError,
  MoyskladApiError,
  MoyskladCollectionError
}


/***/ }),

/***/ 112:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const getEnvVar = __webpack_require__(489)

const DEFAULT_VERSIONS = {
  'remap': '1.2',
  'phone': '1.0',
  'posap': '1.0',
  'moysklad/loyalty': '1.0'
}

const ENV_KEY = {
  'remap': 'REMAP',
  'phone': 'PHONE',
  'posap': 'POSAP',
  'moysklad/loyalty': 'LOYALTY'
}

function getApiDefaultVersion(api) {
  const apiVersion = DEFAULT_VERSIONS[api]
  const envKey = ENV_KEY[api] || api.replace(/\W/g, '_').toUpperCase()
  const envName = `MOYSKLAD_${envKey}_API_VERSION`

  return getEnvVar(envName) || apiVersion
}

module.exports = getApiDefaultVersion


/***/ }),

/***/ 489:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


/* global window */

/**
 * Получить значение переменной окружения
 * @param {string} key Наименоване переменной окружения
 * @param {string} defaultValue Наименоване переменной окружения
 * @returns {string | null} Значение переменной окружения
 */
function getEnvVar(key, defaultValue) {
  if (typeof process !== 'undefined' && process.env && process.env[key]) {
    return process.env[key]
  } else if (typeof window !== 'undefined' && window[key]) {
    return window[key]
  } else if (typeof __webpack_require__.g !== 'undefined' && __webpack_require__.g[key]) {
    return __webpack_require__.g[key]
  } else {
    return defaultValue !== undefined ? defaultValue : null
  }
}

module.exports = getEnvVar


/***/ }),

/***/ 418:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const { MoyskladApiError, MoyskladCollectionError } = __webpack_require__(658)

module.exports = function getResponseError(responseBody, response) {
  if (!responseBody) return null

  if (Array.isArray(responseBody)) {
    const errorsIndexes = responseBody
      .map((item, index) => {
        if (item.errors) {
          return [index, item.errors]
        } else {
          return null
        }
      })
      .filter(item => item !== null)

    if (errorsIndexes.length === 0) return null

    const errors = errorsIndexes
      .map(errItem => errItem[1])
      .reduce((res, errors) => res.concat(errors), [])

    return new MoyskladCollectionError(errors, errorsIndexes, response)
  } else if (responseBody.errors) {
    return new MoyskladApiError(responseBody.errors, response)
  }

  return null
}


/***/ }),

/***/ 83:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const have = __webpack_require__(91)
const matchers = __webpack_require__(823)

module.exports = have.with(matchers)


/***/ }),

/***/ 138:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";
/*
 * moysklad
 * Клиент для JSON API МойСклад
 *
 * Copyright (c) 2017, Vitaliy V. Makeev
 * Licensed under MIT.
 */



const stampit = __webpack_require__(992)

const have = __webpack_require__(83)
const getApiDefaultVersion = __webpack_require__(112)
const { version } = __webpack_require__(345)

// methods
const getTimeString = __webpack_require__(9)
const parseTimeString = __webpack_require__(562)
const buildFilter = __webpack_require__(656)
const buildQuery = __webpack_require__(467)
const getEnvVar = __webpack_require__(489)
const getAuthHeader = __webpack_require__(706)
const buildUrl = __webpack_require__(831)
const parseUrl = __webpack_require__(60)
const fetchUrl = __webpack_require__(579)
const GET = __webpack_require__(573)
const POST = __webpack_require__(397)
const PUT = __webpack_require__(874)
const DELETE = __webpack_require__(200)

// errors
const {
  MoyskladApiError,
  MoyskladError,
  MoyskladRequestError,
  MoyskladCollectionError,
  MoyskladUnexpectedRedirectError
} = __webpack_require__(658)

// TODO Remove old methods
module.exports = stampit({
  methods: {
    getAuthHeader,

    buildUrl,

    /* c8 ignore next 3 */
    buildUri(...args) {
      console.log('Warning: метод buildUri переименован в buildUrl')
      return this.buildUrl(...args)
    },

    parseUrl,

    /* c8 ignore next 3 */
    parseUri(...args) {
      console.log('Warning: метод parseUri переименован в parseUrl')
      return this.parseUrl(...args)
    },

    fetchUrl,

    /* c8 ignore next 3 */
    fetchUri(...args) {
      console.log('Warning: метод fetchUri переименован в fetchUrl')
      return this.fetchUrl(...args)
    },

    GET,

    POST,

    PUT,

    DELETE
  },

  statics: {
    getTimeString,
    parseTimeString,
    parseUrl,
    buildFilter,
    buildQuery,
    MoyskladError,
    MoyskladRequestError,
    MoyskladUnexpectedRedirectError,
    MoyskladApiError,
    MoyskladCollectionError
  }
}).init(function (options) {
  have(options, {
    endpoint: 'opt str',
    api: 'opt str',
    apiVersion: 'opt str'

    // TODO fix have object arguments parsing
    // login: 'opt str',
    // password: 'opt str',
    // fetch: 'opt function'
    // queue: 'opt bool',
    // emitter: 'opt obj'
  })

  if (options.fetch) {
    this.fetch = options.fetch
  } else if (typeof window !== 'undefined' && window.fetch) {
    this.fetch = window.fetch.bind(window)
  } else if (typeof fetch !== 'undefined') {
    /* eslint no-undef:0 */
    this.fetch = fetch
  } else {
    this.fetch = function () {
      throw new MoyskladError(
        'Нельзя выполнить http запрос, т.к. при инициализации' +
          ' экземпляра библиотеки не указан Fetch API модуль' +
          ' (cм. подробнее https://github.com/wmakeev/moysklad#Установка).'
      )
    }
  }

  if (options.emitter) {
    this.emitter = options.emitter
  }

  const MOYSKLAD_HOST = getEnvVar('MOYSKLAD_HOST', 'api.moysklad.ru')
  const MOYSKLAD_API = getEnvVar('MOYSKLAD_API', 'remap')
  const MOYSKLAD_USER_AGENT = getEnvVar(
    'MOYSKLAD_USER_AGENT',
    `moysklad/${version} (+https://github.com/wmakeev/moysklad)`
  )

  const _options = Object.assign(
    {
      endpoint: `https://${MOYSKLAD_HOST}/api`,
      api: MOYSKLAD_API,
      userAgent: MOYSKLAD_USER_AGENT
    },
    options
  )

  if (!_options.apiVersion) {
    const apiVersion = getApiDefaultVersion(_options.api)

    if (apiVersion) {
      _options.apiVersion = apiVersion
    } else {
      throw new MoyskladError(`Не указана версия ${_options.api} API`)
    }
  }

  this.getOptions = function () {
    return _options
  }

  this.getVersion = function () {
    return version
  }
})


/***/ }),

/***/ 823:
/***/ ((module) => {

"use strict";


const UUID_REGEX =
  /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/

const urlMatcher = url =>
  typeof url === 'string' && url.substring(0, 8) === 'https://'

const uuidMatcher = uuid => typeof uuid === 'string' && UUID_REGEX.test(uuid)

// TODO Убедиться что указан необходимый минимум полей для сущностей
module.exports = {
  'entity': ent =>
    !!(ent && ent.id && uuidMatcher(ent.id) && ent.meta && ent.meta.type),

  'uuid': uuidMatcher,

  'url': urlMatcher,

  // 'uuid/uuid': id => {
  //   if (typeof id !== 'string') { return false }
  //   let [dicId, entId] = id.split('/')
  //   return UUID_REGEX.test(dicId) && UUID_REGEX.test(entId)
  // },

  'Moysklad.Collection': col =>
    !!(
      col &&
      col.meta &&
      col.meta.type &&
      urlMatcher(col.meta.href) &&
      typeof col.meta.size === 'number'
    )
}

// TODO Проверка типов "Moysklad." на основании модели


/***/ }),

/***/ 200:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const have = __webpack_require__(83)

module.exports = function DELETE(...args) {
  const { path, options = {} } = have.strict(args, [
    { path: 'str or str arr', options: 'opt Object' },
    have.argumentsObject
  ])

  const url = this.buildUrl(path)

  return this.fetchUrl(url, { ...options, method: 'DELETE' })
}


/***/ }),

/***/ 573:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const have = __webpack_require__(83)

module.exports = function GET(...args) {
  const {
    path,
    query,
    options = {}
  } = have.strict(args, [
    { path: 'str or str arr', query: 'opt Object', options: 'opt Object' },
    have.argumentsObject
  ])

  const url = this.buildUrl(path, query)

  return this.fetchUrl(url, { ...options, method: 'GET' })
}


/***/ }),

/***/ 397:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const have = __webpack_require__(83)

module.exports = function POST(...args) {
  // TODO Test payload: 'Object or Object arr'
  const {
    path,
    payload,
    query,
    options = {}
  } = have.strict(args, [
    {
      path: 'str or str arr',
      payload: 'opt Object or Object arr or str',
      query: 'opt Object',
      options: 'opt Object'
    },
    have.argumentsObject
  ])

  const url = this.buildUrl(path, query)
  const fetchOptions = { method: 'POST' }

  if (payload) {
    fetchOptions.body =
      typeof payload === 'string' ? payload : JSON.stringify(payload)
  }

  return this.fetchUrl(url, { ...options, ...fetchOptions })
}


/***/ }),

/***/ 874:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const have = __webpack_require__(83)

module.exports = function PUT(...args) {
  const {
    path,
    payload,
    query,
    options = {}
  } = have.strict(args, [
    {
      path: 'str or str arr',
      payload: 'opt Object or str',
      query: 'opt Object',
      options: 'opt Object'
    },
    have.argumentsObject
  ])

  const url = this.buildUrl(path, query)
  const fetchOptions = { method: 'PUT' }

  if (payload) {
    fetchOptions.body =
      typeof payload === 'string' ? payload : JSON.stringify(payload)
  }

  return this.fetchUrl(url, { ...options, ...fetchOptions })
}


/***/ }),

/***/ 831:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const have = __webpack_require__(83)
const buildQuery = __webpack_require__(467)
const normalizeUrl = __webpack_require__(461)

let pathArrayDeprecationNoticeShown = false

module.exports = function buildUrl(...args) {
  // eslint-disable-next-line prefer-const
  let { url, path, query } = have.strict(args, [
    { url: 'url', query: 'opt Object' },
    { path: 'str or str arr', query: 'opt Object' },
    have.argumentsObject
  ])

  if (url) {
    const parsedUrl = this.parseUrl(url)
    path = parsedUrl.path.join('/')
    query = {
      ...parsedUrl.query,
      ...query
    }
  }

  if (Array.isArray(path)) {
    if (!pathArrayDeprecationNoticeShown) {
      console.log(
        '[DEPRECATED] moysklad#buildUrl: для передачи параметра path' +
          ' используйте строку вместо массива'
      )
      pathArrayDeprecationNoticeShown = true
    }

    path = path.join('/')
  }

  const { endpoint, api, apiVersion } = this.getOptions()

  let resultUrl = normalizeUrl(
    [endpoint, api, apiVersion].concat(path).join('/')
  )

  if (query) {
    const queryString = buildQuery(query)
    resultUrl = resultUrl + (queryString ? `?${queryString}` : '')
  }

  return resultUrl
}


/***/ }),

/***/ 579:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const have = __webpack_require__(83)
const getResponseError = __webpack_require__(418)
const {
  MoyskladRequestError,
  MoyskladApiError,
  MoyskladCollectionError,
  MoyskladUnexpectedRedirectError
} = __webpack_require__(658)

let globalRequestId = 0

module.exports = async function fetchUrl(url, options = {}) {
  const requestId = ++globalRequestId

  have.strict(arguments, { url: 'url', options: 'opt Object' })

  let result, error

  // Специфические параметры (не передаются в опции fetch)
  let rawResponse = false
  let rawRedirect = false
  let muteApiErrors = false
  let muteCollectionErrors = false

  const emit = this.emitter ? this.emitter.emit.bind(this.emitter) : null

  const fetchOptions = {
    redirect: 'manual',
    ...options,
    headers: {
      'User-Agent': this.getOptions().userAgent,
      'Content-Type': 'application/json',
      'Accept-Encoding': 'gzip',
      ...options.headers
    }
  }

  if (!fetchOptions.headers.Authorization) {
    fetchOptions.credentials = 'include'
  }

  // получаем специфичные параметры
  if (fetchOptions.rawResponse) {
    rawResponse = true
    delete fetchOptions.rawResponse
  }
  if (fetchOptions.rawRedirect) {
    rawRedirect = true
    delete fetchOptions.rawRedirect
  }
  if (/* depricated */ fetchOptions.muteErrors) {
    muteApiErrors = true
    delete fetchOptions.muteErrors
  }
  if (fetchOptions.muteApiErrors) {
    muteApiErrors = true
    delete fetchOptions.muteApiErrors
  }
  if (fetchOptions.muteCollectionErrors) {
    muteCollectionErrors = true
    delete fetchOptions.muteCollectionErrors
  }

  // X-Lognex
  if (fetchOptions.precision) {
    fetchOptions.headers['X-Lognex-Precision'] = 'true'
    delete fetchOptions.precision
  }
  if (fetchOptions.webHookDisable) {
    fetchOptions.headers['X-Lognex-WebHook-Disable'] = 'true'
    delete fetchOptions.webHookDisable
  }
  if (fetchOptions.downloadExpirationSeconds) {
    fetchOptions.headers['X-Lognex-Download-Expiration-Seconds'] = String(
      fetchOptions.downloadExpirationSeconds
    )
    delete fetchOptions.downloadExpirationSeconds
  }

  const authHeader = this.getAuthHeader()
  if (authHeader) {
    fetchOptions.headers.Authorization = this.getAuthHeader()
  }

  if (emit) emit('request', { requestId, url, options: fetchOptions })

  /** @type {Response} */
  const response = await this.fetch(url, fetchOptions)

  if (emit)
    emit('response', { requestId, url, options: fetchOptions, response })

  if (rawResponse) return response

  if (response.status >= 300 && response.status < 400) {
    if (rawRedirect) {
      return response
    } else {
      throw new MoyskladUnexpectedRedirectError(response)
    }
  }

  // response.ok → response.status >= 200 && response.status < 300
  if (response.status < 200 || response.status >= 300) {
    error = new MoyskladRequestError(
      [response.status, response.statusText].filter(it => it).join(' '),
      response
    )
  }

  // разбираем тело запроса
  if (
    response.headers.has('Content-Type') &&
    response.headers.get('Content-Type').indexOf('application/json') !== -1
  ) {
    // response.json() может вызвать ошибку, если тело ответа пустое
    const resBodyText = await response.text()

    if (resBodyText) {
      result = JSON.parse(resBodyText)
    } else {
      result = undefined
    }

    error = getResponseError(result, response) || error
  }

  if (emit) {
    emit('response:body', {
      requestId,
      url,
      options: fetchOptions,
      response,
      body: result
    })
  }

  if (error) {
    if (error instanceof MoyskladApiError && muteApiErrors) {
      return result
    }

    if (error instanceof MoyskladCollectionError && muteCollectionErrors) {
      return result
    }

    if (emit) emit('error', error, { requestId })
    throw error
  }

  return result
}


/***/ }),

/***/ 706:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const { MoyskladError } = __webpack_require__(658)

/* global MOYSKLAD_LOGIN, MOYSKLAD_PASSWORD */
/* eslint no-undef:0 no-unused-vars:0 */

const base64encode = __webpack_require__(52)

const getEnvVar = __webpack_require__(489)

const bearerAuth = token => `Bearer ${token}`
const basicAuth = (login, password) =>
  'Basic ' + base64encode(`${login}:${password}`)

module.exports = function getAuthHeader() {
  let token
  let login
  let password

  const options = this.getOptions()

  switch (true) {
    case options.token != null:
      token = options.token
      break

    case options.login != null:
      login = options.login
      password = options.password
      break

    case getEnvVar('MOYSKLAD_TOKEN') != null:
      token = getEnvVar('MOYSKLAD_TOKEN')
      break

    case getEnvVar('MOYSKLAD_LOGIN') != null:
      login = getEnvVar('MOYSKLAD_LOGIN')
      password = getEnvVar('MOYSKLAD_PASSWORD')
      break

    default:
      return undefined
  }

  if (token) {
    return bearerAuth(token)
  } else if (password) {
    return basicAuth(login, password)
  } else {
    throw new MoyskladError('Не указан пароль для доступа к API')
  }
}


/***/ }),

/***/ 60:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

'use srict'

const { MoyskladError } = __webpack_require__(658)
const have = __webpack_require__(83)
const normalizeUrl = __webpack_require__(461)
const parseQueryString = __webpack_require__(565)

// https://regex101.com/r/yQgvn4/4
const URL_REGEX = /^(https:\/\/.+\/api)\/(.+)\/(\d+\.\d+)\/([^?]+)(?:\?(.+))?$/

module.exports = function parseUrl(...args) {
  const { url, path } = have.strict(args, [
    { url: 'url' },
    { path: 'str or str arr' }
  ])

  const isCalledOnInstance = !!(this && this.getOptions)

  if (!url && !isCalledOnInstance) {
    throw new MoyskladError(
      'Для вызова статического метода parseUrl, необходимо передать url'
    )
  }

  let { endpoint, api, apiVersion } = isCalledOnInstance
    ? this.getOptions()
    : {}

  let pathStr = ''
  let queryStr = ''

  if (path instanceof Array) {
    pathStr = path.join('/')
  } else if (typeof path === 'string') {
    pathStr = path
  } else if (url) {
    const [, endpoint_, api_, version_, path_, query_] =
      URL_REGEX.exec(url) || []
    endpoint = endpoint_
    api = api_
    pathStr = path_
    apiVersion = version_
    queryStr = query_
  }

  if (!endpoint || !api || !apiVersion || !pathStr) {
    throw new MoyskladError(
      `parseUrl: Url не соответствует API МойСклад - ${url || path}`
    )
  }

  return {
    endpoint,
    api,
    apiVersion,
    path: normalizeUrl(pathStr).split(/\//g),
    query: parseQueryString(queryStr) || {}
  }
}


/***/ }),

/***/ 656:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const { MoyskladError } = __webpack_require__(658)
const getTimeString = __webpack_require__(9)
const isPlainObject = __webpack_require__(226)
const isSimpleValue = __webpack_require__(981)

const createValueSelector = selector => (path, value) => {
  if (!isSimpleValue(value)) {
    throw new MoyskladError(
      'значение должно быть строкой, числом, датой или null'
    )
  }
  return [[path, selector, value]]
}

const createCollectionSelector = selector => {
  const sel = createValueSelector(selector)

  return (path, value) => {
    if (!(value instanceof Array)) {
      throw new MoyskladError(
        `значение селектора ${path.join('.')} должно быть массивом`
      )
    }

    return value.reduce((res, v) => res.concat(sel(path, v)), [])
  }
}

// Comparison selectors
const selectors = {
  eq: { operator: '=' },
  gt: { operator: '>' },
  gte: { operator: '>=' },
  lt: { operator: '<' },
  lte: { operator: '<=' },
  ne: { operator: '!=' },
  contains: { operator: '~' },
  st: { operator: '~=' },
  et: { operator: '=~' },
  in: { operator: '=', collection: true },
  nin: { operator: '!=', collection: true }
}

Object.keys(selectors).forEach(key => {
  selectors[key].name = `$${key}`
})

selectors.eq.not = selectors.ne
selectors.gt.not = selectors.lte
selectors.gte.not = selectors.lt
selectors.lt.not = selectors.gte
selectors.lte.not = selectors.gt
selectors.ne.not = selectors.eq
selectors.in.not = selectors.nin
selectors.nin.not = selectors.in

const comparisonSelectors = Object.keys(selectors).reduce((res, key) => {
  const op = selectors[key]
  res['$' + key] = (
    op.collection ? createCollectionSelector : createValueSelector
  )(op)
  return res
}, {})

// Logical selectors
const invertFilterPart = fp => {
  if (!fp[1].not) {
    throw new MoyskladError(
      `${fp[1].name} не поддерживает селектор отрицания $not`
    )
  }
  return [fp[0], fp[1].not, fp[2]]
}

function getFilterParts(path, value) {
  const pathLen = path.length
  const curKey = pathLen ? path[pathLen - 1] : null

  switch (true) {
    // Mongo logical selectors
    case curKey === '$all':
      if (!(value instanceof Array)) {
        throw new MoyskladError('$all: значение селектора должно быть массивом')
      }
      return value.reduce(
        (res, val) => res.concat(getFilterParts(path.slice(0, -1), val)),
        []
      )

    case curKey === '$not':
      if (!isPlainObject(value)) {
        throw new MoyskladError('$not: значение селектора должно быть объектом')
      }
      // .concat([[headPath, selectors.eq, null]])
      return getFilterParts(path.slice(0, -1), value).map(invertFilterPart)

    case curKey === '$exists':
      if (typeof value !== 'boolean') {
        throw new MoyskladError(
          '$exists: значение селектора должно быть логическим значением'
        )
      }
      return [[path.slice(0, -1), value ? selectors.ne : selectors.eq, null]]

    // Mongo comparison selectors
    case !!comparisonSelectors[curKey]:
      try {
        return comparisonSelectors[curKey](path.slice(0, -1), value)
      } catch (error) {
        throw new MoyskladError(`${curKey}: ${error.message}`)
      }

    // Unknown mongo selector
    case curKey && curKey.substr(0, 1) === '$' && path.length > 1:
      throw new MoyskladError(`Неизвестный селектор "${curKey}"`)

    // Array
    case value instanceof Array:
      return value.reduce(
        (res, val) => res.concat(getFilterParts(path, val)),
        []
      )

    // Object
    case !isSimpleValue(value):
      return Object.keys(value).reduce(
        (res, key) => res.concat(getFilterParts(path.concat(key), value[key])),
        []
      )

    // some other value
    default:
      return [[path, selectors.eq, value]]
  }
}

module.exports = function buildFilter(filter) {
  if (!isPlainObject(filter)) {
    throw new MoyskladError('Поле filter должно быть объектом')
  }

  let filterParts = getFilterParts([], filter)

  // преобразование ключа в строку
  filterParts = filterParts.map(part => [part[0].join('.'), part[1], part[2]])

  return (
    filterParts
      // конвертация операторов и значений в строку
      .map(part => {
        const key = part[0]
        const operator = part[1].operator
        const value = part[2]
        switch (true) {
          case value === undefined:
            return null

          case value === null:
            return [key, operator, '']

          case value instanceof Date:
            return [key, operator, getTimeString(value, true)]

          case typeof value === 'string': {
            return [
              key,
              operator,
              value.includes(';') ? value.replaceAll(';', '\\;') : value
            ]
          }

          case typeof value === 'number':
          case typeof value === 'boolean':
            return [key, operator, value]

          default:
            throw new MoyskladError(
              `Некорректное значение поля "${key}" в фильтре`
            )
        }
      })
      .filter(it => it != null)
      .map(part => `${part[0]}${part[1]}${part[2]}`)
      // TODO Можно удалить эту сортировку (лишняя не нужная работа)
      // только нужно адаптировать тесты
      .sort((p1, p2) => {
        if (p1 > p2) {
          return 1
        }
        if (p1 < p2) {
          return -1
        }
        return 0
      })
      .join(';')
  )
}


/***/ }),

/***/ 467:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const { MoyskladError } = __webpack_require__(658)
const buildFilter = __webpack_require__(656)
const isPlainObject = __webpack_require__(226)

const addQueryPart = (res, key) => val => {
  if (val === null) {
    res.push([key, ''])
  } else if (val === undefined) {
    return undefined
  } else if (['string', 'number', 'boolean'].indexOf(typeof val) === -1) {
    throw new MoyskladError(
      'Значение поля строки запроса должно быть строкой, числом, логическим значением, null или undefined'
    )
  } else {
    res.push([key, encodeURIComponent(val)])
  }
}

module.exports = function buildQuery(query) {
  // совместимость с remap 1.2
  if (query.expand && query.limit == null) {
    query.limit = 100
  }

  return Object.keys(query)
    .reduce((res, key) => {
      const addPart = addQueryPart(res, key)

      switch (true) {
        case key === 'filter':
          if (isPlainObject(query.filter)) addPart(buildFilter(query.filter))
          else if (typeof query.filter === 'string') addPart(query.filter)
          else {
            throw new MoyskladError(
              'Поле filter запроса должно быть строкой или объектом'
            )
          }
          break

        case key === 'order' && query.order instanceof Array:
          addPart(
            query.order
              .map(o =>
                o instanceof Array
                  ? `${o[0]}${o[1] != null ? ',' + o[1] : ''}`
                  : o
              )
              .join(';')
          )
          break

        case query[key] instanceof Array:
          query[key].forEach(addPart)
          break

        default:
          addPart(query[key])
      }

      return res
    }, [])
    .map(kv => `${kv[0]}=${kv[1]}`)
    .join('&')
}


/***/ }),

/***/ 9:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const getTimezoneShift = __webpack_require__(928)

const timezoneFix = getTimezoneShift()

/** Временная зона API МойСклад (часовой пояс в мс) */
const mskTimezone = +3 * 60 * 60 * 1000 // ms

function leftPad1(num) {
  return `0${num}`.slice(-2)
}

function leftPad2(num) {
  return `00${num}`.slice(-3)
}

/**
 * Возвращает дату для фильтра в часовом поясе Москвы
 *
 * @param {Date | number} date Конвертируемая дата
 * @param {Boolean} includeMs Необходимо ли включить миллисекунды в дату
 * @returns {string} Дата ввиде строки
 */
module.exports = function getTimeString(date, includeMs) {
  const mskTime = new Date(+date + mskTimezone + timezoneFix)

  const milliseconds = mskTime.getUTCMilliseconds()

  // 2000-01-01 01:00:00.123
  return [
    mskTime.getUTCFullYear(),
    '-',
    leftPad1(mskTime.getUTCMonth() + 1),
    '-',
    leftPad1(mskTime.getUTCDate()),
    ' ',
    leftPad1(mskTime.getUTCHours()),
    ':',
    leftPad1(mskTime.getUTCMinutes()),
    ':',
    leftPad1(mskTime.getUTCSeconds()),
    includeMs ? `.${leftPad2(milliseconds)}` : ''
  ].join('')
}


/***/ }),

/***/ 928:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

const { MoyskladError } = __webpack_require__(658)
const getEnvVar = __webpack_require__(489)

/**
 * @deprecated Работать с датами нужно в UTC либо преобразовывать
 * вне библиотеки
 */
module.exports = function getTimezoneShift() {
  const localTimeZoneOffset = -(new Date().getTimezoneOffset() * 60 * 1000)

  /** Локальная временная зона в мс */
  let timeZoneMs = localTimeZoneOffset

  /** Временная зона приложения (часовой пояс в минутах) */
  const MOYSKLAD_TIMEZONE = getEnvVar('MOYSKLAD_TIMEZONE')

  if (MOYSKLAD_TIMEZONE) {
    const tz = Number.parseInt(MOYSKLAD_TIMEZONE) * 60 * 1000

    if (Number.isNaN(tz)) {
      throw new MoyskladError(
        'Некорректно указана переменная окружения MOYSKLAD_TIMEZONE' +
          ` - ${MOYSKLAD_TIMEZONE}` // TODO Ссылка на документацию
      )
    }

    timeZoneMs = tz
  }

  return localTimeZoneOffset - timeZoneMs
}


/***/ }),

/***/ 226:
/***/ ((module) => {

"use strict";


module.exports = function isPlainObject(value) {
  return Object.prototype.toString.call(value) === '[object Object]'
}


/***/ }),

/***/ 981:
/***/ ((module) => {

"use strict";


module.exports = function isSimpleValue(value) {
  return typeof value !== 'object' || value instanceof Date || value === null
}


/***/ }),

/***/ 461:
/***/ ((module) => {

"use strict";


const URI_EXTRA_SLASH_REGEX = /([^:]\/)\/+/g
const TRIM_SLASH = /^\/+|\/+$/g

module.exports = function normalizeUrl(url) {
  return url.replace(TRIM_SLASH, '').replace(URI_EXTRA_SLASH_REGEX, '$1')
}


/***/ }),

/***/ 565:
/***/ ((module) => {

"use strict";


function extractQueryValue(str) {
  if (str === '') {
    return null
  }
  const asBool = Boolean(str)
  if (asBool.toString() === str) {
    return asBool
  }

  const asNum = parseInt(str)
  if (asNum.toString() === str) {
    return asNum
  }

  return decodeURIComponent(str)
}

function extractQueryValues(str) {
  return str.indexOf(',') !== -1
    ? str.split(',').map(v => extractQueryValue(v))
    : [extractQueryValue(str)]
}

module.exports = function parseQueryString(queryString) {
  if (queryString == null || queryString === '') {
    return undefined
  }
  queryString = queryString.trim()
  if (!queryString) {
    return undefined
  }

  const kvMap = queryString.split('&').reduce((res, queryPart) => {
    const kv = queryPart.split('=')
    const key = kv[0]
    const value = extractQueryValues(kv[1])
    const resValue = res.get(key)
    return res.set(key, resValue ? resValue.concat(value) : value)
  }, new Map())

  const result = {}
  for (const entry of kvMap.entries()) {
    const [key, value] = entry
    result[key] = value.length > 1 ? value : value[0]
  }

  return result
}


/***/ }),

/***/ 562:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const { MoyskladError } = __webpack_require__(658)
const getTimezoneShift = __webpack_require__(928)

const timezoneFix = getTimezoneShift()

// https://regex101.com/r/Bxq7dZ/2
const MS_TIME_REGEX =
  /^(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?$/

function rightPad2(num) {
  return `${num}00`.slice(0, 3)
}

/**
 * Преобразует строку времени МойСклад в объект даты (с учетом временной зоны)
 * @param {string} timeString Время в формате МойСклад ("2017-04-08 13:33:00.123")
 * @returns {Date} Дата
 */
module.exports = function parseTimeString(timeString) {
  // 2017-04-08 13:33:00.123
  const m = MS_TIME_REGEX.exec(timeString)
  if (!m || m.length < 7 || m.length > 8) {
    throw new MoyskladError(`Некорректный формат даты "${timeString}"`)
  }

  const dateExp = `${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}${
    m[7] && Number.parseInt(m[7]) !== 0 ? '.' + rightPad2(m[7]) : ''
  }+03:00`

  const date = new Date(dateExp)

  return timezoneFix ? new Date(+date - timezoneFix) : date
}


/***/ }),

/***/ 345:
/***/ ((module) => {

module.exports = { version: '0.16.0' }


/***/ })

/******/     });
/************************************************************************/
/******/     // The module cache
/******/     var __webpack_module_cache__ = {};
/******/     
/******/     // The require function
/******/     function __webpack_require__(moduleId) {
/******/         // Check if module is in cache
/******/         var cachedModule = __webpack_module_cache__[moduleId];
/******/         if (cachedModule !== undefined) {
/******/             return cachedModule.exports;
/******/         }
/******/         // Create a new module (and put it into the cache)
/******/         var module = __webpack_module_cache__[moduleId] = {
/******/             // no module.id needed
/******/             // no module.loaded needed
/******/             exports: {}
/******/         };
/******/     
/******/         // Execute the module function
/******/         __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/     
/******/         // Return the exports of the module
/******/         return module.exports;
/******/     }
/******/     
/************************************************************************/
/******/     /* webpack/runtime/global */
/******/     (() => {
/******/         __webpack_require__.g = (function() {
/******/             if (typeof globalThis === 'object') return globalThis;
/******/             try {
/******/                 return this || new Function('return this')();
/******/             } catch (e) {
/******/                 if (typeof window === 'object') return window;
/******/             }
/******/         })();
/******/     })();
/******/     
/************************************************************************/
/******/     
/******/     // startup
/******/     // Load entry module and return exports
/******/     // This entry module is referenced by other modules so it can't be inlined
/******/     var __webpack_exports__ = __webpack_require__(138);
/******/     window.MoyskladClient = __webpack_exports__;
/******/     
/******/ })()
;