{"version":3,"file":"index.cjs","sources":["../../node_modules/axios/lib/helpers/bind.js","../../node_modules/axios/lib/utils.js","../../node_modules/axios/lib/core/AxiosError.js","../../node_modules/axios/lib/helpers/null.js","../../node_modules/axios/lib/helpers/toFormData.js","../../node_modules/axios/lib/helpers/AxiosURLSearchParams.js","../../node_modules/axios/lib/helpers/buildURL.js","../../node_modules/axios/lib/core/InterceptorManager.js","../../node_modules/axios/lib/defaults/transitional.js","../../node_modules/axios/lib/platform/browser/classes/URLSearchParams.js","../../node_modules/axios/lib/platform/browser/classes/FormData.js","../../node_modules/axios/lib/platform/browser/classes/Blob.js","../../node_modules/axios/lib/platform/browser/index.js","../../node_modules/axios/lib/platform/common/utils.js","../../node_modules/axios/lib/platform/index.js","../../node_modules/axios/lib/helpers/toURLEncodedForm.js","../../node_modules/axios/lib/helpers/formDataToJSON.js","../../node_modules/axios/lib/defaults/index.js","../../node_modules/axios/lib/helpers/parseHeaders.js","../../node_modules/axios/lib/core/AxiosHeaders.js","../../node_modules/axios/lib/core/transformData.js","../../node_modules/axios/lib/cancel/isCancel.js","../../node_modules/axios/lib/cancel/CanceledError.js","../../node_modules/axios/lib/core/settle.js","../../node_modules/axios/lib/helpers/parseProtocol.js","../../node_modules/axios/lib/helpers/speedometer.js","../../node_modules/axios/lib/helpers/throttle.js","../../node_modules/axios/lib/helpers/progressEventReducer.js","../../node_modules/axios/lib/helpers/isURLSameOrigin.js","../../node_modules/axios/lib/helpers/cookies.js","../../node_modules/axios/lib/helpers/isAbsoluteURL.js","../../node_modules/axios/lib/helpers/combineURLs.js","../../node_modules/axios/lib/core/buildFullPath.js","../../node_modules/axios/lib/core/mergeConfig.js","../../node_modules/axios/lib/helpers/resolveConfig.js","../../node_modules/axios/lib/adapters/xhr.js","../../node_modules/axios/lib/helpers/composeSignals.js","../../node_modules/axios/lib/helpers/trackStream.js","../../node_modules/axios/lib/adapters/fetch.js","../../node_modules/axios/lib/adapters/adapters.js","../../node_modules/axios/lib/core/dispatchRequest.js","../../node_modules/axios/lib/env/data.js","../../node_modules/axios/lib/helpers/validator.js","../../node_modules/axios/lib/core/Axios.js","../../node_modules/axios/lib/cancel/CancelToken.js","../../node_modules/axios/lib/helpers/spread.js","../../node_modules/axios/lib/helpers/isAxiosError.js","../../node_modules/axios/lib/helpers/HttpStatusCode.js","../../node_modules/axios/lib/axios.js","../../node_modules/axios/index.js","../../src/errors/base-error.ts","../../src/errors/auth-error.ts","../../src/errors/rate-limit-error.ts","../../src/errors/validation-error.ts","../../src/errors/network-error.ts","../../src/errors/promotion-errors.ts","../../src/errors/in-store-pickup-errors.ts","../../src/client/rate-limiter.ts","../../src/client/retry-handler.ts","../../src/config/general-rate-limits.ts","../../src/config/products-rate-limits.ts","../../src/config/orders-fbs-rate-limits.ts","../../src/config/orders-fbw-rate-limits.ts","../../src/config/rate-limits.ts","../../src/client/base-client.ts","../../src/modules/general/index.ts","../../src/modules/products/index.ts","../../src/modules/orders-fbs/index.ts","../../src/modules/orders-fbw/index.ts","../../src/modules/finances/index.ts","../../src/modules/analytics/index.ts","../../src/modules/communications/index.ts","../../src/modules/reports/index.ts","../../src/modules/promotion/index.ts","../../src/modules/tariffs/index.ts","../../src/modules/in-store-pickup/index.ts","../../src/config/promotion-rate-limits.ts","../../src/config/tariffs-rate-limits.ts","../../src/types/communications.types.ts","../../src/index.ts"],"sourcesContent":["'use strict';\n\nexport default function bind(fn, thisArg) {\n  return function wrap() {\n    return fn.apply(thisArg, arguments);\n  };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\nconst {iterator, toStringTag} = Symbol;\n\nconst kindOf = (cache => thing => {\n    const str = toString.call(thing);\n    return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n  type = type.toLowerCase();\n  return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n  return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n    && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n  let result;\n  if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n    result = ArrayBuffer.isView(val);\n  } else {\n    result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n  }\n  return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n  if (kindOf(val) !== 'object') {\n    return false;\n  }\n\n  const prototype = getPrototypeOf(val);\n  return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);\n}\n\n/**\n * Determine if a value is an empty object (safely handles Buffers)\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an empty object, otherwise false\n */\nconst isEmptyObject = (val) => {\n  // Early return for non-objects or Buffers to prevent RangeError\n  if (!isObject(val) || isBuffer(val)) {\n    return false;\n  }\n\n  try {\n    return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;\n  } catch (e) {\n    // Fallback for any other objects that might cause RangeError with Object.keys()\n    return false;\n  }\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n  let kind;\n  return thing && (\n    (typeof FormData === 'function' && thing instanceof FormData) || (\n      isFunction(thing.append) && (\n        (kind = kindOf(thing)) === 'formdata' ||\n        // detect form-data instance\n        (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n      )\n    )\n  )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\nconst [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n  str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n  // Don't bother if no value provided\n  if (obj === null || typeof obj === 'undefined') {\n    return;\n  }\n\n  let i;\n  let l;\n\n  // Force an array if not already something iterable\n  if (typeof obj !== 'object') {\n    /*eslint no-param-reassign:0*/\n    obj = [obj];\n  }\n\n  if (isArray(obj)) {\n    // Iterate over array values\n    for (i = 0, l = obj.length; i < l; i++) {\n      fn.call(null, obj[i], i, obj);\n    }\n  } else {\n    // Buffer check\n    if (isBuffer(obj)) {\n      return;\n    }\n\n    // Iterate over object keys\n    const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n    const len = keys.length;\n    let key;\n\n    for (i = 0; i < len; i++) {\n      key = keys[i];\n      fn.call(null, obj[key], key, obj);\n    }\n  }\n}\n\nfunction findKey(obj, key) {\n  if (isBuffer(obj)){\n    return null;\n  }\n\n  key = key.toLowerCase();\n  const keys = Object.keys(obj);\n  let i = keys.length;\n  let _key;\n  while (i-- > 0) {\n    _key = keys[i];\n    if (key === _key.toLowerCase()) {\n      return _key;\n    }\n  }\n  return null;\n}\n\nconst _global = (() => {\n  /*eslint no-undef:0*/\n  if (typeof globalThis !== \"undefined\") return globalThis;\n  return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n  const {caseless, skipUndefined} = isContextDefined(this) && this || {};\n  const result = {};\n  const assignValue = (val, key) => {\n    const targetKey = caseless && findKey(result, key) || key;\n    if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n      result[targetKey] = merge(result[targetKey], val);\n    } else if (isPlainObject(val)) {\n      result[targetKey] = merge({}, val);\n    } else if (isArray(val)) {\n      result[targetKey] = val.slice();\n    } else if (!skipUndefined || !isUndefined(val)) {\n      result[targetKey] = val;\n    }\n  }\n\n  for (let i = 0, l = arguments.length; i < l; i++) {\n    arguments[i] && forEach(arguments[i], assignValue);\n  }\n  return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n  forEach(b, (val, key) => {\n    if (thisArg && isFunction(val)) {\n      a[key] = bind(val, thisArg);\n    } else {\n      a[key] = val;\n    }\n  }, {allOwnKeys});\n  return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n  if (content.charCodeAt(0) === 0xFEFF) {\n    content = content.slice(1);\n  }\n  return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n  constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n  constructor.prototype.constructor = constructor;\n  Object.defineProperty(constructor, 'super', {\n    value: superConstructor.prototype\n  });\n  props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n  let props;\n  let i;\n  let prop;\n  const merged = {};\n\n  destObj = destObj || {};\n  // eslint-disable-next-line no-eq-null,eqeqeq\n  if (sourceObj == null) return destObj;\n\n  do {\n    props = Object.getOwnPropertyNames(sourceObj);\n    i = props.length;\n    while (i-- > 0) {\n      prop = props[i];\n      if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n        destObj[prop] = sourceObj[prop];\n        merged[prop] = true;\n      }\n    }\n    sourceObj = filter !== false && getPrototypeOf(sourceObj);\n  } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n  return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n  str = String(str);\n  if (position === undefined || position > str.length) {\n    position = str.length;\n  }\n  position -= searchString.length;\n  const lastIndex = str.indexOf(searchString, position);\n  return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n  if (!thing) return null;\n  if (isArray(thing)) return thing;\n  let i = thing.length;\n  if (!isNumber(i)) return null;\n  const arr = new Array(i);\n  while (i-- > 0) {\n    arr[i] = thing[i];\n  }\n  return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n  // eslint-disable-next-line func-names\n  return thing => {\n    return TypedArray && thing instanceof TypedArray;\n  };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object<any, any>} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n  const generator = obj && obj[iterator];\n\n  const _iterator = generator.call(obj);\n\n  let result;\n\n  while ((result = _iterator.next()) && !result.done) {\n    const pair = result.value;\n    fn.call(obj, pair[0], pair[1]);\n  }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array<boolean>}\n */\nconst matchAll = (regExp, str) => {\n  let matches;\n  const arr = [];\n\n  while ((matches = regExp.exec(str)) !== null) {\n    arr.push(matches);\n  }\n\n  return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n  return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n    function replacer(m, p1, p2) {\n      return p1.toUpperCase() + p2;\n    }\n  );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n  const descriptors = Object.getOwnPropertyDescriptors(obj);\n  const reducedDescriptors = {};\n\n  forEach(descriptors, (descriptor, name) => {\n    let ret;\n    if ((ret = reducer(descriptor, name, obj)) !== false) {\n      reducedDescriptors[name] = ret || descriptor;\n    }\n  });\n\n  Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n  reduceDescriptors(obj, (descriptor, name) => {\n    // skip restricted props in strict mode\n    if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n      return false;\n    }\n\n    const value = obj[name];\n\n    if (!isFunction(value)) return;\n\n    descriptor.enumerable = false;\n\n    if ('writable' in descriptor) {\n      descriptor.writable = false;\n      return;\n    }\n\n    if (!descriptor.set) {\n      descriptor.set = () => {\n        throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n      };\n    }\n  });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n  const obj = {};\n\n  const define = (arr) => {\n    arr.forEach(value => {\n      obj[value] = true;\n    });\n  }\n\n  isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n  return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n  return value != null && Number.isFinite(value = +value) ? value : defaultValue;\n}\n\n\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n  return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);\n}\n\nconst toJSONObject = (obj) => {\n  const stack = new Array(10);\n\n  const visit = (source, i) => {\n\n    if (isObject(source)) {\n      if (stack.indexOf(source) >= 0) {\n        return;\n      }\n\n      //Buffer check\n      if (isBuffer(source)) {\n        return source;\n      }\n\n      if(!('toJSON' in source)) {\n        stack[i] = source;\n        const target = isArray(source) ? [] : {};\n\n        forEach(source, (value, key) => {\n          const reducedValue = visit(value, i + 1);\n          !isUndefined(reducedValue) && (target[key] = reducedValue);\n        });\n\n        stack[i] = undefined;\n\n        return target;\n      }\n    }\n\n    return source;\n  }\n\n  return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n  thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\n// original code\n// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34\n\nconst _setImmediate = ((setImmediateSupported, postMessageSupported) => {\n  if (setImmediateSupported) {\n    return setImmediate;\n  }\n\n  return postMessageSupported ? ((token, callbacks) => {\n    _global.addEventListener(\"message\", ({source, data}) => {\n      if (source === _global && data === token) {\n        callbacks.length && callbacks.shift()();\n      }\n    }, false);\n\n    return (cb) => {\n      callbacks.push(cb);\n      _global.postMessage(token, \"*\");\n    }\n  })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);\n})(\n  typeof setImmediate === 'function',\n  isFunction(_global.postMessage)\n);\n\nconst asap = typeof queueMicrotask !== 'undefined' ?\n  queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);\n\n// *********************\n\n\nconst isIterable = (thing) => thing != null && isFunction(thing[iterator]);\n\n\nexport default {\n  isArray,\n  isArrayBuffer,\n  isBuffer,\n  isFormData,\n  isArrayBufferView,\n  isString,\n  isNumber,\n  isBoolean,\n  isObject,\n  isPlainObject,\n  isEmptyObject,\n  isReadableStream,\n  isRequest,\n  isResponse,\n  isHeaders,\n  isUndefined,\n  isDate,\n  isFile,\n  isBlob,\n  isRegExp,\n  isFunction,\n  isStream,\n  isURLSearchParams,\n  isTypedArray,\n  isFileList,\n  forEach,\n  merge,\n  extend,\n  trim,\n  stripBOM,\n  inherits,\n  toFlatObject,\n  kindOf,\n  kindOfTest,\n  endsWith,\n  toArray,\n  forEachEntry,\n  matchAll,\n  isHTMLForm,\n  hasOwnProperty,\n  hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n  reduceDescriptors,\n  freezeMethods,\n  toObjectSet,\n  toCamelCase,\n  noop,\n  toFiniteNumber,\n  findKey,\n  global: _global,\n  isContextDefined,\n  isSpecCompliantForm,\n  toJSONObject,\n  isAsyncFn,\n  isThenable,\n  setImmediate: _setImmediate,\n  asap,\n  isIterable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n  Error.call(this);\n\n  if (Error.captureStackTrace) {\n    Error.captureStackTrace(this, this.constructor);\n  } else {\n    this.stack = (new Error()).stack;\n  }\n\n  this.message = message;\n  this.name = 'AxiosError';\n  code && (this.code = code);\n  config && (this.config = config);\n  request && (this.request = request);\n  if (response) {\n    this.response = response;\n    this.status = response.status ? response.status : null;\n  }\n}\n\nutils.inherits(AxiosError, Error, {\n  toJSON: function toJSON() {\n    return {\n      // Standard\n      message: this.message,\n      name: this.name,\n      // Microsoft\n      description: this.description,\n      number: this.number,\n      // Mozilla\n      fileName: this.fileName,\n      lineNumber: this.lineNumber,\n      columnNumber: this.columnNumber,\n      stack: this.stack,\n      // Axios\n      config: utils.toJSONObject(this.config),\n      code: this.code,\n      status: this.status\n    };\n  }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n  'ERR_BAD_OPTION_VALUE',\n  'ERR_BAD_OPTION',\n  'ECONNABORTED',\n  'ETIMEDOUT',\n  'ERR_NETWORK',\n  'ERR_FR_TOO_MANY_REDIRECTS',\n  'ERR_DEPRECATED',\n  'ERR_BAD_RESPONSE',\n  'ERR_BAD_REQUEST',\n  'ERR_CANCELED',\n  'ERR_NOT_SUPPORT',\n  'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n  descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n  const axiosError = Object.create(prototype);\n\n  utils.toFlatObject(error, axiosError, function filter(obj) {\n    return obj !== Error.prototype;\n  }, prop => {\n    return prop !== 'isAxiosError';\n  });\n\n  const msg = error && error.message ? error.message : 'Error';\n\n  // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)\n  const errCode = code == null && error ? error.code : code;\n  AxiosError.call(axiosError, msg, errCode, config, request, response);\n\n  // Chain the original error on the standard field; non-enumerable to avoid JSON noise\n  if (error && axiosError.cause == null) {\n    Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });\n  }\n\n  axiosError.name = (error && error.name) || 'Error';\n\n  customProps && Object.assign(axiosError, customProps);\n\n  return axiosError;\n};\n\nexport default AxiosError;\n","// eslint-disable-next-line strict\nexport default null;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n  return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n  return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n  if (!path) return key;\n  return path.concat(key).map(function each(token, i) {\n    // eslint-disable-next-line no-param-reassign\n    token = removeBrackets(token);\n    return !dots && i ? '[' + token + ']' : token;\n  }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array<any>} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n  return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n  return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object<any, any>} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object<string, any>} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n  if (!utils.isObject(obj)) {\n    throw new TypeError('target must be an object');\n  }\n\n  // eslint-disable-next-line no-param-reassign\n  formData = formData || new (PlatformFormData || FormData)();\n\n  // eslint-disable-next-line no-param-reassign\n  options = utils.toFlatObject(options, {\n    metaTokens: true,\n    dots: false,\n    indexes: false\n  }, false, function defined(option, source) {\n    // eslint-disable-next-line no-eq-null,eqeqeq\n    return !utils.isUndefined(source[option]);\n  });\n\n  const metaTokens = options.metaTokens;\n  // eslint-disable-next-line no-use-before-define\n  const visitor = options.visitor || defaultVisitor;\n  const dots = options.dots;\n  const indexes = options.indexes;\n  const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n  const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n  if (!utils.isFunction(visitor)) {\n    throw new TypeError('visitor must be a function');\n  }\n\n  function convertValue(value) {\n    if (value === null) return '';\n\n    if (utils.isDate(value)) {\n      return value.toISOString();\n    }\n\n    if (utils.isBoolean(value)) {\n      return value.toString();\n    }\n\n    if (!useBlob && utils.isBlob(value)) {\n      throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n    }\n\n    if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n      return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n    }\n\n    return value;\n  }\n\n  /**\n   * Default visitor.\n   *\n   * @param {*} value\n   * @param {String|Number} key\n   * @param {Array<String|Number>} path\n   * @this {FormData}\n   *\n   * @returns {boolean} return true to visit the each prop of the value recursively\n   */\n  function defaultVisitor(value, key, path) {\n    let arr = value;\n\n    if (value && !path && typeof value === 'object') {\n      if (utils.endsWith(key, '{}')) {\n        // eslint-disable-next-line no-param-reassign\n        key = metaTokens ? key : key.slice(0, -2);\n        // eslint-disable-next-line no-param-reassign\n        value = JSON.stringify(value);\n      } else if (\n        (utils.isArray(value) && isFlatArray(value)) ||\n        ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n        )) {\n        // eslint-disable-next-line no-param-reassign\n        key = removeBrackets(key);\n\n        arr.forEach(function each(el, index) {\n          !(utils.isUndefined(el) || el === null) && formData.append(\n            // eslint-disable-next-line no-nested-ternary\n            indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n            convertValue(el)\n          );\n        });\n        return false;\n      }\n    }\n\n    if (isVisitable(value)) {\n      return true;\n    }\n\n    formData.append(renderKey(path, key, dots), convertValue(value));\n\n    return false;\n  }\n\n  const stack = [];\n\n  const exposedHelpers = Object.assign(predicates, {\n    defaultVisitor,\n    convertValue,\n    isVisitable\n  });\n\n  function build(value, path) {\n    if (utils.isUndefined(value)) return;\n\n    if (stack.indexOf(value) !== -1) {\n      throw Error('Circular reference detected in ' + path.join('.'));\n    }\n\n    stack.push(value);\n\n    utils.forEach(value, function each(el, key) {\n      const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n        formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n      );\n\n      if (result === true) {\n        build(el, path ? path.concat(key) : [key]);\n      }\n    });\n\n    stack.pop();\n  }\n\n  if (!utils.isObject(obj)) {\n    throw new TypeError('data must be an object');\n  }\n\n  build(obj);\n\n  return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n  const charMap = {\n    '!': '%21',\n    \"'\": '%27',\n    '(': '%28',\n    ')': '%29',\n    '~': '%7E',\n    '%20': '+',\n    '%00': '\\x00'\n  };\n  return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n    return charMap[match];\n  });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object<string, any>} params - The parameters to be converted to a FormData object.\n * @param {Object<string, any>} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n  this._pairs = [];\n\n  params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n  this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n  const _encode = encoder ? function(value) {\n    return encoder.call(this, value, encode);\n  } : encode;\n\n  return this._pairs.map(function each(pair) {\n    return _encode(pair[0]) + '=' + _encode(pair[1]);\n  }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n  return encodeURIComponent(val).\n    replace(/%3A/gi, ':').\n    replace(/%24/g, '$').\n    replace(/%2C/gi, ',').\n    replace(/%20/g, '+');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?(object|Function)} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n  /*eslint no-param-reassign:0*/\n  if (!params) {\n    return url;\n  }\n  \n  const _encode = options && options.encode || encode;\n\n  if (utils.isFunction(options)) {\n    options = {\n      serialize: options\n    };\n  } \n\n  const serializeFn = options && options.serialize;\n\n  let serializedParams;\n\n  if (serializeFn) {\n    serializedParams = serializeFn(params, options);\n  } else {\n    serializedParams = utils.isURLSearchParams(params) ?\n      params.toString() :\n      new AxiosURLSearchParams(params, options).toString(_encode);\n  }\n\n  if (serializedParams) {\n    const hashmarkIndex = url.indexOf(\"#\");\n\n    if (hashmarkIndex !== -1) {\n      url = url.slice(0, hashmarkIndex);\n    }\n    url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n  }\n\n  return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n  constructor() {\n    this.handlers = [];\n  }\n\n  /**\n   * Add a new interceptor to the stack\n   *\n   * @param {Function} fulfilled The function to handle `then` for a `Promise`\n   * @param {Function} rejected The function to handle `reject` for a `Promise`\n   *\n   * @return {Number} An ID used to remove interceptor later\n   */\n  use(fulfilled, rejected, options) {\n    this.handlers.push({\n      fulfilled,\n      rejected,\n      synchronous: options ? options.synchronous : false,\n      runWhen: options ? options.runWhen : null\n    });\n    return this.handlers.length - 1;\n  }\n\n  /**\n   * Remove an interceptor from the stack\n   *\n   * @param {Number} id The ID that was returned by `use`\n   *\n   * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n   */\n  eject(id) {\n    if (this.handlers[id]) {\n      this.handlers[id] = null;\n    }\n  }\n\n  /**\n   * Clear all interceptors from the stack\n   *\n   * @returns {void}\n   */\n  clear() {\n    if (this.handlers) {\n      this.handlers = [];\n    }\n  }\n\n  /**\n   * Iterate over all the registered interceptors\n   *\n   * This method is particularly useful for skipping over any\n   * interceptors that may have become `null` calling `eject`.\n   *\n   * @param {Function} fn The function to call for each interceptor\n   *\n   * @returns {void}\n   */\n  forEach(fn) {\n    utils.forEach(this.handlers, function forEachHandler(h) {\n      if (h !== null) {\n        fn(h);\n      }\n    });\n  }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n  silentJSONParsing: true,\n  forcedJSONParsing: true,\n  clarifyTimeoutError: false\n};\n","'use strict';\n\nimport AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js';\nexport default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;\n","'use strict';\n\nexport default typeof FormData !== 'undefined' ? FormData : null;\n","'use strict'\n\nexport default typeof Blob !== 'undefined' ? Blob : null\n","import URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\nimport Blob from './classes/Blob.js'\n\nexport default {\n  isBrowser: true,\n  classes: {\n    URLSearchParams,\n    FormData,\n    Blob\n  },\n  protocols: ['http', 'https', 'file', 'blob', 'url', 'data']\n};\n","const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst _navigator = typeof navigator === 'object' && navigator || undefined;\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n *  typeof window -> undefined\n *  typeof document -> undefined\n *\n * react-native:\n *  navigator.product -> 'ReactNative'\n * nativescript\n *  navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst hasStandardBrowserEnv = hasBrowserEnv &&\n  (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0);\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\nconst hasStandardBrowserWebWorkerEnv = (() => {\n  return (\n    typeof WorkerGlobalScope !== 'undefined' &&\n    // eslint-disable-next-line no-undef\n    self instanceof WorkerGlobalScope &&\n    typeof self.importScripts === 'function'\n  );\n})();\n\nconst origin = hasBrowserEnv && window.location.href || 'http://localhost';\n\nexport {\n  hasBrowserEnv,\n  hasStandardBrowserWebWorkerEnv,\n  hasStandardBrowserEnv,\n  _navigator as navigator,\n  origin\n}\n","import platform from './node/index.js';\nimport * as utils from './common/utils.js';\n\nexport default {\n  ...utils,\n  ...platform\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n  return toFormData(data, new platform.classes.URLSearchParams(), {\n    visitor: function(value, key, path, helpers) {\n      if (platform.isNode && utils.isBuffer(value)) {\n        this.append(key, value.toString('base64'));\n        return false;\n      }\n\n      return helpers.defaultVisitor.apply(this, arguments);\n    },\n    ...options\n  });\n}\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n  // foo[x][y][z]\n  // foo.x.y.z\n  // foo-x-y-z\n  // foo x y z\n  return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n    return match[0] === '[]' ? '' : match[1] || match[0];\n  });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array<any>} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n  const obj = {};\n  const keys = Object.keys(arr);\n  let i;\n  const len = keys.length;\n  let key;\n  for (i = 0; i < len; i++) {\n    key = keys[i];\n    obj[key] = arr[key];\n  }\n  return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object<string, any> | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n  function buildPath(path, value, target, index) {\n    let name = path[index++];\n\n    if (name === '__proto__') return true;\n\n    const isNumericKey = Number.isFinite(+name);\n    const isLast = index >= path.length;\n    name = !name && utils.isArray(target) ? target.length : name;\n\n    if (isLast) {\n      if (utils.hasOwnProp(target, name)) {\n        target[name] = [target[name], value];\n      } else {\n        target[name] = value;\n      }\n\n      return !isNumericKey;\n    }\n\n    if (!target[name] || !utils.isObject(target[name])) {\n      target[name] = [];\n    }\n\n    const result = buildPath(path, value, target[name], index);\n\n    if (result && utils.isArray(target[name])) {\n      target[name] = arrayToObject(target[name]);\n    }\n\n    return !isNumericKey;\n  }\n\n  if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n    const obj = {};\n\n    utils.forEachEntry(formData, (name, value) => {\n      buildPath(parsePropPath(name), value, obj, 0);\n    });\n\n    return obj;\n  }\n\n  return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n  if (utils.isString(rawValue)) {\n    try {\n      (parser || JSON.parse)(rawValue);\n      return utils.trim(rawValue);\n    } catch (e) {\n      if (e.name !== 'SyntaxError') {\n        throw e;\n      }\n    }\n  }\n\n  return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n  transitional: transitionalDefaults,\n\n  adapter: ['xhr', 'http', 'fetch'],\n\n  transformRequest: [function transformRequest(data, headers) {\n    const contentType = headers.getContentType() || '';\n    const hasJSONContentType = contentType.indexOf('application/json') > -1;\n    const isObjectPayload = utils.isObject(data);\n\n    if (isObjectPayload && utils.isHTMLForm(data)) {\n      data = new FormData(data);\n    }\n\n    const isFormData = utils.isFormData(data);\n\n    if (isFormData) {\n      return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n    }\n\n    if (utils.isArrayBuffer(data) ||\n      utils.isBuffer(data) ||\n      utils.isStream(data) ||\n      utils.isFile(data) ||\n      utils.isBlob(data) ||\n      utils.isReadableStream(data)\n    ) {\n      return data;\n    }\n    if (utils.isArrayBufferView(data)) {\n      return data.buffer;\n    }\n    if (utils.isURLSearchParams(data)) {\n      headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n      return data.toString();\n    }\n\n    let isFileList;\n\n    if (isObjectPayload) {\n      if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n        return toURLEncodedForm(data, this.formSerializer).toString();\n      }\n\n      if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n        const _FormData = this.env && this.env.FormData;\n\n        return toFormData(\n          isFileList ? {'files[]': data} : data,\n          _FormData && new _FormData(),\n          this.formSerializer\n        );\n      }\n    }\n\n    if (isObjectPayload || hasJSONContentType ) {\n      headers.setContentType('application/json', false);\n      return stringifySafely(data);\n    }\n\n    return data;\n  }],\n\n  transformResponse: [function transformResponse(data) {\n    const transitional = this.transitional || defaults.transitional;\n    const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n    const JSONRequested = this.responseType === 'json';\n\n    if (utils.isResponse(data) || utils.isReadableStream(data)) {\n      return data;\n    }\n\n    if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n      const silentJSONParsing = transitional && transitional.silentJSONParsing;\n      const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n      try {\n        return JSON.parse(data, this.parseReviver);\n      } catch (e) {\n        if (strictJSONParsing) {\n          if (e.name === 'SyntaxError') {\n            throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n          }\n          throw e;\n        }\n      }\n    }\n\n    return data;\n  }],\n\n  /**\n   * A timeout in milliseconds to abort a request. If set to 0 (default) a\n   * timeout is not created.\n   */\n  timeout: 0,\n\n  xsrfCookieName: 'XSRF-TOKEN',\n  xsrfHeaderName: 'X-XSRF-TOKEN',\n\n  maxContentLength: -1,\n  maxBodyLength: -1,\n\n  env: {\n    FormData: platform.classes.FormData,\n    Blob: platform.classes.Blob\n  },\n\n  validateStatus: function validateStatus(status) {\n    return status >= 200 && status < 300;\n  },\n\n  headers: {\n    common: {\n      'Accept': 'application/json, text/plain, */*',\n      'Content-Type': undefined\n    }\n  }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n  defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n  'age', 'authorization', 'content-length', 'content-type', 'etag',\n  'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n  'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n  'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n  const parsed = {};\n  let key;\n  let val;\n  let i;\n\n  rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n    i = line.indexOf(':');\n    key = line.substring(0, i).trim().toLowerCase();\n    val = line.substring(i + 1).trim();\n\n    if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n      return;\n    }\n\n    if (key === 'set-cookie') {\n      if (parsed[key]) {\n        parsed[key].push(val);\n      } else {\n        parsed[key] = [val];\n      }\n    } else {\n      parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n    }\n  });\n\n  return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n  return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n  if (value === false || value == null) {\n    return value;\n  }\n\n  return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n  const tokens = Object.create(null);\n  const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n  let match;\n\n  while ((match = tokensRE.exec(str))) {\n    tokens[match[1]] = match[2];\n  }\n\n  return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n  if (utils.isFunction(filter)) {\n    return filter.call(this, value, header);\n  }\n\n  if (isHeaderNameFilter) {\n    value = header;\n  }\n\n  if (!utils.isString(value)) return;\n\n  if (utils.isString(filter)) {\n    return value.indexOf(filter) !== -1;\n  }\n\n  if (utils.isRegExp(filter)) {\n    return filter.test(value);\n  }\n}\n\nfunction formatHeader(header) {\n  return header.trim()\n    .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n      return char.toUpperCase() + str;\n    });\n}\n\nfunction buildAccessors(obj, header) {\n  const accessorName = utils.toCamelCase(' ' + header);\n\n  ['get', 'set', 'has'].forEach(methodName => {\n    Object.defineProperty(obj, methodName + accessorName, {\n      value: function(arg1, arg2, arg3) {\n        return this[methodName].call(this, header, arg1, arg2, arg3);\n      },\n      configurable: true\n    });\n  });\n}\n\nclass AxiosHeaders {\n  constructor(headers) {\n    headers && this.set(headers);\n  }\n\n  set(header, valueOrRewrite, rewrite) {\n    const self = this;\n\n    function setHeader(_value, _header, _rewrite) {\n      const lHeader = normalizeHeader(_header);\n\n      if (!lHeader) {\n        throw new Error('header name must be a non-empty string');\n      }\n\n      const key = utils.findKey(self, lHeader);\n\n      if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n        self[key || _header] = normalizeValue(_value);\n      }\n    }\n\n    const setHeaders = (headers, _rewrite) =>\n      utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n    if (utils.isPlainObject(header) || header instanceof this.constructor) {\n      setHeaders(header, valueOrRewrite)\n    } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n      setHeaders(parseHeaders(header), valueOrRewrite);\n    } else if (utils.isObject(header) && utils.isIterable(header)) {\n      let obj = {}, dest, key;\n      for (const entry of header) {\n        if (!utils.isArray(entry)) {\n          throw TypeError('Object iterator must return a key-value pair');\n        }\n\n        obj[key = entry[0]] = (dest = obj[key]) ?\n          (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1];\n      }\n\n      setHeaders(obj, valueOrRewrite)\n    } else {\n      header != null && setHeader(valueOrRewrite, header, rewrite);\n    }\n\n    return this;\n  }\n\n  get(header, parser) {\n    header = normalizeHeader(header);\n\n    if (header) {\n      const key = utils.findKey(this, header);\n\n      if (key) {\n        const value = this[key];\n\n        if (!parser) {\n          return value;\n        }\n\n        if (parser === true) {\n          return parseTokens(value);\n        }\n\n        if (utils.isFunction(parser)) {\n          return parser.call(this, value, key);\n        }\n\n        if (utils.isRegExp(parser)) {\n          return parser.exec(value);\n        }\n\n        throw new TypeError('parser must be boolean|regexp|function');\n      }\n    }\n  }\n\n  has(header, matcher) {\n    header = normalizeHeader(header);\n\n    if (header) {\n      const key = utils.findKey(this, header);\n\n      return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n    }\n\n    return false;\n  }\n\n  delete(header, matcher) {\n    const self = this;\n    let deleted = false;\n\n    function deleteHeader(_header) {\n      _header = normalizeHeader(_header);\n\n      if (_header) {\n        const key = utils.findKey(self, _header);\n\n        if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n          delete self[key];\n\n          deleted = true;\n        }\n      }\n    }\n\n    if (utils.isArray(header)) {\n      header.forEach(deleteHeader);\n    } else {\n      deleteHeader(header);\n    }\n\n    return deleted;\n  }\n\n  clear(matcher) {\n    const keys = Object.keys(this);\n    let i = keys.length;\n    let deleted = false;\n\n    while (i--) {\n      const key = keys[i];\n      if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n        delete this[key];\n        deleted = true;\n      }\n    }\n\n    return deleted;\n  }\n\n  normalize(format) {\n    const self = this;\n    const headers = {};\n\n    utils.forEach(this, (value, header) => {\n      const key = utils.findKey(headers, header);\n\n      if (key) {\n        self[key] = normalizeValue(value);\n        delete self[header];\n        return;\n      }\n\n      const normalized = format ? formatHeader(header) : String(header).trim();\n\n      if (normalized !== header) {\n        delete self[header];\n      }\n\n      self[normalized] = normalizeValue(value);\n\n      headers[normalized] = true;\n    });\n\n    return this;\n  }\n\n  concat(...targets) {\n    return this.constructor.concat(this, ...targets);\n  }\n\n  toJSON(asStrings) {\n    const obj = Object.create(null);\n\n    utils.forEach(this, (value, header) => {\n      value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n    });\n\n    return obj;\n  }\n\n  [Symbol.iterator]() {\n    return Object.entries(this.toJSON())[Symbol.iterator]();\n  }\n\n  toString() {\n    return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n  }\n\n  getSetCookie() {\n    return this.get(\"set-cookie\") || [];\n  }\n\n  get [Symbol.toStringTag]() {\n    return 'AxiosHeaders';\n  }\n\n  static from(thing) {\n    return thing instanceof this ? thing : new this(thing);\n  }\n\n  static concat(first, ...targets) {\n    const computed = new this(first);\n\n    targets.forEach((target) => computed.set(target));\n\n    return computed;\n  }\n\n  static accessor(header) {\n    const internals = this[$internals] = (this[$internals] = {\n      accessors: {}\n    });\n\n    const accessors = internals.accessors;\n    const prototype = this.prototype;\n\n    function defineAccessor(_header) {\n      const lHeader = normalizeHeader(_header);\n\n      if (!accessors[lHeader]) {\n        buildAccessors(prototype, _header);\n        accessors[lHeader] = true;\n      }\n    }\n\n    utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n    return this;\n  }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n  let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n  return {\n    get: () => value,\n    set(headerValue) {\n      this[mapped] = headerValue;\n    }\n  }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n  const config = this || defaults;\n  const context = response || config;\n  const headers = AxiosHeaders.from(context.headers);\n  let data = context.data;\n\n  utils.forEach(fns, function transform(fn) {\n    data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n  });\n\n  headers.normalize();\n\n  return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n  return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n  // eslint-disable-next-line no-eq-null,eqeqeq\n  AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n  this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n  __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n  const validateStatus = response.config.validateStatus;\n  if (!response.status || !validateStatus || validateStatus(response.status)) {\n    resolve(response);\n  } else {\n    reject(new AxiosError(\n      'Request failed with status code ' + response.status,\n      [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n      response.config,\n      response.request,\n      response\n    ));\n  }\n}\n","'use strict';\n\nexport default function parseProtocol(url) {\n  const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n  return match && match[1] || '';\n}\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n  samplesCount = samplesCount || 10;\n  const bytes = new Array(samplesCount);\n  const timestamps = new Array(samplesCount);\n  let head = 0;\n  let tail = 0;\n  let firstSampleTS;\n\n  min = min !== undefined ? min : 1000;\n\n  return function push(chunkLength) {\n    const now = Date.now();\n\n    const startedAt = timestamps[tail];\n\n    if (!firstSampleTS) {\n      firstSampleTS = now;\n    }\n\n    bytes[head] = chunkLength;\n    timestamps[head] = now;\n\n    let i = tail;\n    let bytesCount = 0;\n\n    while (i !== head) {\n      bytesCount += bytes[i++];\n      i = i % samplesCount;\n    }\n\n    head = (head + 1) % samplesCount;\n\n    if (head === tail) {\n      tail = (tail + 1) % samplesCount;\n    }\n\n    if (now - firstSampleTS < min) {\n      return;\n    }\n\n    const passed = startedAt && now - startedAt;\n\n    return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n  };\n}\n\nexport default speedometer;\n","/**\n * Throttle decorator\n * @param {Function} fn\n * @param {Number} freq\n * @return {Function}\n */\nfunction throttle(fn, freq) {\n  let timestamp = 0;\n  let threshold = 1000 / freq;\n  let lastArgs;\n  let timer;\n\n  const invoke = (args, now = Date.now()) => {\n    timestamp = now;\n    lastArgs = null;\n    if (timer) {\n      clearTimeout(timer);\n      timer = null;\n    }\n    fn(...args);\n  }\n\n  const throttled = (...args) => {\n    const now = Date.now();\n    const passed = now - timestamp;\n    if ( passed >= threshold) {\n      invoke(args, now);\n    } else {\n      lastArgs = args;\n      if (!timer) {\n        timer = setTimeout(() => {\n          timer = null;\n          invoke(lastArgs)\n        }, threshold - passed);\n      }\n    }\n  }\n\n  const flush = () => lastArgs && invoke(lastArgs);\n\n  return [throttled, flush];\n}\n\nexport default throttle;\n","import speedometer from \"./speedometer.js\";\nimport throttle from \"./throttle.js\";\nimport utils from \"../utils.js\";\n\nexport const progressEventReducer = (listener, isDownloadStream, freq = 3) => {\n  let bytesNotified = 0;\n  const _speedometer = speedometer(50, 250);\n\n  return throttle(e => {\n    const loaded = e.loaded;\n    const total = e.lengthComputable ? e.total : undefined;\n    const progressBytes = loaded - bytesNotified;\n    const rate = _speedometer(progressBytes);\n    const inRange = loaded <= total;\n\n    bytesNotified = loaded;\n\n    const data = {\n      loaded,\n      total,\n      progress: total ? (loaded / total) : undefined,\n      bytes: progressBytes,\n      rate: rate ? rate : undefined,\n      estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n      event: e,\n      lengthComputable: total != null,\n      [isDownloadStream ? 'download' : 'upload']: true\n    };\n\n    listener(data);\n  }, freq);\n}\n\nexport const progressEventDecorator = (total, throttled) => {\n  const lengthComputable = total != null;\n\n  return [(loaded) => throttled[0]({\n    lengthComputable,\n    total,\n    loaded\n  }), throttled[1]];\n}\n\nexport const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args));\n","import platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {\n  url = new URL(url, platform.origin);\n\n  return (\n    origin.protocol === url.protocol &&\n    origin.host === url.host &&\n    (isMSIE || origin.port === url.port)\n  );\n})(\n  new URL(platform.origin),\n  platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)\n) : () => true;\n","import utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ?\n\n  // Standard browser envs support document.cookie\n  {\n    write(name, value, expires, path, domain, secure) {\n      const cookie = [name + '=' + encodeURIComponent(value)];\n\n      utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());\n\n      utils.isString(path) && cookie.push('path=' + path);\n\n      utils.isString(domain) && cookie.push('domain=' + domain);\n\n      secure === true && cookie.push('secure');\n\n      document.cookie = cookie.join('; ');\n    },\n\n    read(name) {\n      const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n      return (match ? decodeURIComponent(match[3]) : null);\n    },\n\n    remove(name) {\n      this.write(name, '', Date.now() - 86400000);\n    }\n  }\n\n  :\n\n  // Non-standard browser env (web workers, react-native) lack needed support.\n  {\n    write() {},\n    read() {\n      return null;\n    },\n    remove() {}\n  };\n\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n  // A URL is considered absolute if it begins with \"<scheme>://\" or \"//\" (protocol-relative URL).\n  // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n  // by any combination of letters, digits, plus, period, or hyphen.\n  return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n  return relativeURL\n    ? baseURL.replace(/\\/?\\/$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n    : baseURL;\n}\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {\n  let isRelativeUrl = !isAbsoluteURL(requestedURL);\n  if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {\n    return combineURLs(baseURL, requestedURL);\n  }\n  return requestedURL;\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n  // eslint-disable-next-line no-param-reassign\n  config2 = config2 || {};\n  const config = {};\n\n  function getMergedValue(target, source, prop, caseless) {\n    if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n      return utils.merge.call({caseless}, target, source);\n    } else if (utils.isPlainObject(source)) {\n      return utils.merge({}, source);\n    } else if (utils.isArray(source)) {\n      return source.slice();\n    }\n    return source;\n  }\n\n  // eslint-disable-next-line consistent-return\n  function mergeDeepProperties(a, b, prop , caseless) {\n    if (!utils.isUndefined(b)) {\n      return getMergedValue(a, b, prop , caseless);\n    } else if (!utils.isUndefined(a)) {\n      return getMergedValue(undefined, a, prop , caseless);\n    }\n  }\n\n  // eslint-disable-next-line consistent-return\n  function valueFromConfig2(a, b) {\n    if (!utils.isUndefined(b)) {\n      return getMergedValue(undefined, b);\n    }\n  }\n\n  // eslint-disable-next-line consistent-return\n  function defaultToConfig2(a, b) {\n    if (!utils.isUndefined(b)) {\n      return getMergedValue(undefined, b);\n    } else if (!utils.isUndefined(a)) {\n      return getMergedValue(undefined, a);\n    }\n  }\n\n  // eslint-disable-next-line consistent-return\n  function mergeDirectKeys(a, b, prop) {\n    if (prop in config2) {\n      return getMergedValue(a, b);\n    } else if (prop in config1) {\n      return getMergedValue(undefined, a);\n    }\n  }\n\n  const mergeMap = {\n    url: valueFromConfig2,\n    method: valueFromConfig2,\n    data: valueFromConfig2,\n    baseURL: defaultToConfig2,\n    transformRequest: defaultToConfig2,\n    transformResponse: defaultToConfig2,\n    paramsSerializer: defaultToConfig2,\n    timeout: defaultToConfig2,\n    timeoutMessage: defaultToConfig2,\n    withCredentials: defaultToConfig2,\n    withXSRFToken: defaultToConfig2,\n    adapter: defaultToConfig2,\n    responseType: defaultToConfig2,\n    xsrfCookieName: defaultToConfig2,\n    xsrfHeaderName: defaultToConfig2,\n    onUploadProgress: defaultToConfig2,\n    onDownloadProgress: defaultToConfig2,\n    decompress: defaultToConfig2,\n    maxContentLength: defaultToConfig2,\n    maxBodyLength: defaultToConfig2,\n    beforeRedirect: defaultToConfig2,\n    transport: defaultToConfig2,\n    httpAgent: defaultToConfig2,\n    httpsAgent: defaultToConfig2,\n    cancelToken: defaultToConfig2,\n    socketPath: defaultToConfig2,\n    responseEncoding: defaultToConfig2,\n    validateStatus: mergeDirectKeys,\n    headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)\n  };\n\n  utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {\n    const merge = mergeMap[prop] || mergeDeepProperties;\n    const configValue = merge(config1[prop], config2[prop], prop);\n    (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n  });\n\n  return config;\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport isURLSameOrigin from \"./isURLSameOrigin.js\";\nimport cookies from \"./cookies.js\";\nimport buildFullPath from \"../core/buildFullPath.js\";\nimport mergeConfig from \"../core/mergeConfig.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport buildURL from \"./buildURL.js\";\n\nexport default (config) => {\n  const newConfig = mergeConfig({}, config);\n\n  let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;\n\n  newConfig.headers = headers = AxiosHeaders.from(headers);\n\n  newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);\n\n  // HTTP basic authentication\n  if (auth) {\n    headers.set('Authorization', 'Basic ' +\n      btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))\n    );\n  }\n\n  if (utils.isFormData(data)) {\n    if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {\n      headers.setContentType(undefined); // browser handles it\n    } else if (utils.isFunction(data.getHeaders)) {\n      // Node.js FormData (like form-data package)\n      const formHeaders = data.getHeaders();\n      // Only set safe headers to avoid overwriting security headers\n      const allowedHeaders = ['content-type', 'content-length'];\n      Object.entries(formHeaders).forEach(([key, val]) => {\n        if (allowedHeaders.includes(key.toLowerCase())) {\n          headers.set(key, val);\n        }\n      });\n    }\n  }  \n\n  // Add xsrf header\n  // This is only done if running in a standard browser environment.\n  // Specifically not if we're in a web worker, or react-native.\n\n  if (platform.hasStandardBrowserEnv) {\n    withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));\n\n    if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {\n      // Add xsrf header\n      const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);\n\n      if (xsrfValue) {\n        headers.set(xsrfHeaderName, xsrfValue);\n      }\n    }\n  }\n\n  return newConfig;\n}\n\n","import utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport {progressEventReducer} from '../helpers/progressEventReducer.js';\nimport resolveConfig from \"../helpers/resolveConfig.js\";\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n  return new Promise(function dispatchXhrRequest(resolve, reject) {\n    const _config = resolveConfig(config);\n    let requestData = _config.data;\n    const requestHeaders = AxiosHeaders.from(_config.headers).normalize();\n    let {responseType, onUploadProgress, onDownloadProgress} = _config;\n    let onCanceled;\n    let uploadThrottled, downloadThrottled;\n    let flushUpload, flushDownload;\n\n    function done() {\n      flushUpload && flushUpload(); // flush events\n      flushDownload && flushDownload(); // flush events\n\n      _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);\n\n      _config.signal && _config.signal.removeEventListener('abort', onCanceled);\n    }\n\n    let request = new XMLHttpRequest();\n\n    request.open(_config.method.toUpperCase(), _config.url, true);\n\n    // Set the request timeout in MS\n    request.timeout = _config.timeout;\n\n    function onloadend() {\n      if (!request) {\n        return;\n      }\n      // Prepare the response\n      const responseHeaders = AxiosHeaders.from(\n        'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n      );\n      const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n        request.responseText : request.response;\n      const response = {\n        data: responseData,\n        status: request.status,\n        statusText: request.statusText,\n        headers: responseHeaders,\n        config,\n        request\n      };\n\n      settle(function _resolve(value) {\n        resolve(value);\n        done();\n      }, function _reject(err) {\n        reject(err);\n        done();\n      }, response);\n\n      // Clean up request\n      request = null;\n    }\n\n    if ('onloadend' in request) {\n      // Use onloadend if available\n      request.onloadend = onloadend;\n    } else {\n      // Listen for ready state to emulate onloadend\n      request.onreadystatechange = function handleLoad() {\n        if (!request || request.readyState !== 4) {\n          return;\n        }\n\n        // The request errored out and we didn't get a response, this will be\n        // handled by onerror instead\n        // With one exception: request that using file: protocol, most browsers\n        // will return status as 0 even though it's a successful request\n        if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n          return;\n        }\n        // readystate handler is calling before onerror or ontimeout handlers,\n        // so we should call onloadend on the next 'tick'\n        setTimeout(onloadend);\n      };\n    }\n\n    // Handle browser request cancellation (as opposed to a manual cancellation)\n    request.onabort = function handleAbort() {\n      if (!request) {\n        return;\n      }\n\n      reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n      // Clean up request\n      request = null;\n    };\n\n    // Handle low level network errors\n  request.onerror = function handleError(event) {\n       // Browsers deliver a ProgressEvent in XHR onerror\n       // (message may be empty; when present, surface it)\n       // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event\n       const msg = event && event.message ? event.message : 'Network Error';\n       const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);\n       // attach the underlying event for consumers who want details\n       err.event = event || null;\n       reject(err);\n       request = null;\n    };\n    \n    // Handle timeout\n    request.ontimeout = function handleTimeout() {\n      let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';\n      const transitional = _config.transitional || transitionalDefaults;\n      if (_config.timeoutErrorMessage) {\n        timeoutErrorMessage = _config.timeoutErrorMessage;\n      }\n      reject(new AxiosError(\n        timeoutErrorMessage,\n        transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n        config,\n        request));\n\n      // Clean up request\n      request = null;\n    };\n\n    // Remove Content-Type if data is undefined\n    requestData === undefined && requestHeaders.setContentType(null);\n\n    // Add headers to the request\n    if ('setRequestHeader' in request) {\n      utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n        request.setRequestHeader(key, val);\n      });\n    }\n\n    // Add withCredentials to request if needed\n    if (!utils.isUndefined(_config.withCredentials)) {\n      request.withCredentials = !!_config.withCredentials;\n    }\n\n    // Add responseType to request if needed\n    if (responseType && responseType !== 'json') {\n      request.responseType = _config.responseType;\n    }\n\n    // Handle progress if needed\n    if (onDownloadProgress) {\n      ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));\n      request.addEventListener('progress', downloadThrottled);\n    }\n\n    // Not all browsers support upload events\n    if (onUploadProgress && request.upload) {\n      ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));\n\n      request.upload.addEventListener('progress', uploadThrottled);\n\n      request.upload.addEventListener('loadend', flushUpload);\n    }\n\n    if (_config.cancelToken || _config.signal) {\n      // Handle cancellation\n      // eslint-disable-next-line func-names\n      onCanceled = cancel => {\n        if (!request) {\n          return;\n        }\n        reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n        request.abort();\n        request = null;\n      };\n\n      _config.cancelToken && _config.cancelToken.subscribe(onCanceled);\n      if (_config.signal) {\n        _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);\n      }\n    }\n\n    const protocol = parseProtocol(_config.url);\n\n    if (protocol && platform.protocols.indexOf(protocol) === -1) {\n      reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n      return;\n    }\n\n\n    // Send the request\n    request.send(requestData || null);\n  });\n}\n","import CanceledError from \"../cancel/CanceledError.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport utils from '../utils.js';\n\nconst composeSignals = (signals, timeout) => {\n  const {length} = (signals = signals ? signals.filter(Boolean) : []);\n\n  if (timeout || length) {\n    let controller = new AbortController();\n\n    let aborted;\n\n    const onabort = function (reason) {\n      if (!aborted) {\n        aborted = true;\n        unsubscribe();\n        const err = reason instanceof Error ? reason : this.reason;\n        controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));\n      }\n    }\n\n    let timer = timeout && setTimeout(() => {\n      timer = null;\n      onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))\n    }, timeout)\n\n    const unsubscribe = () => {\n      if (signals) {\n        timer && clearTimeout(timer);\n        timer = null;\n        signals.forEach(signal => {\n          signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);\n        });\n        signals = null;\n      }\n    }\n\n    signals.forEach((signal) => signal.addEventListener('abort', onabort));\n\n    const {signal} = controller;\n\n    signal.unsubscribe = () => utils.asap(unsubscribe);\n\n    return signal;\n  }\n}\n\nexport default composeSignals;\n","\nexport const streamChunk = function* (chunk, chunkSize) {\n  let len = chunk.byteLength;\n\n  if (!chunkSize || len < chunkSize) {\n    yield chunk;\n    return;\n  }\n\n  let pos = 0;\n  let end;\n\n  while (pos < len) {\n    end = pos + chunkSize;\n    yield chunk.slice(pos, end);\n    pos = end;\n  }\n}\n\nexport const readBytes = async function* (iterable, chunkSize) {\n  for await (const chunk of readStream(iterable)) {\n    yield* streamChunk(chunk, chunkSize);\n  }\n}\n\nconst readStream = async function* (stream) {\n  if (stream[Symbol.asyncIterator]) {\n    yield* stream;\n    return;\n  }\n\n  const reader = stream.getReader();\n  try {\n    for (;;) {\n      const {done, value} = await reader.read();\n      if (done) {\n        break;\n      }\n      yield value;\n    }\n  } finally {\n    await reader.cancel();\n  }\n}\n\nexport const trackStream = (stream, chunkSize, onProgress, onFinish) => {\n  const iterator = readBytes(stream, chunkSize);\n\n  let bytes = 0;\n  let done;\n  let _onFinish = (e) => {\n    if (!done) {\n      done = true;\n      onFinish && onFinish(e);\n    }\n  }\n\n  return new ReadableStream({\n    async pull(controller) {\n      try {\n        const {done, value} = await iterator.next();\n\n        if (done) {\n         _onFinish();\n          controller.close();\n          return;\n        }\n\n        let len = value.byteLength;\n        if (onProgress) {\n          let loadedBytes = bytes += len;\n          onProgress(loadedBytes);\n        }\n        controller.enqueue(new Uint8Array(value));\n      } catch (err) {\n        _onFinish(err);\n        throw err;\n      }\n    },\n    cancel(reason) {\n      _onFinish(reason);\n      return iterator.return();\n    }\n  }, {\n    highWaterMark: 2\n  })\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport composeSignals from \"../helpers/composeSignals.js\";\nimport {trackStream} from \"../helpers/trackStream.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\nimport resolveConfig from \"../helpers/resolveConfig.js\";\nimport settle from \"../core/settle.js\";\n\nconst DEFAULT_CHUNK_SIZE = 64 * 1024;\n\nconst {isFunction} = utils;\n\nconst globalFetchAPI = (({Request, Response}) => ({\n  Request, Response\n}))(utils.global);\n\nconst {\n  ReadableStream, TextEncoder\n} = utils.global;\n\n\nconst test = (fn, ...args) => {\n  try {\n    return !!fn(...args);\n  } catch (e) {\n    return false\n  }\n}\n\nconst factory = (env) => {\n  env = utils.merge.call({\n    skipUndefined: true\n  }, globalFetchAPI, env);\n\n  const {fetch: envFetch, Request, Response} = env;\n  const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';\n  const isRequestSupported = isFunction(Request);\n  const isResponseSupported = isFunction(Response);\n\n  if (!isFetchSupported) {\n    return false;\n  }\n\n  const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);\n\n  const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?\n      ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :\n      async (str) => new Uint8Array(await new Request(str).arrayBuffer())\n  );\n\n  const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {\n    let duplexAccessed = false;\n\n    const hasContentType = new Request(platform.origin, {\n      body: new ReadableStream(),\n      method: 'POST',\n      get duplex() {\n        duplexAccessed = true;\n        return 'half';\n      },\n    }).headers.has('Content-Type');\n\n    return duplexAccessed && !hasContentType;\n  });\n\n  const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&\n    test(() => utils.isReadableStream(new Response('').body));\n\n  const resolvers = {\n    stream: supportsResponseStream && ((res) => res.body)\n  };\n\n  isFetchSupported && ((() => {\n    ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {\n      !resolvers[type] && (resolvers[type] = (res, config) => {\n        let method = res && res[type];\n\n        if (method) {\n          return method.call(res);\n        }\n\n        throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);\n      })\n    });\n  })());\n\n  const getBodyLength = async (body) => {\n    if (body == null) {\n      return 0;\n    }\n\n    if (utils.isBlob(body)) {\n      return body.size;\n    }\n\n    if (utils.isSpecCompliantForm(body)) {\n      const _request = new Request(platform.origin, {\n        method: 'POST',\n        body,\n      });\n      return (await _request.arrayBuffer()).byteLength;\n    }\n\n    if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {\n      return body.byteLength;\n    }\n\n    if (utils.isURLSearchParams(body)) {\n      body = body + '';\n    }\n\n    if (utils.isString(body)) {\n      return (await encodeText(body)).byteLength;\n    }\n  }\n\n  const resolveBodyLength = async (headers, body) => {\n    const length = utils.toFiniteNumber(headers.getContentLength());\n\n    return length == null ? getBodyLength(body) : length;\n  }\n\n  return async (config) => {\n    let {\n      url,\n      method,\n      data,\n      signal,\n      cancelToken,\n      timeout,\n      onDownloadProgress,\n      onUploadProgress,\n      responseType,\n      headers,\n      withCredentials = 'same-origin',\n      fetchOptions\n    } = resolveConfig(config);\n\n    let _fetch = envFetch || fetch;\n\n    responseType = responseType ? (responseType + '').toLowerCase() : 'text';\n\n    let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);\n\n    let request = null;\n\n    const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {\n      composedSignal.unsubscribe();\n    });\n\n    let requestContentLength;\n\n    try {\n      if (\n        onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&\n        (requestContentLength = await resolveBodyLength(headers, data)) !== 0\n      ) {\n        let _request = new Request(url, {\n          method: 'POST',\n          body: data,\n          duplex: \"half\"\n        });\n\n        let contentTypeHeader;\n\n        if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {\n          headers.setContentType(contentTypeHeader)\n        }\n\n        if (_request.body) {\n          const [onProgress, flush] = progressEventDecorator(\n            requestContentLength,\n            progressEventReducer(asyncDecorator(onUploadProgress))\n          );\n\n          data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);\n        }\n      }\n\n      if (!utils.isString(withCredentials)) {\n        withCredentials = withCredentials ? 'include' : 'omit';\n      }\n\n      // Cloudflare Workers throws when credentials are defined\n      // see https://github.com/cloudflare/workerd/issues/902\n      const isCredentialsSupported = isRequestSupported && \"credentials\" in Request.prototype;\n\n      const resolvedOptions = {\n        ...fetchOptions,\n        signal: composedSignal,\n        method: method.toUpperCase(),\n        headers: headers.normalize().toJSON(),\n        body: data,\n        duplex: \"half\",\n        credentials: isCredentialsSupported ? withCredentials : undefined\n      };\n\n      request = isRequestSupported && new Request(url, resolvedOptions);\n\n      let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));\n\n      const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');\n\n      if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {\n        const options = {};\n\n        ['status', 'statusText', 'headers'].forEach(prop => {\n          options[prop] = response[prop];\n        });\n\n        const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));\n\n        const [onProgress, flush] = onDownloadProgress && progressEventDecorator(\n          responseContentLength,\n          progressEventReducer(asyncDecorator(onDownloadProgress), true)\n        ) || [];\n\n        response = new Response(\n          trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {\n            flush && flush();\n            unsubscribe && unsubscribe();\n          }),\n          options\n        );\n      }\n\n      responseType = responseType || 'text';\n\n      let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);\n\n      !isStreamResponse && unsubscribe && unsubscribe();\n\n      return await new Promise((resolve, reject) => {\n        settle(resolve, reject, {\n          data: responseData,\n          headers: AxiosHeaders.from(response.headers),\n          status: response.status,\n          statusText: response.statusText,\n          config,\n          request\n        })\n      })\n    } catch (err) {\n      unsubscribe && unsubscribe();\n\n      if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {\n        throw Object.assign(\n          new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),\n          {\n            cause: err.cause || err\n          }\n        )\n      }\n\n      throw AxiosError.from(err, err && err.code, config, request);\n    }\n  }\n}\n\nconst seedCache = new Map();\n\nexport const getFetch = (config) => {\n  let env = config ? config.env : {};\n  const {fetch, Request, Response} = env;\n  const seeds = [\n    Request, Response, fetch\n  ];\n\n  let len = seeds.length, i = len,\n    seed, target, map = seedCache;\n\n  while (i--) {\n    seed = seeds[i];\n    target = map.get(seed);\n\n    target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))\n\n    map = target;\n  }\n\n  return target;\n};\n\nconst adapter = getFetch();\n\nexport default adapter;\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport * as fetchAdapter from './fetch.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n  http: httpAdapter,\n  xhr: xhrAdapter,\n  fetch: {\n    get: fetchAdapter.getFetch,\n  }\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n  if (fn) {\n    try {\n      Object.defineProperty(fn, 'name', {value});\n    } catch (e) {\n      // eslint-disable-next-line no-empty\n    }\n    Object.defineProperty(fn, 'adapterName', {value});\n  }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n  getAdapter: (adapters, config) => {\n    adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n    const {length} = adapters;\n    let nameOrAdapter;\n    let adapter;\n\n    const rejectedReasons = {};\n\n    for (let i = 0; i < length; i++) {\n      nameOrAdapter = adapters[i];\n      let id;\n\n      adapter = nameOrAdapter;\n\n      if (!isResolvedHandle(nameOrAdapter)) {\n        adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n        if (adapter === undefined) {\n          throw new AxiosError(`Unknown adapter '${id}'`);\n        }\n      }\n\n      if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {\n        break;\n      }\n\n      rejectedReasons[id || '#' + i] = adapter;\n    }\n\n    if (!adapter) {\n\n      const reasons = Object.entries(rejectedReasons)\n        .map(([id, state]) => `adapter ${id} ` +\n          (state === false ? 'is not supported by the environment' : 'is not available in the build')\n        );\n\n      let s = length ?\n        (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n        'as no adapter specified';\n\n      throw new AxiosError(\n        `There is no suitable adapter to dispatch the request ` + s,\n        'ERR_NOT_SUPPORT'\n      );\n    }\n\n    return adapter;\n  },\n  adapters: knownAdapters\n}\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n  if (config.cancelToken) {\n    config.cancelToken.throwIfRequested();\n  }\n\n  if (config.signal && config.signal.aborted) {\n    throw new CanceledError(null, config);\n  }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n  throwIfCancellationRequested(config);\n\n  config.headers = AxiosHeaders.from(config.headers);\n\n  // Transform request data\n  config.data = transformData.call(\n    config,\n    config.transformRequest\n  );\n\n  if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n    config.headers.setContentType('application/x-www-form-urlencoded', false);\n  }\n\n  const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);\n\n  return adapter(config).then(function onAdapterResolution(response) {\n    throwIfCancellationRequested(config);\n\n    // Transform response data\n    response.data = transformData.call(\n      config,\n      config.transformResponse,\n      response\n    );\n\n    response.headers = AxiosHeaders.from(response.headers);\n\n    return response;\n  }, function onAdapterRejection(reason) {\n    if (!isCancel(reason)) {\n      throwIfCancellationRequested(config);\n\n      // Transform response data\n      if (reason && reason.response) {\n        reason.response.data = transformData.call(\n          config,\n          config.transformResponse,\n          reason.response\n        );\n        reason.response.headers = AxiosHeaders.from(reason.response.headers);\n      }\n    }\n\n    return Promise.reject(reason);\n  });\n}\n","export const VERSION = \"1.12.2\";","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n  validators[type] = function validator(thing) {\n    return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n  };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n  function formatMessage(opt, desc) {\n    return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n  }\n\n  // eslint-disable-next-line func-names\n  return (value, opt, opts) => {\n    if (validator === false) {\n      throw new AxiosError(\n        formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n        AxiosError.ERR_DEPRECATED\n      );\n    }\n\n    if (version && !deprecatedWarnings[opt]) {\n      deprecatedWarnings[opt] = true;\n      // eslint-disable-next-line no-console\n      console.warn(\n        formatMessage(\n          opt,\n          ' has been deprecated since v' + version + ' and will be removed in the near future'\n        )\n      );\n    }\n\n    return validator ? validator(value, opt, opts) : true;\n  };\n};\n\nvalidators.spelling = function spelling(correctSpelling) {\n  return (value, opt) => {\n    // eslint-disable-next-line no-console\n    console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);\n    return true;\n  }\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n  if (typeof options !== 'object') {\n    throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n  }\n  const keys = Object.keys(options);\n  let i = keys.length;\n  while (i-- > 0) {\n    const opt = keys[i];\n    const validator = schema[opt];\n    if (validator) {\n      const value = options[opt];\n      const result = value === undefined || validator(value, opt, options);\n      if (result !== true) {\n        throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n      }\n      continue;\n    }\n    if (allowUnknown !== true) {\n      throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n    }\n  }\n}\n\nexport default {\n  assertOptions,\n  validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n  constructor(instanceConfig) {\n    this.defaults = instanceConfig || {};\n    this.interceptors = {\n      request: new InterceptorManager(),\n      response: new InterceptorManager()\n    };\n  }\n\n  /**\n   * Dispatch a request\n   *\n   * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n   * @param {?Object} config\n   *\n   * @returns {Promise} The Promise to be fulfilled\n   */\n  async request(configOrUrl, config) {\n    try {\n      return await this._request(configOrUrl, config);\n    } catch (err) {\n      if (err instanceof Error) {\n        let dummy = {};\n\n        Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());\n\n        // slice off the Error: ... line\n        const stack = dummy.stack ? dummy.stack.replace(/^.+\\n/, '') : '';\n        try {\n          if (!err.stack) {\n            err.stack = stack;\n            // match without the 2 top stack lines\n          } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\\n.+\\n/, ''))) {\n            err.stack += '\\n' + stack\n          }\n        } catch (e) {\n          // ignore the case where \"stack\" is an un-writable property\n        }\n      }\n\n      throw err;\n    }\n  }\n\n  _request(configOrUrl, config) {\n    /*eslint no-param-reassign:0*/\n    // Allow for axios('example/url'[, config]) a la fetch API\n    if (typeof configOrUrl === 'string') {\n      config = config || {};\n      config.url = configOrUrl;\n    } else {\n      config = configOrUrl || {};\n    }\n\n    config = mergeConfig(this.defaults, config);\n\n    const {transitional, paramsSerializer, headers} = config;\n\n    if (transitional !== undefined) {\n      validator.assertOptions(transitional, {\n        silentJSONParsing: validators.transitional(validators.boolean),\n        forcedJSONParsing: validators.transitional(validators.boolean),\n        clarifyTimeoutError: validators.transitional(validators.boolean)\n      }, false);\n    }\n\n    if (paramsSerializer != null) {\n      if (utils.isFunction(paramsSerializer)) {\n        config.paramsSerializer = {\n          serialize: paramsSerializer\n        }\n      } else {\n        validator.assertOptions(paramsSerializer, {\n          encode: validators.function,\n          serialize: validators.function\n        }, true);\n      }\n    }\n\n    // Set config.allowAbsoluteUrls\n    if (config.allowAbsoluteUrls !== undefined) {\n      // do nothing\n    } else if (this.defaults.allowAbsoluteUrls !== undefined) {\n      config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;\n    } else {\n      config.allowAbsoluteUrls = true;\n    }\n\n    validator.assertOptions(config, {\n      baseUrl: validators.spelling('baseURL'),\n      withXsrfToken: validators.spelling('withXSRFToken')\n    }, true);\n\n    // Set config.method\n    config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n    // Flatten headers\n    let contextHeaders = headers && utils.merge(\n      headers.common,\n      headers[config.method]\n    );\n\n    headers && utils.forEach(\n      ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n      (method) => {\n        delete headers[method];\n      }\n    );\n\n    config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n    // filter out skipped interceptors\n    const requestInterceptorChain = [];\n    let synchronousRequestInterceptors = true;\n    this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n      if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n        return;\n      }\n\n      synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n      requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n    });\n\n    const responseInterceptorChain = [];\n    this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n      responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n    });\n\n    let promise;\n    let i = 0;\n    let len;\n\n    if (!synchronousRequestInterceptors) {\n      const chain = [dispatchRequest.bind(this), undefined];\n      chain.unshift(...requestInterceptorChain);\n      chain.push(...responseInterceptorChain);\n      len = chain.length;\n\n      promise = Promise.resolve(config);\n\n      while (i < len) {\n        promise = promise.then(chain[i++], chain[i++]);\n      }\n\n      return promise;\n    }\n\n    len = requestInterceptorChain.length;\n\n    let newConfig = config;\n\n    while (i < len) {\n      const onFulfilled = requestInterceptorChain[i++];\n      const onRejected = requestInterceptorChain[i++];\n      try {\n        newConfig = onFulfilled(newConfig);\n      } catch (error) {\n        onRejected.call(this, error);\n        break;\n      }\n    }\n\n    try {\n      promise = dispatchRequest.call(this, newConfig);\n    } catch (error) {\n      return Promise.reject(error);\n    }\n\n    i = 0;\n    len = responseInterceptorChain.length;\n\n    while (i < len) {\n      promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n    }\n\n    return promise;\n  }\n\n  getUri(config) {\n    config = mergeConfig(this.defaults, config);\n    const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n    return buildURL(fullPath, config.params, config.paramsSerializer);\n  }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n  /*eslint func-names:0*/\n  Axios.prototype[method] = function(url, config) {\n    return this.request(mergeConfig(config || {}, {\n      method,\n      url,\n      data: (config || {}).data\n    }));\n  };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n  /*eslint func-names:0*/\n\n  function generateHTTPMethod(isForm) {\n    return function httpMethod(url, data, config) {\n      return this.request(mergeConfig(config || {}, {\n        method,\n        headers: isForm ? {\n          'Content-Type': 'multipart/form-data'\n        } : {},\n        url,\n        data\n      }));\n    };\n  }\n\n  Axios.prototype[method] = generateHTTPMethod();\n\n  Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n  constructor(executor) {\n    if (typeof executor !== 'function') {\n      throw new TypeError('executor must be a function.');\n    }\n\n    let resolvePromise;\n\n    this.promise = new Promise(function promiseExecutor(resolve) {\n      resolvePromise = resolve;\n    });\n\n    const token = this;\n\n    // eslint-disable-next-line func-names\n    this.promise.then(cancel => {\n      if (!token._listeners) return;\n\n      let i = token._listeners.length;\n\n      while (i-- > 0) {\n        token._listeners[i](cancel);\n      }\n      token._listeners = null;\n    });\n\n    // eslint-disable-next-line func-names\n    this.promise.then = onfulfilled => {\n      let _resolve;\n      // eslint-disable-next-line func-names\n      const promise = new Promise(resolve => {\n        token.subscribe(resolve);\n        _resolve = resolve;\n      }).then(onfulfilled);\n\n      promise.cancel = function reject() {\n        token.unsubscribe(_resolve);\n      };\n\n      return promise;\n    };\n\n    executor(function cancel(message, config, request) {\n      if (token.reason) {\n        // Cancellation has already been requested\n        return;\n      }\n\n      token.reason = new CanceledError(message, config, request);\n      resolvePromise(token.reason);\n    });\n  }\n\n  /**\n   * Throws a `CanceledError` if cancellation has been requested.\n   */\n  throwIfRequested() {\n    if (this.reason) {\n      throw this.reason;\n    }\n  }\n\n  /**\n   * Subscribe to the cancel signal\n   */\n\n  subscribe(listener) {\n    if (this.reason) {\n      listener(this.reason);\n      return;\n    }\n\n    if (this._listeners) {\n      this._listeners.push(listener);\n    } else {\n      this._listeners = [listener];\n    }\n  }\n\n  /**\n   * Unsubscribe from the cancel signal\n   */\n\n  unsubscribe(listener) {\n    if (!this._listeners) {\n      return;\n    }\n    const index = this._listeners.indexOf(listener);\n    if (index !== -1) {\n      this._listeners.splice(index, 1);\n    }\n  }\n\n  toAbortSignal() {\n    const controller = new AbortController();\n\n    const abort = (err) => {\n      controller.abort(err);\n    };\n\n    this.subscribe(abort);\n\n    controller.signal.unsubscribe = () => this.unsubscribe(abort);\n\n    return controller.signal;\n  }\n\n  /**\n   * Returns an object that contains a new `CancelToken` and a function that, when called,\n   * cancels the `CancelToken`.\n   */\n  static source() {\n    let cancel;\n    const token = new CancelToken(function executor(c) {\n      cancel = c;\n    });\n    return {\n      token,\n      cancel\n    };\n  }\n}\n\nexport default CancelToken;\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n *  ```js\n *  function f(x, y, z) {}\n *  var args = [1, 2, 3];\n *  f.apply(null, args);\n *  ```\n *\n * With `spread` this example can be re-written.\n *\n *  ```js\n *  spread(function(x, y, z) {})([1, 2, 3]);\n *  ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n  return function wrap(arr) {\n    return callback.apply(null, arr);\n  };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n  return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n","const HttpStatusCode = {\n  Continue: 100,\n  SwitchingProtocols: 101,\n  Processing: 102,\n  EarlyHints: 103,\n  Ok: 200,\n  Created: 201,\n  Accepted: 202,\n  NonAuthoritativeInformation: 203,\n  NoContent: 204,\n  ResetContent: 205,\n  PartialContent: 206,\n  MultiStatus: 207,\n  AlreadyReported: 208,\n  ImUsed: 226,\n  MultipleChoices: 300,\n  MovedPermanently: 301,\n  Found: 302,\n  SeeOther: 303,\n  NotModified: 304,\n  UseProxy: 305,\n  Unused: 306,\n  TemporaryRedirect: 307,\n  PermanentRedirect: 308,\n  BadRequest: 400,\n  Unauthorized: 401,\n  PaymentRequired: 402,\n  Forbidden: 403,\n  NotFound: 404,\n  MethodNotAllowed: 405,\n  NotAcceptable: 406,\n  ProxyAuthenticationRequired: 407,\n  RequestTimeout: 408,\n  Conflict: 409,\n  Gone: 410,\n  LengthRequired: 411,\n  PreconditionFailed: 412,\n  PayloadTooLarge: 413,\n  UriTooLong: 414,\n  UnsupportedMediaType: 415,\n  RangeNotSatisfiable: 416,\n  ExpectationFailed: 417,\n  ImATeapot: 418,\n  MisdirectedRequest: 421,\n  UnprocessableEntity: 422,\n  Locked: 423,\n  FailedDependency: 424,\n  TooEarly: 425,\n  UpgradeRequired: 426,\n  PreconditionRequired: 428,\n  TooManyRequests: 429,\n  RequestHeaderFieldsTooLarge: 431,\n  UnavailableForLegalReasons: 451,\n  InternalServerError: 500,\n  NotImplemented: 501,\n  BadGateway: 502,\n  ServiceUnavailable: 503,\n  GatewayTimeout: 504,\n  HttpVersionNotSupported: 505,\n  VariantAlsoNegotiates: 506,\n  InsufficientStorage: 507,\n  LoopDetected: 508,\n  NotExtended: 510,\n  NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n  HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n  const context = new Axios(defaultConfig);\n  const instance = bind(Axios.prototype.request, context);\n\n  // Copy axios.prototype to instance\n  utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n  // Copy context to instance\n  utils.extend(instance, context, null, {allOwnKeys: true});\n\n  // Factory for creating new instances\n  instance.create = function create(instanceConfig) {\n    return createInstance(mergeConfig(defaultConfig, instanceConfig));\n  };\n\n  return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n  return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n","import axios from './lib/axios.js';\n\n// This module is intended to unwrap Axios default export as named.\n// Keep top-level export same with static properties\n// so that it can keep same with es module or cjs\nconst {\n  Axios,\n  AxiosError,\n  CanceledError,\n  isCancel,\n  CancelToken,\n  VERSION,\n  all,\n  Cancel,\n  isAxiosError,\n  spread,\n  toFormData,\n  AxiosHeaders,\n  HttpStatusCode,\n  formToJSON,\n  getAdapter,\n  mergeConfig\n} = axios;\n\nexport {\n  axios as default,\n  Axios,\n  AxiosError,\n  CanceledError,\n  isCancel,\n  CancelToken,\n  VERSION,\n  all,\n  Cancel,\n  isAxiosError,\n  spread,\n  toFormData,\n  AxiosHeaders,\n  HttpStatusCode,\n  formToJSON,\n  getAdapter,\n  mergeConfig\n}\n","/**\n * Base error class for all Wildberries SDK errors.\n *\n * All SDK-specific errors extend this class to enable consumers to catch\n * all SDK errors with a single catch block if desired.\n *\n * @example\n * ```typescript\n * import { WBAPIError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   await sdk.general.ping();\n * } catch (error) {\n *   if (error instanceof WBAPIError) {\n *     console.error('SDK error:', error.getUserMessage());\n *     console.error('Status code:', error.statusCode);\n *   }\n * }\n * ```\n */\nexport class WBAPIError extends Error {\n  /**\n   * HTTP status code if applicable\n   */\n  public readonly statusCode?: number;\n\n  /**\n   * API response body if available\n   */\n  public readonly response?: unknown;\n\n  /**\n   * Correlation ID for debugging and tracing requests\n   */\n  public readonly requestId?: string;\n\n  /**\n   * Creates a new WBAPIError\n   *\n   * @param message - Error message describing what went wrong\n   * @param statusCode - HTTP status code if applicable\n   * @param response - API response body if available\n   * @param requestId - Correlation ID for debugging\n   */\n  constructor(\n    message: string,\n    statusCode?: number,\n    response?: unknown,\n    requestId?: string\n  ) {\n    super(message);\n\n    // Set error name to class name for proper identification\n    this.name = this.constructor.name;\n\n    // Preserve stack trace for debugging (V8 engines like Node.js)\n    // Type assertion needed because captureStackTrace is V8-specific\n    const captureStackTrace = (Error as {\n      captureStackTrace?: (target: object, constructor: new (...args: unknown[]) => unknown) => void\n    }).captureStackTrace;\n    if (captureStackTrace) {\n      captureStackTrace(this, this.constructor as new (...args: unknown[]) => unknown);\n    }\n\n    this.statusCode = statusCode;\n    this.response = response;\n    this.requestId = requestId;\n  }\n\n  /**\n   * Returns a human-readable error message with recovery guidance.\n   *\n   * Override this method in subclasses to provide specific recovery steps.\n   *\n   * @returns User-friendly error message with actionable guidance\n   *\n   * @example\n   * ```typescript\n   * try {\n   *   await sdk.products.createProduct(data);\n   * } catch (error) {\n   *   if (error instanceof WBAPIError) {\n   *     // Show user-friendly message\n   *     alert(error.getUserMessage());\n   *\n   *     // Log technical details for debugging\n   *     console.error('Technical details:', {\n   *       statusCode: error.statusCode,\n   *       requestId: error.requestId\n   *     });\n   *   }\n   * }\n   * ```\n   */\n  getUserMessage(): string {\n    let message = this.message;\n\n    if (this.statusCode !== undefined) {\n      message += ` (Status: ${this.statusCode.toString()})`;\n    }\n\n    if (this.requestId) {\n      message += ` [Request ID: ${this.requestId}]`;\n    }\n\n    return message;\n  }\n\n  /**\n   * Custom JSON serialization to preserve all error properties.\n   *\n   * By default, Error objects don't serialize the `message` property\n   * when using JSON.stringify(). This method ensures all important\n   * properties are included in the JSON output.\n   *\n   * @returns Object representation of the error for JSON serialization\n   *\n   * @example\n   * ```typescript\n   * const error = new WBAPIError('Test error', 400, { detail: 'info' }, 'req-123');\n   * const json = JSON.stringify(error);\n   * // { \"name\": \"WBAPIError\", \"message\": \"Test error\", \"statusCode\": 400, ... }\n   * ```\n   */\n  toJSON(): {\n    name: string;\n    message: string;\n    statusCode?: number;\n    response?: unknown;\n    requestId?: string;\n  } {\n    return {\n      name: this.name,\n      message: this.message,\n      statusCode: this.statusCode,\n      response: this.response,\n      requestId: this.requestId,\n    };\n  }\n}\n","import { WBAPIError } from './base-error';\n\n/**\n * Authentication error thrown when API key is invalid or lacks permissions.\n *\n * This error is thrown for:\n * - 401 Unauthorized responses (invalid API key)\n * - 403 Forbidden responses (insufficient permissions)\n * - Client-side API key validation failures\n *\n * @example\n * ```typescript\n * import { AuthenticationError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   await sdk.general.ping();\n * } catch (error) {\n *   if (error instanceof AuthenticationError) {\n *     console.error('Invalid API key:', error.getUserMessage());\n *     // Prompt user to update API key in settings\n *   }\n * }\n * ```\n */\nexport class AuthenticationError extends WBAPIError {\n  /**\n   * Creates an authentication error\n   *\n   * @param message - Error message (defaults to standard authentication failure message)\n   * @param statusCode - HTTP status code (401 or 403)\n   * @param response - API response body if available\n   * @param requestId - Correlation ID for debugging\n   */\n  constructor(\n    message = 'Authentication failed. Please verify your API key is valid and has the required permissions.',\n    statusCode: 401 | 403 = 401,\n    response?: unknown,\n    requestId?: string\n  ) {\n    super(message, statusCode, response, requestId);\n    this.name = 'AuthenticationError';\n  }\n\n  /**\n   * Returns user-friendly error message with API key troubleshooting guidance\n   *\n   * @returns Error message with actionable recovery steps\n   */\n  getUserMessage(): string {\n    const baseMessage = super.getUserMessage();\n\n    const guidance = [\n      '\\n\\nTo resolve this issue:',\n      '1. Verify your API key is valid and correctly formatted',\n      '2. Check that your API key has the required permissions for this operation',\n      '3. Ensure the Authorization header is properly set',\n      '4. Confirm your API key has not been revoked or expired',\n    ].join('\\n');\n\n    return baseMessage + guidance;\n  }\n}\n","import { WBAPIError } from './base-error';\n\n/**\n * Rate limit error thrown when API rate limits are exceeded.\n *\n * This error is thrown for 429 Too Many Requests responses.\n * The SDK's RetryHandler automatically retries rate-limited requests\n * after the specified delay, so consumers typically don't need to\n * handle this error manually.\n *\n * @example\n * ```typescript\n * import { RateLimitError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   await sdk.products.createProduct(data);\n * } catch (error) {\n *   if (error instanceof RateLimitError) {\n *     console.log(`Rate limited. SDK will retry after ${error.retryAfter}ms`);\n *     // The SDK automatically retries, so you usually don't need to do anything\n *   }\n * }\n * ```\n */\nexport class RateLimitError extends WBAPIError {\n  /**\n   * Milliseconds to wait before retrying the request\n   */\n  public readonly retryAfter: number;\n\n  /**\n   * Creates a rate limit error\n   *\n   * @param message - Error message (defaults to standard rate limit message)\n   * @param retryAfter - Milliseconds until retry is allowed\n   * @param response - API response body if available\n   * @param requestId - Correlation ID for debugging\n   */\n  constructor(\n    message = 'Rate limit exceeded. The SDK will automatically retry this request.',\n    retryAfter: number,\n    response?: unknown,\n    requestId?: string\n  ) {\n    super(message, 429, response, requestId);\n    this.name = 'RateLimitError';\n    this.retryAfter = retryAfter;\n  }\n\n  /**\n   * Returns user-friendly error message with retry timing information\n   *\n   * @returns Error message with retry delay and automatic handling notice\n   */\n  getUserMessage(): string {\n    const baseMessage = super.getUserMessage();\n\n    const retrySeconds = (this.retryAfter / 1000).toFixed(1);\n    const guidance = [\n      `\\n\\nRetry after: ${retrySeconds} seconds`,\n      '\\nThe SDK will automatically retry this request.',\n      '\\nIf rate limiting occurs frequently, consider:',\n      '1. Implementing request batching to reduce API call frequency',\n      '2. Caching responses when appropriate',\n      '3. Reviewing your application\\'s API usage patterns',\n    ].join('\\n');\n\n    return baseMessage + guidance;\n  }\n\n  /**\n   * Custom JSON serialization to preserve retryAfter property\n   *\n   * @returns Object representation including retryAfter timing\n   */\n  toJSON(): {\n    name: string;\n    message: string;\n    statusCode: number;\n    retryAfter: number;\n    response?: unknown;\n    requestId?: string;\n  } {\n    return {\n      ...super.toJSON(),\n      statusCode: this.statusCode ?? 429,\n      retryAfter: this.retryAfter,\n    };\n  }\n}\n","import { WBAPIError } from './base-error';\n\n/**\n * Validation error thrown when request data fails validation.\n *\n * This error is thrown for:\n * - 400 Bad Request responses (malformed requests)\n * - 422 Unprocessable Entity responses (validation failures)\n *\n * Includes field-level error details when available to help\n * identify which specific fields failed validation.\n *\n * @example\n * ```typescript\n * import { ValidationError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   await sdk.products.createProduct({\n *     // Missing required fields\n *   });\n * } catch (error) {\n *   if (error instanceof ValidationError) {\n *     console.error('Validation failed:', error.getUserMessage());\n *\n *     // Access field-level errors\n *     if (error.fieldErrors) {\n *       Object.entries(error.fieldErrors).forEach(([field, message]) => {\n *         console.error(`  - ${field}: ${message}`);\n *       });\n *     }\n *   }\n * }\n * ```\n */\nexport class ValidationError extends WBAPIError {\n  /**\n   * Map of field names to their validation error messages\n   */\n  public readonly fieldErrors?: Record<string, string>;\n\n  /**\n   * Creates a validation error\n   *\n   * @param message - Error message (defaults to standard validation failure message)\n   * @param fieldErrors - Optional map of field names to error messages\n   * @param statusCode - HTTP status code (400 or 422)\n   * @param response - API response body if available\n   * @param requestId - Correlation ID for debugging\n   */\n  constructor(\n    message = 'Validation failed. Please check the request data and try again.',\n    fieldErrors?: Record<string, string>,\n    statusCode: 400 | 422 = 400,\n    response?: unknown,\n    requestId?: string\n  ) {\n    super(message, statusCode, response, requestId);\n    this.name = 'ValidationError';\n    this.fieldErrors = fieldErrors;\n  }\n\n  /**\n   * Returns user-friendly error message with field-level validation details\n   *\n   * @returns Error message with specific field errors and resolution guidance\n   */\n  getUserMessage(): string {\n    const baseMessage = super.getUserMessage();\n\n    if (this.fieldErrors && Object.keys(this.fieldErrors).length > 0) {\n      const fieldErrorsList = Object.entries(this.fieldErrors)\n        .map(([field, error]) => `  - ${field}: ${error}`)\n        .join('\\n');\n\n      const guidance = [\n        '\\n\\nField validation errors:',\n        fieldErrorsList,\n        '\\nPlease correct the above fields and try again.',\n      ].join('\\n');\n\n      return baseMessage + guidance;\n    }\n\n    const guidance = [\n      '\\n\\nTo resolve this issue:',\n      '1. Ensure all required fields are provided',\n      '2. Verify that field values meet the API specifications',\n      '3. Check that data types and formats are correct',\n      '4. Review the API documentation for field requirements',\n    ].join('\\n');\n\n    return baseMessage + guidance;\n  }\n\n  /**\n   * Custom JSON serialization to preserve fieldErrors property\n   *\n   * @returns Object representation including field-level error details\n   */\n  toJSON(): {\n    name: string;\n    message: string;\n    statusCode: number;\n    fieldErrors?: Record<string, string>;\n    response?: unknown;\n    requestId?: string;\n  } {\n    return {\n      ...super.toJSON(),\n      statusCode: this.statusCode ?? 400,\n      fieldErrors: this.fieldErrors,\n    };\n  }\n}\n","import { WBAPIError } from './base-error';\n\n/**\n * Network error thrown for connection failures, timeouts, and server errors.\n *\n * This error is thrown for:\n * - Network connection failures (no internet, DNS failures)\n * - Request timeouts (exceeding configured timeout)\n * - 500-level server errors (500, 502, 503, 504)\n *\n * The SDK's RetryHandler automatically retries network errors with\n * exponential backoff (max 3 attempts), so transient failures are\n * handled automatically.\n *\n * @example\n * ```typescript\n * import { NetworkError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   await sdk.products.getProductList();\n * } catch (error) {\n *   if (error instanceof NetworkError) {\n *     if (error.isTimeout) {\n *       console.error('Request timed out:', error.getUserMessage());\n *     } else {\n *       console.error('Network error:', error.getUserMessage());\n *     }\n *     // The SDK already attempted 3 retries automatically\n *   }\n * }\n * ```\n */\nexport class NetworkError extends WBAPIError {\n  /**\n   * Original error from the HTTP client\n   */\n  public readonly cause?: Error;\n\n  /**\n   * True if the error was caused by a timeout\n   */\n  public readonly isTimeout: boolean;\n\n  /**\n   * Creates a network error\n   *\n   * @param message - Error message describing the network failure\n   * @param isTimeout - Whether this error was caused by a timeout\n   * @param statusCode - HTTP status code (0 for network failures, 5xx for server errors)\n   * @param cause - Original error from the HTTP client\n   * @param response - API response body if available\n   * @param requestId - Correlation ID for debugging\n   */\n  constructor(\n    message: string,\n    isTimeout = false,\n    statusCode?: number,\n    cause?: Error,\n    response?: unknown,\n    requestId?: string\n  ) {\n    super(message, statusCode, response, requestId);\n    this.name = 'NetworkError';\n    this.isTimeout = isTimeout;\n    this.cause = cause;\n  }\n\n  /**\n   * Returns user-friendly error message with retry information and troubleshooting guidance\n   *\n   * @returns Error message with network-specific recovery steps\n   */\n  getUserMessage(): string {\n    const baseMessage = super.getUserMessage();\n\n    let guidance: string;\n\n    if (this.isTimeout) {\n      guidance = [\n        '\\n\\nThis request timed out after 30 seconds.',\n        'The SDK automatically retried this request 3 times.',\n        '\\nTo resolve timeout issues:',\n        '1. Check if the Wildberries API is experiencing high latency',\n        '2. Consider increasing the timeout configuration',\n        '3. Verify your network connection is stable',\n        '4. Try again later if the API is overloaded',\n      ].join('\\n');\n    } else if (this.statusCode && this.statusCode >= 500) {\n      guidance = [\n        '\\n\\nThe Wildberries API server encountered an error.',\n        'The SDK automatically retried this request 3 times.',\n        '\\nTo resolve server errors:',\n        '1. Wait a few moments and try again',\n        '2. Check the Wildberries API status page for known issues',\n        '3. If the problem persists, contact Wildberries API support',\n      ].join('\\n');\n    } else {\n      guidance = [\n        '\\n\\nNetwork connection failed.',\n        'The SDK automatically retried this request 3 times.',\n        '\\nTo resolve connection issues:',\n        '1. Check your internet connection',\n        '2. Verify network firewalls allow HTTPS connections',\n        '3. Ensure DNS resolution is working properly',\n        '4. Try again when network connectivity is restored',\n      ].join('\\n');\n    }\n\n    return baseMessage + guidance;\n  }\n\n  /**\n   * Custom JSON serialization to preserve isTimeout property\n   *\n   * Note: The `cause` property is not serialized as Error objects\n   * don't serialize well. Check the cause property directly if needed.\n   *\n   * @returns Object representation including timeout flag and status\n   */\n  toJSON(): {\n    name: string;\n    message: string;\n    isTimeout: boolean;\n    statusCode?: number;\n    response?: unknown;\n    requestId?: string;\n  } {\n    return {\n      ...super.toJSON(),\n      isTimeout: this.isTimeout,\n    };\n  }\n}\n","import { WBAPIError } from './base-error';\nimport { ValidationError } from './validation-error';\n\n/**\n * Error thrown when a campaign is not found by its ID.\n *\n * This error typically occurs when:\n * - Campaign was deleted\n * - Campaign ID is incorrect\n * - Campaign belongs to another seller account\n *\n * @example\n * ```typescript\n * import { CampaignNotFoundError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   await sdk.promotion.startCampaign(123456);\n * } catch (error) {\n *   if (error instanceof CampaignNotFoundError) {\n *     console.error('Campaign does not exist:', error.message);\n *     // Verify campaign ID and try again\n *   }\n * }\n * ```\n */\nexport class CampaignNotFoundError extends WBAPIError {\n  /**\n   * Campaign ID that was not found\n   */\n  public readonly campaignId: number;\n\n  /**\n   * Creates a CampaignNotFoundError\n   *\n   * @param campaignId - ID of the campaign that wasn't found\n   * @param response - API response body if available\n   * @param requestId - Correlation ID for debugging\n   */\n  constructor(campaignId: number, response?: unknown, requestId?: string) {\n    super(`Campaign not found: ${campaignId}`, 404, response, requestId);\n    this.name = 'CampaignNotFoundError';\n    this.campaignId = campaignId;\n  }\n\n  /**\n   * Returns user-friendly error message with recovery guidance\n   *\n   * @returns Error message with actionable steps\n   */\n  getUserMessage(): string {\n    const baseMessage = super.getUserMessage();\n\n    const guidance = [\n      '\\n\\nTo resolve this issue:',\n      `1. Verify that campaign ID ${this.campaignId} is correct`,\n      '2. Check if the campaign was deleted',\n      '3. Ensure you have access to this campaign in your account',\n      '4. Use getCampaignCount() to list all available campaigns',\n    ].join('\\n');\n\n    return baseMessage + guidance;\n  }\n\n  /**\n   * Custom JSON serialization\n   */\n  toJSON(): {\n    name: string;\n    message: string;\n    statusCode: number;\n    campaignId: number;\n    response?: unknown;\n    requestId?: string;\n  } {\n    return {\n      ...super.toJSON(),\n      statusCode: 404,\n      campaignId: this.campaignId,\n    };\n  }\n}\n\n/**\n * Error thrown when bid amount is invalid or below minimum.\n *\n * This error occurs when:\n * - Bid is below the minimum required amount\n * - Bid format is incorrect\n * - Bid exceeds maximum allowed amount\n *\n * @example\n * ```typescript\n * import { InvalidBidError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   await sdk.promotion.updateAuctionBids({\n *     bids: [{ advert_id: 123, nm_bids: [{ nm_id: 456, bid: 50, placement: 'search' }] }]\n *   });\n * } catch (error) {\n *   if (error instanceof InvalidBidError) {\n *     console.error(`Minimum bid is ${error.minBid}`);\n *     // Increase bid amount and retry\n *   }\n * }\n * ```\n */\nexport class InvalidBidError extends ValidationError {\n  /**\n   * Minimum bid amount required (if available)\n   */\n  public readonly minBid?: number;\n\n  /**\n   * Maximum bid amount allowed (if applicable)\n   */\n  public readonly maxBid?: number;\n\n  /**\n   * Current bid amount that was rejected\n   */\n  public readonly currentBid?: number;\n\n  /**\n   * Creates an InvalidBidError\n   *\n   * @param message - Error message describing the bid validation failure\n   * @param context - Additional context (minBid, maxBid, currentBid)\n   * @param response - API response body if available\n   * @param requestId - Correlation ID for debugging\n   */\n  constructor(\n    message: string,\n    context?: {\n      field?: string;\n      minBid?: number;\n      maxBid?: number;\n      currentBid?: number;\n    },\n    response?: unknown,\n    requestId?: string\n  ) {\n    const fieldErrors = context?.field\n      ? { [context.field]: message }\n      : { bid: message };\n\n    super(message, fieldErrors, 400, response, requestId);\n    this.name = 'InvalidBidError';\n    this.minBid = context?.minBid;\n    this.maxBid = context?.maxBid;\n    this.currentBid = context?.currentBid;\n  }\n\n  /**\n   * Returns user-friendly error message with bid requirements\n   *\n   * @returns Error message with specific bid constraints\n   */\n  getUserMessage(): string {\n    const baseMessage = super.getUserMessage();\n\n    const bidInfo: string[] = [];\n\n    if (this.minBid !== undefined) {\n      bidInfo.push(`Minimum bid: ${this.minBid} руб.`);\n    }\n\n    if (this.maxBid !== undefined) {\n      bidInfo.push(`Maximum bid: ${this.maxBid} руб.`);\n    }\n\n    if (this.currentBid !== undefined) {\n      bidInfo.push(`Your bid: ${this.currentBid} руб.`);\n    }\n\n    if (bidInfo.length > 0) {\n      const guidance = [\n        '\\n\\nBid requirements:',\n        ...bidInfo.map(info => `  - ${info}`),\n        '\\nPlease adjust your bid to meet these requirements.',\n      ].join('\\n');\n\n      return baseMessage + guidance;\n    }\n\n    return baseMessage;\n  }\n\n  /**\n   * Custom JSON serialization\n   */\n  toJSON(): {\n    name: string;\n    message: string;\n    statusCode: number;\n    fieldErrors?: Record<string, string>;\n    minBid?: number;\n    maxBid?: number;\n    currentBid?: number;\n    response?: unknown;\n    requestId?: string;\n  } {\n    return {\n      ...super.toJSON(),\n      minBid: this.minBid,\n      maxBid: this.maxBid,\n      currentBid: this.currentBid,\n    };\n  }\n}\n\n/**\n * Error thrown when campaign budget is exceeded or insufficient.\n *\n * This error occurs when:\n * - Requested operation would exceed campaign budget\n * - Insufficient funds in account for deposit\n * - Budget limit reached for billing period\n *\n * @example\n * ```typescript\n * import { BudgetExceededError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   await sdk.promotion.createBudgetDeposit({ sum: 50000 }, { id: 123 });\n * } catch (error) {\n *   if (error instanceof BudgetExceededError) {\n *     console.error(`Budget exceeded: ${error.message}`);\n *     console.error(`Available: ${error.availableBudget}, Required: ${error.requiredBudget}`);\n *   }\n * }\n * ```\n */\nexport class BudgetExceededError extends WBAPIError {\n  /**\n   * Available budget amount\n   */\n  public readonly availableBudget?: number;\n\n  /**\n   * Required budget amount for the operation\n   */\n  public readonly requiredBudget?: number;\n\n  /**\n   * Creates a BudgetExceededError\n   *\n   * @param message - Error message describing the budget issue\n   * @param context - Budget information (available, required)\n   * @param response - API response body if available\n   * @param requestId - Correlation ID for debugging\n   */\n  constructor(\n    message: string,\n    context?: {\n      availableBudget?: number;\n      requiredBudget?: number;\n    },\n    response?: unknown,\n    requestId?: string\n  ) {\n    super(message, 400, response, requestId);\n    this.name = 'BudgetExceededError';\n    this.availableBudget = context?.availableBudget;\n    this.requiredBudget = context?.requiredBudget;\n  }\n\n  /**\n   * Returns user-friendly error message with budget details\n   *\n   * @returns Error message with budget information\n   */\n  getUserMessage(): string {\n    const baseMessage = super.getUserMessage();\n\n    const budgetInfo: string[] = [];\n\n    if (this.availableBudget !== undefined) {\n      budgetInfo.push(`Available budget: ${this.availableBudget} руб.`);\n    }\n\n    if (this.requiredBudget !== undefined) {\n      budgetInfo.push(`Required budget: ${this.requiredBudget} руб.`);\n    }\n\n    if (budgetInfo.length > 0) {\n      const guidance = [\n        '\\n\\nBudget information:',\n        ...budgetInfo.map(info => `  - ${info}`),\n        '\\nTo resolve this issue:',\n        '1. Check your account balance using getAdvBalance()',\n        '2. Add funds to your advertising account',\n        '3. Reduce the requested budget or bid amounts',\n        '4. Contact Wildberries support for account limit increases',\n      ].join('\\n');\n\n      return baseMessage + guidance;\n    }\n\n    const guidance = [\n      '\\n\\nTo resolve this issue:',\n      '1. Check your account balance using getAdvBalance()',\n      '2. Add funds to your advertising account',\n      '3. Verify campaign budget limits',\n    ].join('\\n');\n\n    return baseMessage + guidance;\n  }\n\n  /**\n   * Custom JSON serialization\n   */\n  toJSON(): {\n    name: string;\n    message: string;\n    statusCode: number;\n    availableBudget?: number;\n    requiredBudget?: number;\n    response?: unknown;\n    requestId?: string;\n  } {\n    return {\n      ...super.toJSON(),\n      statusCode: 400,\n      availableBudget: this.availableBudget,\n      requiredBudget: this.requiredBudget,\n    };\n  }\n}\n\n/**\n * Error thrown when attempting invalid campaign state transitions.\n *\n * Campaign lifecycle states:\n * - `-1`: Deleted (being deleted, will complete in 10 minutes)\n * - `4`: Ready to launch\n * - `7`: Completed\n * - `8`: Cancelled\n * - `9`: Active\n * - `11`: Paused\n *\n * Valid transitions:\n * - Ready (4) → Active (9) via startCampaign()\n * - Active (9) → Paused (11) via pauseCampaign()\n * - Paused (11) → Active (9) via startCampaign()\n * - Active/Paused → Completed (7) via stopCampaign()\n *\n * @example\n * ```typescript\n * import { InvalidCampaignStateError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   // Trying to start an already active campaign\n *   await sdk.promotion.startCampaign(123);\n * } catch (error) {\n *   if (error instanceof InvalidCampaignStateError) {\n *     console.error(`Cannot ${error.attemptedAction} campaign in ${error.currentState} state`);\n *     console.error('Valid states:', error.validStates);\n *   }\n * }\n * ```\n */\nexport class InvalidCampaignStateError extends WBAPIError {\n  /**\n   * Current campaign state\n   */\n  public readonly currentState: string;\n\n  /**\n   * Action that was attempted\n   */\n  public readonly attemptedAction: string;\n\n  /**\n   * List of valid states for the attempted action\n   */\n  public readonly validStates?: string[];\n\n  /**\n   * Creates an InvalidCampaignStateError\n   *\n   * @param currentState - Current state of the campaign\n   * @param attemptedAction - Action that was attempted (start, pause, stop, delete)\n   * @param validStates - Optional list of valid states for this action\n   * @param response - API response body if available\n   * @param requestId - Correlation ID for debugging\n   */\n  constructor(\n    currentState: string,\n    attemptedAction: string,\n    validStates?: string[],\n    response?: unknown,\n    requestId?: string\n  ) {\n    super(\n      `Cannot ${attemptedAction} campaign in ${currentState} state`,\n      400,\n      response,\n      requestId\n    );\n    this.name = 'InvalidCampaignStateError';\n    this.currentState = currentState;\n    this.attemptedAction = attemptedAction;\n    this.validStates = validStates;\n  }\n\n  /**\n   * Returns user-friendly error message with state transition guidance\n   *\n   * @returns Error message with valid state transitions\n   */\n  getUserMessage(): string {\n    const baseMessage = super.getUserMessage();\n\n    const stateGuide: string[] = ['\\n\\nCampaign state information:', `  - Current state: ${this.currentState}`];\n\n    if (this.validStates && this.validStates.length > 0) {\n      stateGuide.push(`  - Valid states for ${this.attemptedAction}: ${this.validStates.join(', ')}`);\n    }\n\n    const transitionGuide = [\n      '\\nValid state transitions:',\n      '  - Ready (4) → Active (9): Use startCampaign()',\n      '  - Active (9) → Paused (11): Use pauseCampaign()',\n      '  - Paused (11) → Active (9): Use startCampaign()',\n      '  - Active/Paused → Completed (7): Use stopCampaign()',\n      '\\nTo resolve this issue:',\n      '1. Check current campaign state using getCampaigns() or getAuctionAdverts()',\n      '2. Ensure campaign is in a valid state for this operation',\n      '3. Review campaign lifecycle documentation',\n    ].join('\\n');\n\n    return baseMessage + stateGuide.join('\\n') + transitionGuide;\n  }\n\n  /**\n   * Custom JSON serialization\n   */\n  toJSON(): {\n    name: string;\n    message: string;\n    statusCode: number;\n    currentState: string;\n    attemptedAction: string;\n    validStates?: string[];\n    response?: unknown;\n    requestId?: string;\n  } {\n    return {\n      ...super.toJSON(),\n      statusCode: 400,\n      currentState: this.currentState,\n      attemptedAction: this.attemptedAction,\n      validStates: this.validStates,\n    };\n  }\n}\n","/**\n * In-Store Pickup specific error classes\n *\n * These errors handle failures specific to click & collect order operations,\n * including order state transitions, customer verification, and metadata management.\n *\n * @module errors/in-store-pickup-errors\n */\n\nimport { WBAPIError } from './base-error';\n\n/**\n * Error thrown when a pickup order is not found\n *\n * **HTTP Status**: 404\n * **Retry**: No (permanent failure)\n *\n * @example\n * ```typescript\n * try {\n *   await sdk.inStorePickup.confirmOrder(999999);\n * } catch (error) {\n *   if (error instanceof PickupOrderNotFoundError) {\n *     console.error(`Order ${error.orderId} not found`);\n *     // Handle order not found scenario\n *   }\n * }\n * ```\n */\nexport class PickupOrderNotFoundError extends WBAPIError {\n  /**\n   * Creates a new PickupOrderNotFoundError\n   *\n   * @param orderId - ID of the order that was not found\n   * @param requestId - Optional request ID from API response\n   */\n  constructor(\n    public readonly orderId: number,\n    requestId?: string\n  ) {\n    super(\n      `Pickup order not found: ${orderId}`,\n      404,\n      {\n        orderId,\n        errorType: 'OrderNotFound',\n      },\n      requestId\n    );\n    this.name = 'PickupOrderNotFoundError';\n  }\n\n  /**\n   * Returns user-friendly error message with recovery guidance\n   */\n  override getUserMessage(): string {\n    return `Pickup order ${this.orderId} was not found. Please verify the order ID and try again. The order may have been cancelled or does not exist.`;\n  }\n}\n\n/**\n * Error thrown when an order state transition is invalid\n *\n * **HTTP Status**: 409 Conflict\n * **Retry**: No (permanent failure - requires state correction)\n * **Rate Limit**: 409 responses count as 5 requests!\n *\n * This error occurs when attempting to transition an order to a state that is\n * not valid given its current state (e.g., trying to prepare an order that\n * hasn't been confirmed yet).\n *\n * **Valid State Transitions**:\n * - `new` → `confirm` (confirmOrder)\n * - `confirm` → `prepare` (prepareOrder)\n * - `prepare` → `receive` (receiveOrder) - terminal state\n * - `prepare` → `reject` (rejectOrder) - terminal state\n * - Any → `cancel` (cancelOrder) - terminal state\n *\n * @example\n * ```typescript\n * try {\n *   // Trying to prepare order without confirming first\n *   await sdk.inStorePickup.prepareOrder(12345);\n * } catch (error) {\n *   if (error instanceof InvalidOrderStateError) {\n *     console.error(`Cannot ${error.attemptedAction} order ${error.orderId}`);\n *     console.error(`Current state: ${error.currentState}`);\n *     console.error('Recovery:', error.getUserMessage());\n *\n *     // Get current status and retry with correct action\n *     const statuses = await sdk.inStorePickup.getOrderStatuses([error.orderId]);\n *     const currentState = statuses.orders[0]?.supplierStatus;\n *     // Handle based on current state\n *   }\n * }\n * ```\n */\nexport class InvalidOrderStateError extends WBAPIError {\n  /**\n   * Creates a new InvalidOrderStateError\n   *\n   * @param orderId - ID of the order with invalid state\n   * @param currentState - Current state of the order (if known)\n   * @param attemptedAction - Action that was attempted (e.g., \"prepare\", \"receive\")\n   * @param requestId - Optional request ID from API response\n   */\n  constructor(\n    public readonly orderId: number,\n    public readonly currentState: string | undefined,\n    public readonly attemptedAction: string,\n    requestId?: string\n  ) {\n    const stateInfo = currentState ? ` in ${currentState} state` : '';\n    super(\n      `Cannot ${attemptedAction} order ${orderId}${stateInfo}. Invalid state transition.`,\n      409,\n      {\n        orderId,\n        currentState,\n        attemptedAction,\n        errorType: 'StatusMismatch',\n      },\n      requestId\n    );\n    this.name = 'InvalidOrderStateError';\n  }\n\n  /**\n   * Returns user-friendly error message with recovery guidance\n   */\n  override getUserMessage(): string {\n    const stateMsg = this.currentState\n      ? `The order is currently in \"${this.currentState}\" state and`\n      : 'The order';\n\n    return (\n      `${stateMsg} cannot be transitioned to \"${this.attemptedAction}\". ` +\n      `Please check the current order status using getOrderStatuses() and ` +\n      `ensure you follow the correct state transition sequence: ` +\n      `new → confirm → prepare → receive/reject. ` +\n      `Note: This 409 response counts as 5 requests toward your rate limit.`\n    );\n  }\n}\n\n/**\n * Error thrown when customer identity verification fails\n *\n * **HTTP Status**: 409 Conflict\n * **Retry**: No (permanent failure - requires correct passcode)\n * **Rate Limit**: 409 responses count as 5 requests!\n *\n * This error occurs when the passcode provided for identity verification does\n * not match the customer's order code. The customer needs to provide the correct\n * passcode from their Wildberries app.\n *\n * @example\n * ```typescript\n * try {\n *   const result = await sdk.inStorePickup.verifyCustomerIdentity({\n *     orderCode: '21117866-0006',\n *     passcode: '1234'\n *   });\n * } catch (error) {\n *   if (error instanceof CustomerVerificationError) {\n *     console.error('Verification failed:', error.getUserMessage());\n *     // Ask customer to check their app for correct passcode\n *     // Note: Be careful not to exceed rate limits (30 req/min)\n *   }\n * }\n * ```\n */\nexport class CustomerVerificationError extends WBAPIError {\n  /**\n   * Creates a new CustomerVerificationError\n   *\n   * @param orderCode - Customer's order code that failed verification\n   * @param message - Detailed error message from API\n   * @param requestId - Optional request ID from API response\n   */\n  constructor(\n    public readonly orderCode: string,\n    message: string,\n    requestId?: string\n  ) {\n    super(\n      `Customer verification failed for order ${orderCode}: ${message}`,\n      409,\n      {\n        orderCode,\n        errorType: 'InvalidPasscode',\n      },\n      requestId\n    );\n    this.name = 'CustomerVerificationError';\n  }\n\n  /**\n   * Returns user-friendly error message with recovery guidance\n   */\n  override getUserMessage(): string {\n    return (\n      `Customer identity verification failed for order ${this.orderCode}. ` +\n      `The passcode provided does not match. Please ask the customer to check ` +\n      `their Wildberries app for the correct passcode. ` +\n      `Note: This 409 response counts as 5 requests toward your rate limit. ` +\n      `Be careful not to exceed the 30 requests/minute limit for this endpoint.`\n    );\n  }\n}\n\n/**\n * Error thrown when product metadata validation fails\n *\n * **HTTP Status**: 409 Conflict (metadata update failures)\n * **Retry**: No (permanent failure - requires correct data or order state)\n * **Rate Limit**: 409 responses count as 5 requests!\n *\n * This error occurs when attempting to set metadata (SGTIN, UIN, IMEI, GTIN) codes\n * but the operation fails due to:\n * - Invalid code format\n * - Order not in `confirm` status\n * - Metadata type not in order's `requiredMeta` list\n * - Delivery not by WB (for UIN, IMEI, GTIN)\n *\n * @example\n * ```typescript\n * try {\n *   await sdk.inStorePickup.setSGTINCode(12345, ['invalid-code']);\n * } catch (error) {\n *   if (error instanceof MetadataValidationError) {\n *     console.error(`Cannot set ${error.codeType}:`, error.getUserMessage());\n *\n *     // Check order status\n *     const statuses = await sdk.inStorePickup.getOrderStatuses([12345]);\n *     console.log('Current status:', statuses.orders[0].supplierStatus);\n *\n *     // Check required metadata\n *     const newOrders = await sdk.inStorePickup.getNewOrders();\n *     const order = newOrders.orders.find(o => o.id === 12345);\n *     console.log('Required metadata:', order?.requiredMeta);\n *   }\n * }\n * ```\n */\nexport class MetadataValidationError extends WBAPIError {\n  /**\n   * Creates a new MetadataValidationError\n   *\n   * @param codeType - Type of metadata code (SGTIN, UIN, IMEI, GTIN)\n   * @param orderId - ID of the order for which metadata update failed\n   * @param message - Detailed error message from API\n   * @param requestId - Optional request ID from API response\n   */\n  constructor(\n    public readonly codeType: 'SGTIN' | 'UIN' | 'IMEI' | 'GTIN',\n    public readonly orderId: number,\n    message: string,\n    requestId?: string\n  ) {\n    super(\n      message,\n      409,\n      {\n        codeType,\n        orderId,\n        errorType: 'FailedToUpdateMeta',\n      },\n      requestId\n    );\n    this.name = 'MetadataValidationError';\n  }\n\n  /**\n   * Returns user-friendly error message with recovery guidance\n   */\n  override getUserMessage(): string {\n    return (\n      `Failed to set ${this.codeType} metadata for order ${this.orderId}. ` +\n      `Please ensure: 1) Order is in \"confirm\" status, ` +\n      `2) \"${this.codeType.toLowerCase()}\" is in the order's requiredMeta list, ` +\n      `3) Code format is valid, ` +\n      `4) For UIN/IMEI/GTIN: delivery is by WB. ` +\n      `Use getNewOrders() to check requiredMeta and getOrderStatuses() to check status. ` +\n      `Note: This 409 response counts as 5 requests toward your rate limit.`\n    );\n  }\n}\n","/**\n * Rate Limiting with Token Bucket Algorithm\n *\n * This module implements automatic rate limiting for Wildberries API endpoints using\n * the token bucket algorithm. Each endpoint can have independent rate limits configured\n * to prevent exceeding API quotas and avoid request throttling or bans.\n *\n * @module client/rate-limiter\n */\n\n/**\n * Configuration for rate limiting a specific endpoint.\n *\n * Rate limits follow the token bucket algorithm where:\n * - Each request consumes 1 token from the bucket\n * - Tokens refill at a steady rate based on `requestsPerMinute`\n * - The bucket can hold up to `burstLimit` tokens maximum\n * - Requests wait in queue when no tokens are available\n *\n * @example\n * ```typescript\n * // Strict limit: 1 request every 10 seconds\n * const strictLimit: RateLimitConfig = {\n *   requestsPerMinute: 6,      // 60s / 10s = 6 requests/minute\n *   intervalSeconds: 10,       // Minimum 10s between requests\n *   burstLimit: 1              // Cannot burst multiple requests\n * };\n *\n * // Burst-friendly: 20 requests/minute, can burst 10 initially\n * const burstLimit: RateLimitConfig = {\n *   requestsPerMinute: 20,\n *   burstLimit: 10             // Can send 10 rapid requests, then throttled\n * };\n *\n * // Simple rate limit: 5 requests/minute\n * const simpleLimit: RateLimitConfig = {\n *   requestsPerMinute: 5       // burstLimit defaults to 5\n * };\n * ```\n */\nexport interface RateLimitConfig {\n  /**\n   * Maximum number of requests allowed per 1-minute window.\n   *\n   * This determines the token refill rate:\n   * - refillRate = requestsPerMinute / 60000 (tokens per millisecond)\n   *\n   * @example 6 // Allows 6 requests per minute (1 request every 10 seconds)\n   * @example 20 // Allows 20 requests per minute (3 requests every second)\n   */\n  requestsPerMinute: number;\n\n  /**\n   * Optional minimum interval in seconds between requests.\n   *\n   * When specified, enforces a strict minimum time gap between consecutive requests.\n   * This is useful for endpoints with explicit interval requirements (e.g., \"20 seconds between requests\").\n   *\n   * @example 10 // Enforces 10-second minimum interval between requests\n   * @default undefined // No interval enforcement, only per-minute limit\n   */\n  intervalSeconds?: number;\n\n  /**\n   * Optional maximum number of tokens the bucket can hold (burst capacity).\n   *\n   * Allows sending multiple requests rapidly up to this limit before rate limiting kicks in.\n   * After consuming all burst tokens, requests are throttled to the `requestsPerMinute` rate.\n   *\n   * @example 10 // Can send 10 rapid requests, then limited to requestsPerMinute\n   * @default requestsPerMinute // Burst limit equals per-minute limit\n   */\n  burstLimit?: number;\n}\n\n/**\n * Mapping of endpoint keys to their rate limit configurations.\n *\n * Each key represents a unique API endpoint or operation (e.g., 'products.create', 'orders.list').\n * Keys are arbitrary strings defined by the SDK module implementations.\n *\n * @example\n * ```typescript\n * const limits: EndpointLimits = {\n *   'products.create': {\n *     requestsPerMinute: 6,\n *     intervalSeconds: 10,\n *     burstLimit: 1\n *   },\n *   'products.list': {\n *     requestsPerMinute: 20,\n *     burstLimit: 20\n *   },\n *   'orders.updateStatus': {\n *     requestsPerMinute: 10\n *   }\n * };\n * ```\n */\nexport type EndpointLimits = Record<string, RateLimitConfig>;\n\n/**\n * Internal token bucket implementation for rate limiting.\n *\n * Implements the token bucket algorithm where:\n * 1. A bucket holds up to `capacity` tokens\n * 2. Tokens refill at a steady `refillRate` over time\n * 3. Each request consumes 1 token\n * 4. Requests queue when no tokens are available\n * 5. Queued requests are processed FIFO when tokens become available\n *\n * This class is used internally by RateLimiter and not exported.\n *\n * @internal\n * @see {@link https://en.wikipedia.org/wiki/Token_bucket Token Bucket Algorithm}\n */\nclass _TokenBucket {\n  /**\n   * Current number of tokens available in the bucket.\n   * Starts at `capacity` and decreases with each request.\n   * Refills over time based on `refillRate`.\n   */\n  private tokens: number;\n\n  /**\n   * Maximum number of tokens the bucket can hold (burst capacity).\n   * Derived from config.burstLimit or config.requestsPerMinute.\n   */\n  private readonly capacity: number;\n\n  /**\n   * Rate at which tokens are added to the bucket (tokens per millisecond).\n   * Calculated as: requestsPerMinute / 60000\n   *\n   * @example\n   * // For 6 requests/minute:\n   * refillRate = 6 / 60000 = 0.0001 tokens/ms = 1 token/10000ms\n   */\n  private readonly refillRate: number;\n\n  /**\n   * Timestamp (milliseconds since epoch) of the last token refill operation.\n   * Used to calculate how many tokens to add based on elapsed time.\n   */\n  private lastRefill: number;\n\n  /**\n   * Queue of pending requests waiting for tokens to become available.\n   * Each item is a Promise resolve function that will be called when\n   * a token becomes available for that request.\n   *\n   * Requests are processed in FIFO order.\n   */\n  private readonly queue: (() => void)[];\n\n  /**\n   * Creates a new token bucket with the specified rate limit configuration.\n   *\n   * @param config - Rate limit configuration for this bucket\n   */\n  constructor(config: RateLimitConfig) {\n    this.capacity = config.burstLimit ?? config.requestsPerMinute;\n    this.tokens = this.capacity; // Start with full bucket\n    this.refillRate = config.requestsPerMinute / 60000; // tokens per millisecond\n    this.lastRefill = Date.now();\n    this.queue = [];\n  }\n\n  /**\n   * Refills tokens based on elapsed time since last refill.\n   *\n   * Tokens are added at the configured `refillRate` but never exceed `capacity`.\n   * This method is called before each token consumption attempt.\n   *\n   * @example\n   * // If refillRate is 0.0001 tokens/ms and 10000ms have elapsed:\n   * // tokensToAdd = 10000 * 0.0001 = 1 token\n   * // tokens = Math.min(capacity, currentTokens + 1)\n   */\n  private refill(): void {\n    const now = Date.now();\n    const elapsed = now - this.lastRefill;\n    const tokensToAdd = elapsed * this.refillRate;\n\n    this.tokens = Math.min(this.capacity, this.tokens + tokensToAdd);\n    this.lastRefill = now;\n  }\n\n  /**\n   * Attempts to consume a token for a request.\n   *\n   * If tokens are available, consumes one immediately and resolves.\n   * If no tokens are available, queues the request and returns a Promise\n   * that will resolve when a token becomes available.\n   *\n   * Queued requests are processed in FIFO order.\n   *\n   * @returns Promise that resolves when a token has been consumed\n   *\n   * @example\n   * ```typescript\n   * const bucket = new TokenBucket({ requestsPerMinute: 6, burstLimit: 1 });\n   *\n   * // First request: immediate (token available)\n   * await bucket.consume(); // Resolves immediately\n   *\n   * // Second request: queued (no tokens)\n   * await bucket.consume(); // Waits ~10 seconds for token refill\n   * ```\n   */\n  async consume(): Promise<void> {\n    this.refill();\n\n    if (this.tokens >= 1) {\n      this.tokens -= 1;\n      return; // Immediate execution\n    }\n\n    // Queue the request and wait for token availability\n    return new Promise<void>((resolve) => {\n      this.queue.push(resolve);\n      this.scheduleNextRelease();\n    });\n  }\n\n  /**\n   * Schedules the release of the next queued request when a token becomes available.\n   *\n   * Calculates the time until the next token will be available based on `refillRate`,\n   * then uses setTimeout to process the next queued request at that time.\n   *\n   * This method is called automatically when a request is queued.\n   *\n   * @private\n   */\n  private scheduleNextRelease(): void {\n    if (this.queue.length === 0) return;\n\n    // Calculate milliseconds until next token is available\n    const timeToNextToken = 1 / this.refillRate;\n\n    setTimeout(() => {\n      this.refill();\n\n      if (this.tokens >= 1 && this.queue.length > 0) {\n        this.tokens -= 1;\n        const resolve = this.queue.shift();\n        if (resolve) {\n          resolve();\n        }\n\n        // Schedule next release if queue has more requests\n        if (this.queue.length > 0) {\n          this.scheduleNextRelease();\n        }\n      }\n    }, timeToNextToken);\n  }\n\n  /**\n   * Get the current number of available tokens after refilling.\n   *\n   * This method triggers a refill and returns the current token count.\n   * Useful for monitoring and debugging.\n   *\n   * @returns Current number of available tokens\n   * @internal\n   */\n  getAvailableTokens(): number {\n    this.refill();\n    return this.tokens;\n  }\n}\n\n/**\n * Rate limiter for API endpoints using the token bucket algorithm.\n *\n * Manages per-endpoint rate limiting to prevent exceeding API quotas.\n * Each endpoint key (e.g., 'products.create', 'orders.list') can have\n * independent rate limit configurations.\n *\n * Features:\n * - Automatic request queueing when rate limit reached\n * - FIFO queue processing\n * - Per-endpoint configuration\n * - Dynamic configuration updates\n * - Zero external dependencies (in-memory state)\n *\n * @example\n * ```typescript\n * import { RateLimiter } from './rate-limiter';\n *\n * // Create rate limiter with predefined limits\n * const limiter = new RateLimiter({\n *   'products.create': {\n *     requestsPerMinute: 6,\n *     intervalSeconds: 10,\n *     burstLimit: 1\n *   },\n *   'orders.list': {\n *     requestsPerMinute: 5\n *   }\n * });\n *\n * // Wait for rate limit slot before making request\n * await limiter.waitForSlot('products.create');\n * // Request proceeds when token available\n *\n * // Endpoints without configured limits are unlimited\n * await limiter.waitForSlot('general.ping'); // Returns immediately\n * ```\n *\n * @example\n * ```typescript\n * // Create empty rate limiter and configure dynamically\n * const limiter = new RateLimiter();\n *\n * // Add rate limit for specific endpoint\n * limiter.configure('products.update', {\n *   requestsPerMinute: 10,\n *   burstLimit: 5\n * });\n *\n * await limiter.waitForSlot('products.update');\n * ```\n */\nexport class RateLimiter {\n  /**\n   * Map of endpoint keys to their token buckets.\n   * Buckets are created lazily when first accessed for an endpoint.\n   */\n  private readonly buckets = new Map<string, _TokenBucket>();\n\n  /**\n   * Rate limit configuration for each endpoint.\n   * Keys are endpoint identifiers, values are rate limit configs.\n   */\n  private readonly config: EndpointLimits;\n\n  /**\n   * Creates a new RateLimiter instance.\n   *\n   * @param config - Optional initial rate limit configuration.\n   *                 Can be empty and configured dynamically via configure().\n   *                 Defaults to empty object (no limits).\n   *\n   * @example\n   * ```typescript\n   * // With predefined limits\n   * const limiter = new RateLimiter({\n   *   'api.operation': { requestsPerMinute: 10 }\n   * });\n   *\n   * // Empty (configure later)\n   * const limiter = new RateLimiter();\n   * ```\n   */\n  constructor(config?: EndpointLimits) {\n    this.config = config ?? {};\n  }\n\n  /**\n   * Waits for a rate limit slot to become available for the specified endpoint.\n   *\n   * This method should be called before making an API request to ensure\n   * the request doesn't exceed the endpoint's rate limit.\n   *\n   * Behavior:\n   * - If no rate limit is configured for the endpoint key, returns immediately (unlimited)\n   * - If tokens are available, consumes one and returns immediately\n   * - If no tokens available, queues the request and waits until a token is available\n   * - Queued requests are processed in FIFO order\n   *\n   * @param key - Endpoint identifier (e.g., 'products.create', 'orders.list')\n   * @returns Promise that resolves when a rate limit slot is available\n   *\n   * @example\n   * ```typescript\n   * const limiter = new RateLimiter({\n   *   'products.create': { requestsPerMinute: 6, burstLimit: 1 }\n   * });\n   *\n   * // First request: immediate (token available)\n   * await limiter.waitForSlot('products.create');\n   * console.log('Request 1 can proceed');\n   *\n   * // Second request: queued (no tokens, waits ~10 seconds)\n   * await limiter.waitForSlot('products.create');\n   * console.log('Request 2 can proceed');\n   *\n   * // Unlimited endpoint: always immediate\n   * await limiter.waitForSlot('general.ping');\n   * console.log('Unlimited request proceeds immediately');\n   * ```\n   *\n   * @example\n   * ```typescript\n   * // Multiple concurrent requests are queued in FIFO order\n   * const promises = [\n   *   limiter.waitForSlot('api.operation'),\n   *   limiter.waitForSlot('api.operation'),\n   *   limiter.waitForSlot('api.operation')\n   * ];\n   *\n   * // First request proceeds immediately (token available)\n   * // Second and third queue and wait in order\n   * await Promise.all(promises);\n   * ```\n   */\n  async waitForSlot(key: string): Promise<void> {\n    const bucket = this.getOrCreateBucket(key);\n    if (!bucket) {\n      return; // No rate limit configured for this endpoint\n    }\n\n    await bucket.consume();\n  }\n\n  /**\n   * Gets or creates a token bucket for the specified endpoint.\n   *\n   * Buckets are created lazily on first access and reused for subsequent requests.\n   * If no rate limit is configured for the endpoint, returns null (unlimited).\n   *\n   * @param key - Endpoint identifier\n   * @returns TokenBucket instance or null if unlimited\n   * @private\n   */\n  private getOrCreateBucket(key: string): _TokenBucket | null {\n    if (this.buckets.has(key)) {\n      return this.buckets.get(key) ?? null;\n    }\n\n    if (!(key in this.config)) {\n      return null; // No rate limit for this endpoint\n    }\n\n    const config = this.config[key];\n    const bucket = new _TokenBucket(config);\n    this.buckets.set(key, bucket);\n    return bucket;\n  }\n\n  /**\n   * Dynamically configure or update rate limit for an endpoint.\n   *\n   * If a bucket already exists for this endpoint, it will be reset\n   * with the new configuration. Existing queued requests will continue\n   * with the old bucket until completed.\n   *\n   * @param key - Endpoint identifier\n   * @param config - Rate limit configuration\n   *\n   * @example\n   * ```typescript\n   * const limiter = new RateLimiter();\n   *\n   * // Add rate limit for endpoint\n   * limiter.configure('products.create', {\n   *   requestsPerMinute: 6,\n   *   intervalSeconds: 10,\n   *   burstLimit: 1\n   * });\n   *\n   * // Update existing rate limit\n   * limiter.configure('products.create', {\n   *   requestsPerMinute: 10  // Increase limit\n   * });\n   * ```\n   */\n  configure(key: string, config: RateLimitConfig): void {\n    this.config[key] = config;\n    // Reset bucket if it exists to apply new config\n    this.buckets.delete(key);\n  }\n\n  /**\n   * Get the current rate limit configuration for an endpoint.\n   *\n   * @param key - Endpoint identifier\n   * @returns Rate limit configuration or undefined if no limit configured\n   *\n   * @example\n   * ```typescript\n   * const config = limiter.getConfiguration('products.create');\n   * if (config) {\n   *   console.log(`Limit: ${config.requestsPerMinute} req/min`);\n   * }\n   * ```\n   */\n  getConfiguration(key: string): RateLimitConfig | undefined {\n    return key in this.config ? this.config[key] : undefined;\n  }\n\n  /**\n   * Check if a request can proceed immediately without queueing.\n   *\n   * This is a non-blocking check useful for monitoring or debugging.\n   * Does NOT consume a token.\n   *\n   * @param key - Endpoint identifier\n   * @returns true if request can proceed immediately, false if would queue\n   *\n   * @example\n   * ```typescript\n   * if (limiter.canProceed('products.create')) {\n   *   console.log('Request will execute immediately');\n   * } else {\n   *   console.log('Request will be queued');\n   * }\n   *\n   * // Still need to call waitForSlot before making request\n   * await limiter.waitForSlot('products.create');\n   * ```\n   */\n  canProceed(key: string): boolean {\n    // Get or create bucket if configuration exists\n    const bucket = this.getOrCreateBucket(key);\n    if (!bucket) {\n      return true; // No configuration = no limit\n    }\n\n    return bucket.getAvailableTokens() >= 1;\n  }\n\n  /**\n   * Get the number of tokens currently available for an endpoint.\n   *\n   * This is a monitoring/debugging method. The value can change rapidly\n   * as tokens are consumed and refilled.\n   *\n   * @param key - Endpoint identifier\n   * @returns Number of available tokens, or Infinity if unlimited\n   *\n   * @example\n   * ```typescript\n   * const remaining = limiter.getRemainingTokens('products.create');\n   * console.log(`${remaining} requests can execute immediately`);\n   * ```\n   */\n  getRemainingTokens(key: string): number {\n    // Get or create bucket if configuration exists\n    const bucket = this.getOrCreateBucket(key);\n    if (!bucket) {\n      return Infinity; // No configuration = unlimited\n    }\n\n    return bucket.getAvailableTokens();\n  }\n\n  /**\n   * Reset rate limiting state for an endpoint or all endpoints.\n   *\n   * Clears token buckets and queued requests. Use with caution as\n   * queued requests will never resolve (they'll hang indefinitely).\n   *\n   * This is primarily a testing utility.\n   *\n   * @param key - Optional endpoint identifier. If omitted, resets all endpoints.\n   *\n   * @example\n   * ```typescript\n   * // Reset specific endpoint\n   * limiter.reset('products.create');\n   *\n   * // Reset all endpoints\n   * limiter.reset();\n   * ```\n   */\n  reset(key?: string): void {\n    if (key) {\n      this.buckets.delete(key);\n    } else {\n      this.buckets.clear();\n    }\n  }\n}\n","/**\n * Retry Handler with Exponential Backoff\n *\n * Provides resilience against transient failures through automatic retry\n * with configurable exponential backoff strategy.\n *\n * @module client/retry-handler\n */\n\nimport {\n  AuthenticationError,\n  ValidationError,\n  RateLimitError,\n  NetworkError,\n} from '../errors';\n\n/**\n * Configuration options for retry behavior\n *\n * Controls how the RetryHandler responds to failures, including\n * maximum retry attempts, delay timing, and backoff strategy.\n *\n * @example\n * ```typescript\n * // Default behavior (3 retries with exponential backoff)\n * const defaultConfig = {};\n *\n * // Custom: More aggressive retries\n * const aggressive: RetryConfig = {\n *   maxRetries: 5,\n *   retryDelay: 500,\n *   exponentialBackoff: true\n * };\n *\n * // Custom: Linear backoff (no exponential)\n * const linear: RetryConfig = {\n *   maxRetries: 3,\n *   retryDelay: 2000,\n *   exponentialBackoff: false\n * };\n * ```\n */\nexport interface RetryConfig {\n  /**\n   * Maximum number of retry attempts after initial failure\n   *\n   * @default 3\n   * @minimum 0\n   * @example\n   * ```typescript\n   * maxRetries: 3  // Initial attempt + 3 retries = 4 total attempts\n   * maxRetries: 0  // Disable retries completely\n   * ```\n   */\n  maxRetries?: number;\n\n  /**\n   * Initial delay in milliseconds before first retry\n   *\n   * With exponential backoff, subsequent delays are calculated as:\n   * `retryDelay * 2^attempt * jitter`\n   *\n   * @default 1000 (1 second)\n   * @minimum 0\n   * @example\n   * ```typescript\n   * retryDelay: 1000  // 1s, 2s, 4s, 8s with exponential backoff\n   * retryDelay: 500   // 500ms, 1s, 2s, 4s with exponential backoff\n   * ```\n   */\n  retryDelay?: number;\n\n  /**\n   * Whether to use exponential backoff for retry delays\n   *\n   * - `true`: Delays increase exponentially (1s, 2s, 4s, 8s...)\n   * - `false`: Delays remain constant (1s, 1s, 1s, 1s...)\n   *\n   * Exponential backoff gives APIs time to recover from overload\n   * and reduces load during incidents.\n   *\n   * @default true\n   * @example\n   * ```typescript\n   * exponentialBackoff: true   // 1s → 2s → 4s → 8s\n   * exponentialBackoff: false  // 1s → 1s → 1s → 1s\n   * ```\n   */\n  exponentialBackoff?: boolean;\n}\n\n/**\n * Context information for a retry operation\n *\n * Provides metadata about the current retry attempt, used\n * for logging and debugging purposes.\n */\nexport interface RetryContext {\n  /**\n   * Current retry attempt number (0-indexed)\n   *\n   * - Attempt 0: Initial try\n   * - Attempt 1: First retry\n   * - Attempt 2: Second retry\n   * - etc.\n   *\n   * @minimum 0\n   */\n  attempt: number;\n\n  /**\n   * Human-readable description of the operation being retried\n   *\n   * Used for logging and debugging to identify which operation\n   * is experiencing retries.\n   *\n   * @example\n   * ```typescript\n   * operation: 'GET https://api.example.com/products'\n   * operation: 'POST https://api.example.com/orders'\n   * ```\n   */\n  operation: string;\n}\n\n/**\n * RetryHandler - Automatic retry with exponential backoff\n *\n * Provides resilience against transient failures by automatically retrying\n * failed operations with configurable delays and backoff strategies.\n *\n * **Retry Policy:**\n * - ✅ Retries: 5xx errors, 429 rate limits, network timeouts, connection failures\n * - ❌ NO Retry: 401/403 auth errors, 400/422 validation errors, other 4xx errors\n *\n * **Exponential Backoff:**\n * - Formula: `delay = retryDelay * 2^attempt * jitter`\n * - Jitter: Random ±10% to prevent thundering herd\n * - Max delay: Capped at 30 seconds\n *\n * @example\n * ```typescript\n * const handler = new RetryHandler({\n *   maxRetries: 3,\n *   retryDelay: 1000,\n *   exponentialBackoff: true\n * });\n *\n * const result = await handler.executeWithRetry(\n *   async () => await fetchData(),\n *   'fetchData'\n * );\n * ```\n */\nexport class RetryHandler {\n  private config: Required<RetryConfig>;\n\n  /**\n   * Creates a new RetryHandler instance\n   *\n   * @param config - Optional retry configuration (uses defaults if not provided)\n   *\n   * @example\n   * ```typescript\n   * // Use defaults (3 retries, 1s delay, exponential backoff)\n   * const handler = new RetryHandler();\n   *\n   * // Custom configuration\n   * const handler = new RetryHandler({\n   *   maxRetries: 5,\n   *   retryDelay: 500,\n   *   exponentialBackoff: true\n   * });\n   * ```\n   */\n  constructor(config?: RetryConfig) {\n    this.config = {\n      maxRetries: config?.maxRetries ?? 3,\n      retryDelay: config?.retryDelay ?? 1000,\n      exponentialBackoff: config?.exponentialBackoff ?? true,\n    };\n  }\n\n  /**\n   * Executes an async operation with automatic retry on transient failures\n   *\n   * Wraps the provided operation and automatically retries on failures that\n   * are likely to be transient (network errors, server errors, rate limits).\n   *\n   * **Retry Behavior:**\n   * - Retries on: NetworkError (5xx, timeout, no status), RateLimitError (429)\n   * - NO retry on: AuthenticationError, ValidationError, other 4xx errors\n   * - Uses exponential backoff with jitter (if configured)\n   * - Preserves and re-throws final error after max retries exhausted\n   *\n   * @typeParam T - The return type of the operation\n   * @param operation - Async function to execute (and retry on failure)\n   * @param operationName - Description of operation for logging (optional)\n   * @returns The result of the successful operation\n   * @throws The final error if all retry attempts are exhausted\n   *\n   * @example\n   * ```typescript\n   * // Basic usage\n   * const data = await handler.executeWithRetry(\n   *   async () => await api.getData(),\n   *   'getData'\n   * );\n   *\n   * // With arrow function\n   * const result = await handler.executeWithRetry(\n   *   () => fetch('https://api.example.com/data').then(r => r.json()),\n   *   'fetch data'\n   * );\n   * ```\n   */\n  async executeWithRetry<T>(\n    operation: () => Promise<T>,\n    operationName = 'operation'\n  ): Promise<T> {\n    let lastError: Error | undefined;\n\n    for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {\n      try {\n        const result = await operation();\n\n        // Log success after retries\n        if (attempt > 0) {\n          this.log('info', `Operation succeeded after ${String(attempt)} retries`, {\n            operationName,\n          });\n        }\n\n        return result;\n      } catch (error) {\n        lastError = error as Error;\n\n        // Check if we should retry this error\n        if (!this.shouldRetry(error, attempt)) {\n          throw error;\n        }\n\n        // Calculate delay for next retry\n        const delay = this.calculateDelay(attempt);\n\n        this.log('debug', `Retry attempt ${String(attempt + 1)}/${String(this.config.maxRetries)}`, {\n          operationName,\n          delay,\n          error: error instanceof Error ? error.message : String(error),\n        });\n\n        await this.sleep(delay);\n      }\n    }\n\n    // All retries exhausted\n    this.log('warn', `Max retries exhausted for ${operationName}`, {\n      maxRetries: this.config.maxRetries,\n    });\n\n    // This should never happen due to loop logic, but TypeScript needs the check\n    if (!lastError) {\n      throw new Error('Unexpected: No error captured after retry exhaustion');\n    }\n\n    throw lastError;\n  }\n\n  /**\n   * Determines if an error should be retried\n   *\n   * Classifies errors into retryable (transient) and non-retryable (permanent).\n   *\n   * **Retryable Errors:**\n   * - NetworkError with 5xx status (500-599)\n   * - NetworkError with timeout flag\n   * - NetworkError with no status (network failure)\n   * - RateLimitError (429)\n   *\n   * **Non-Retryable Errors:**\n   * - AuthenticationError (401, 403) - invalid credentials won't fix with retry\n   * - ValidationError (400, 422) - bad request data won't fix with retry\n   * - Other 4xx errors - client errors are permanent failures\n   *\n   * @param error - The error to classify\n   * @param attempt - Current attempt number (0-indexed)\n   * @returns true if error should be retried, false otherwise\n   *\n   * @private\n   */\n  private shouldRetry(error: unknown, attempt: number): boolean {\n    // Exhausted retries\n    if (attempt >= this.config.maxRetries) {\n      return false;\n    }\n\n    // Type-safe error checking using instanceof\n    if (error instanceof AuthenticationError) {\n      return false; // Permanent failure - invalid credentials\n    }\n\n    if (error instanceof ValidationError) {\n      return false; // Permanent failure - bad request data\n    }\n\n    if (error instanceof RateLimitError) {\n      return true; // Transient - should retry with backoff\n    }\n\n    if (error instanceof NetworkError) {\n      // Retry on 5xx, timeouts, and network failures\n      const status = error.statusCode;\n\n      // No status = network failure (retry)\n      if (!status || status === 0) return true;\n\n      // 5xx errors are transient server errors\n      if (status >= 500 && status < 600) return true;\n\n      // Timeouts are transient\n      if (error.isTimeout) return true;\n\n      // Other status codes (4xx except 429) are permanent failures\n      return false;\n    }\n\n    // Unknown error type - default to no retry (conservative approach)\n    return false;\n  }\n\n  /**\n   * Calculates the delay before the next retry attempt\n   *\n   * **Exponential Backoff (when enabled):**\n   * - Formula: `delay = retryDelay * 2^attempt * jitter`\n   * - Example: 1s → 2s → 4s → 8s (with default 1000ms retryDelay)\n   *\n   * **Linear Backoff (when disabled):**\n   * - Formula: `delay = retryDelay * jitter`\n   * - Example: 1s → 1s → 1s → 1s (constant delay)\n   *\n   * **Jitter:**\n   * - Adds random ±10% variation to prevent thundering herd\n   * - Multiple clients won't retry simultaneously after service recovery\n   *\n   * **Max Cap:**\n   * - Delays are capped at 30 seconds to prevent excessive waits\n   *\n   * @param attempt - Current attempt number (0-indexed)\n   * @returns Delay in milliseconds before next retry\n   *\n   * @example\n   * ```typescript\n   * // With exponentialBackoff: true, retryDelay: 1000\n   * calculateDelay(0) // ~1000ms (1s * 2^0 * jitter)\n   * calculateDelay(1) // ~2000ms (1s * 2^1 * jitter)\n   * calculateDelay(2) // ~4000ms (1s * 2^2 * jitter)\n   *\n   * // With exponentialBackoff: false, retryDelay: 1000\n   * calculateDelay(0) // ~1000ms\n   * calculateDelay(1) // ~1000ms\n   * calculateDelay(2) // ~1000ms\n   * ```\n   *\n   * @private\n   */\n  private calculateDelay(attempt: number): number {\n    let delay: number;\n\n    if (this.config.exponentialBackoff) {\n      // Exponential: delay * 2^attempt\n      delay = this.config.retryDelay * Math.pow(2, attempt);\n    } else {\n      // Linear: constant delay\n      delay = this.config.retryDelay;\n    }\n\n    // Add jitter (±10%) to prevent thundering herd\n    const jitter = 1 + (Math.random() * 0.2 - 0.1);\n    delay = delay * jitter;\n\n    // Cap at 30 seconds to prevent excessive waits\n    return Math.min(delay, 30000);\n  }\n\n  /**\n   * Sleeps for the specified number of milliseconds\n   *\n   * @param ms - Milliseconds to sleep\n   * @returns Promise that resolves after the delay\n   *\n   * @private\n   */\n  private async sleep(ms: number): Promise<void> {\n    return new Promise((resolve) => setTimeout(resolve, ms));\n  }\n\n  /**\n   * Logs retry-related messages\n   *\n   * Uses structured logging format for consistency with BaseClient.\n   * Debug logs are skipped by default to reduce noise.\n   *\n   * @param level - Log level (debug, info, warn, error)\n   * @param message - Log message\n   * @param meta - Optional metadata to include in log\n   *\n   * @private\n   */\n  private log(level: string, message: string, meta?: unknown): void {\n    // Skip debug logs by default (reduce noise)\n    if (level === 'debug') return;\n\n    // Simple console logging - integrate with BaseClient logger in production\n    // eslint-disable-next-line no-console\n    const logMethod = console[level as 'info' | 'warn' | 'error'];\n\n    const logData: Record<string, unknown> = {\n      timestamp: new Date().toISOString(),\n      level,\n      service: 'RetryHandler',\n      message,\n    };\n\n    // Safely merge meta if it's an object\n    if (meta && typeof meta === 'object') {\n      Object.assign(logData, meta);\n    }\n\n    logMethod(logData);\n  }\n}\n\n","/**\n * Auto-generated rate limit configuration for general module\n * Generated from: wildberries_api_doc/01-general.yaml\n * DO NOT EDIT MANUALLY - Changes will be overwritten on regeneration\n *\n * This file contains rate limit configurations extracted from OpenAPI operation descriptions.\n * Rate limits are enforced by the RateLimiter (Story 1.4) using the token bucket algorithm.\n *\n * @see {@link ../../src/client/rate-limiter!RateLimiter RateLimiter Documentation}\n * @module config/general-rate-limits\n * @generated\n */\n\nimport type { RateLimitConfig } from '../client/rate-limiter';\n\nexport const generalRateLimits: Record<string, RateLimitConfig> = {\n  'general.ping': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'general.communicationsNews': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'general.sellerInfo': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  }\n};\n","/**\n * Auto-generated rate limit configuration for products module\n * Generated from: wildberries_api_doc/02-products.yaml\n * DO NOT EDIT MANUALLY - Changes will be overwritten on regeneration\n *\n * This file contains rate limit configurations extracted from OpenAPI operation descriptions.\n * Rate limits are enforced by the RateLimiter (Story 1.4) using the token bucket algorithm.\n *\n * @see {@link ../../src/client/rate-limiter!RateLimiter RateLimiter Documentation}\n * @module config/products-rate-limits\n * @generated\n */\n\nimport type { RateLimitConfig } from '../client/rate-limiter';\n\nexport const productsRateLimits: Record<string, RateLimitConfig> = {\n  'products.contentObjectParentAll': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentObjectAll': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentObjectCharcs': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentDirectoryColors': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentDirectoryKinds': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentDirectoryCountries': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentDirectorySeasons': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentDirectoryVat': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentDirectoryTnved': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentTags': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentTag': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.patchContentTag': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.deleteContentTag': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentTagNomenclatureLink': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentGetCardsList': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentCardsErrorList': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'products.postContentCardsUpdate': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'products.postContentCardsMoveNm': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentCardsDeleteTrash': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentCardsRecover': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentGetCardsTrash': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.contentCardsLimits': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentBarcodes': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentCardsUpload': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'products.postContentCardsUploadAdd': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'products.postContentMediaFile': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postContentMediaSave': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postUploadTask': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postUploadTaskSize': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postUploadTaskClubDiscount': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.historyTasks': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.historyGoodsTask': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.bufferTasks': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.bufferGoodsTask': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.listGoodsFilter': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postListGoodsFilter': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.listGoodsSizeNm': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.quarantineGoods': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.postStocks': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.putStocks': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.deleteStocks': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.offices': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.warehouses': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.postWarehouses': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.putWarehouses': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.deleteWarehouses': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.dbwWarehousesContacts': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.putDbwWarehousesContacts': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n\n  // ============================================================================\n  // Media Management Rate Limits (Story 2.3)\n  // ============================================================================\n  // Content API limits: 100 requests/minute, 600ms interval\n  'products.uploadMediaFile': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'products.uploadMediaByURLs': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n\n  // ============================================================================\n  // Pricing Management Rate Limits (Story 2.3)\n  // ============================================================================\n  // Pricing API limits: 10 requests per 6 seconds (STRICTER than Content API)\n  'products.updatePricing': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'products.getPricing': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'products.getPricingTaskStatus': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n\n  // ============================================================================\n  // Warehouse and Stock Management Rate Limits (Story 2.4)\n  // ============================================================================\n  // Warehouse/Stock API limits: 300 requests/minute, 200ms interval, 20 burst\n  // NOTE: 409 errors count as 5 requests!\n  'products.getWBOffices': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.getWarehouses': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.createWarehouse': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.updateWarehouse': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.deleteWarehouse': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.getStock': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.updateStock': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  },\n  'products.deleteStock': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20\n  }\n};\n","/**\n * Rate limit configuration for orders-fbs module\n * Source: wildberries_api_doc/03-orders-fbs.yaml\n *\n * This file contains rate limit configurations for FBS (Fulfillment by Seller) order endpoints.\n * Rate limits are enforced by the RateLimiter (Story 1.4) using the token bucket algorithm.\n *\n * **Shared Rate Limit Pool:**\n * All FBS orders, supplies, and passes methods share the same 300 req/min rate limit pool.\n * Be mindful of total request volume across all FBS operations.\n *\n * **Important:**\n * 409 errors count as 5 requests toward rate limit (for supply operations)\n *\n * @see {@link ../../src/client/rate-limiter!RateLimiter RateLimiter Documentation}\n * @module config/orders-fbs-rate-limits\n */\n\nimport type { RateLimitConfig } from '../client/rate-limiter';\n\nexport const ordersFBSRateLimits: Record<string, RateLimitConfig> = {\n  // ============================================================================\n  // Orders FBS - Order Retrieval and Status Management (Story 2.5)\n  // ============================================================================\n  // Marketplace API limits: 300 requests/minute, 200ms interval, 20 burst\n  // Note: All FBS orders, supplies, and passes methods share this limit pool\n\n  /**\n   * GET /api/v3/orders/new - Get new FBS orders awaiting processing\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   */\n  'ordersFBS.getNewOrders': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  /**\n   * GET /api/v3/orders - Get FBS orders with filters and pagination\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   */\n  'ordersFBS.getOrders': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  /**\n   * POST /api/v3/orders/status - Get order statuses\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   */\n  'ordersFBS.getOrderStatuses': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  // ============================================================================\n  // Orders FBS - Supply Management (Story 2.6)\n  // ============================================================================\n  // Standard FBS limits: 300 requests/minute, 200ms interval, 20 burst\n  // Exception: addOrderToSupply has higher limit (1000 req/min)\n  // Note: 409 errors count as 5 requests for supply operations\n\n  /**\n   * POST /api/v3/supplies - Create new supply\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   */\n  'ordersFBS.createSupply': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  /**\n   * GET /api/v3/supplies - Get supplies with pagination\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   */\n  'ordersFBS.getSupplies': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  /**\n   * GET /api/v3/supplies/{supplyId} - Get supply details\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   */\n  'ordersFBS.getSupply': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  /**\n   * PATCH /api/v3/supplies/{supplyId}/orders/{orderId} - Add order to supply\n   * Rate limit: 1000 req/min, 60ms interval, 20 burst (HIGHER than other endpoints)\n   * Note: 409 errors count as 5 requests\n   */\n  'ordersFBS.addOrderToSupply': {\n    requestsPerMinute: 1000,\n    intervalSeconds: 0.06,\n    burstLimit: 20,\n  },\n\n  /**\n   * PATCH /api/v3/supplies/{supplyId}/deliver - Mark supply as delivered\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   * Note: 409 errors count as 5 requests\n   */\n  'ordersFBS.deliverSupply': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  /**\n   * DELETE /api/v3/supplies/{supplyId} - Delete empty supply\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   * Note: 409 errors count as 5 requests\n   */\n  'ordersFBS.deleteSupply': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  // ============================================================================\n  // Orders FBS - Shipping Labels and Barcodes (Story 2.6)\n  // ============================================================================\n\n  /**\n   * POST /api/v3/orders/stickers - Get order shipping label stickers\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   */\n  'ordersFBS.getOrderStickers': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  /**\n   * GET /api/v3/supplies/{supplyId}/barcode - Get supply QR code\n   * Rate limit: 300 req/min, 200ms interval, 20 burst\n   * Note: 409 errors count as 5 requests\n   */\n  'ordersFBS.getSupplyBarcode': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 20,\n  },\n\n  /**\n   * PATCH /api/v3/orders/{orderId}/cancel - Cancel FBS order\n   * Rate limit: 100 req/min, 600ms interval, 20 burst (LOWER than other endpoints)\n   * Note: 409 errors count as 5 requests\n   */\n  'ordersFBS.cancelOrder': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 20,\n  },\n};\n","/**\n * Auto-generated rate limit configuration for orders-fbw module\n * Generated from: wildberries_api_doc/07-orders-fbw.yaml\n * DO NOT EDIT MANUALLY - Changes will be overwritten on regeneration\n *\n * This file contains rate limit configurations extracted from OpenAPI operation descriptions.\n * Rate limits are enforced by the RateLimiter (Story 1.4) using the token bucket algorithm.\n *\n * @see {@link ../../src/client/rate-limiter!RateLimiter RateLimiter Documentation}\n * @module config/orders-fbw-rate-limits\n * @generated\n */\n\nimport type { RateLimitConfig } from '../client/rate-limiter';\n\nexport const ordersFBWRateLimits: Record<string, RateLimitConfig> = {\n  'orders-fbw.acceptanceCoefficients': {\n    requestsPerMinute: 6,\n    intervalSeconds: 10,\n    burstLimit: 6\n  },\n  'orders-fbw.postAcceptanceOptions': {\n    requestsPerMinute: 6,\n    intervalSeconds: 10,\n    burstLimit: 6\n  },\n  'orders-fbw.warehouses': {\n    requestsPerMinute: 6,\n    intervalSeconds: 10,\n    burstLimit: 6\n  },\n  'orders-fbw.transitTariffs': {\n    requestsPerMinute: 6,\n    intervalSeconds: 10,\n    burstLimit: 10\n  },\n  'orders-fbw.postSupplies': {\n    requestsPerMinute: 30,\n    intervalSeconds: 2,\n    burstLimit: 10\n  },\n  'orders-fbw.supplies': {\n    requestsPerMinute: 30,\n    intervalSeconds: 2,\n    burstLimit: 10\n  },\n  'orders-fbw.suppliesGoods': {\n    requestsPerMinute: 30,\n    intervalSeconds: 2,\n    burstLimit: 10\n  },\n  'orders-fbw.suppliesPackage': {\n    requestsPerMinute: 30,\n    intervalSeconds: 2,\n    burstLimit: 10\n  }\n};\n","/**\n * Aggregated Rate Limit Configuration\n *\n * Central export of all module-specific rate limit configurations.\n * This file combines auto-generated rate limits from all SDK modules for use by the RateLimiter.\n *\n * **Auto-Generation (Story 1.8):**\n * Individual module configs are automatically generated from OpenAPI specifications.\n * This aggregator imports and combines them into a single configuration object.\n *\n * **Module Structure:**\n * - Each module has its own rate limit file: `{module}-rate-limits.ts`\n * - Rate limits are parsed from OpenAPI operation descriptions (Russian rate limit tables)\n * - Conservative defaults (10 req/min, 6s interval, burst: 5) used when parsing fails\n *\n * @module config/rate-limits\n * @see {@link ../client/rate-limiter!RateLimiter RateLimiter Documentation}\n * @see {@link https://dev.wildberries.ru/openapi Wildberries API Documentation}\n */\n\nimport { generalRateLimits } from './general-rate-limits';\nimport { productsRateLimits } from './products-rate-limits';\nimport { ordersFBSRateLimits } from './orders-fbs-rate-limits';\nimport { ordersFBWRateLimits } from './orders-fbw-rate-limits';\n// Import additional module rate limits here as they are generated:\n// import { financesRateLimits } from './finances-rate-limits';\n// import { analyticsRateLimits } from './analytics-rate-limits';\n// import { reportsRateLimits } from './reports-rate-limits';\n// import { communicationsRateLimits } from './communications-rate-limits';\n// import { promotionRateLimits } from './promotion-rate-limits';\n// import { tariffsRateLimits } from './tariffs-rate-limits';\n// import { inStorePickupRateLimits } from './in-store-pickup-rate-limits';\n\n/**\n * Aggregated rate limit configuration for all SDK modules.\n *\n * Combines rate limits from all generated modules into a single object.\n * Endpoint keys follow the format: `{moduleName}.{methodName}`\n *\n * **Current Modules:**\n * - general: General API endpoints (ping, news, seller info)\n * - products: Product management endpoints (categories, CRUD, media, pricing, stock)\n * - ordersFBS: FBS order retrieval and status management endpoints\n * - ordersFBW: FBW warehouse supply and acceptance endpoints\n *\n * **Future Modules (will be added as generated):**\n * - finances: Financial reporting endpoints\n * - analytics: Sales analytics endpoints\n * - reports: Async report generation endpoints\n * - communications: Chat, Q&A, reviews endpoints\n * - promotion: Marketing campaigns endpoints\n * - tariffs: Commission and fee endpoints\n * - inStorePickup: Pickup point management endpoints\n *\n * @example\n * ```typescript\n * import { ALL_RATE_LIMITS } from './config/rate-limits';\n * import { RateLimiter } from './client/rate-limiter';\n *\n * const limiter = new RateLimiter(ALL_RATE_LIMITS);\n * await limiter.waitForSlot('general.ping');\n * ```\n *\n * @example\n * ```typescript\n * // Access individual module limits\n * import { generalRateLimits } from './config/general-rate-limits';\n * console.log(generalRateLimits['general.ping']);\n * ```\n */\nexport const ALL_RATE_LIMITS = {\n  ...generalRateLimits,\n  ...productsRateLimits,\n  ...ordersFBSRateLimits,\n  ...ordersFBWRateLimits,\n  // Spread additional module rate limits here as they are generated:\n  // ...financesRateLimits,\n  // ...analyticsRateLimits,\n  // ...reportsRateLimits,\n  // ...communicationsRateLimits,\n  // ...promotionRateLimits,\n  // ...tariffsRateLimits,\n  // ...inStorePickupRateLimits,\n};\n\n/**\n * Type representing all possible endpoint keys.\n *\n * Automatically inferred from ALL_RATE_LIMITS object.\n * Provides type safety when referencing endpoint keys in code.\n *\n * @example\n * ```typescript\n * const endpointKey: EndpointKey = 'general.ping'; // Type-safe ✓\n * const invalid: EndpointKey = 'invalid.key'; // TypeScript error ✗\n * ```\n */\nexport type EndpointKey = keyof typeof ALL_RATE_LIMITS;\n\n/**\n * Legacy export for backwards compatibility.\n * @deprecated Use ALL_RATE_LIMITS instead\n */\nexport const DEFAULT_RATE_LIMITS = ALL_RATE_LIMITS;\n","/**\n * BaseClient - Core HTTP infrastructure for Wildberries API SDK\n *\n * Provides centralized HTTP client with authentication, timeout configuration,\n * error transformation, and debug logging for all SDK modules.\n *\n * @packageDocumentation\n */\n\nimport axios, { type AxiosInstance, type AxiosError } from 'axios';\nimport type { SDKConfig, RequestOptions } from '../config';\nimport {\n  WBAPIError,\n  AuthenticationError,\n  RateLimitError,\n  ValidationError,\n  NetworkError,\n} from '../errors';\nimport { RateLimiter } from './rate-limiter';\nimport { RetryHandler } from './retry-handler';\nimport { ALL_RATE_LIMITS } from '../config/rate-limits';\n\n/**\n * Base HTTP client for all Wildberries API modules\n *\n * This class provides a unified HTTP interface with:\n * - Automatic authentication header injection\n * - Configurable timeouts\n * - Typed error transformation\n * - Debug logging with PII sanitization\n *\n * All API modules receive a BaseClient instance via dependency injection\n * to ensure consistent behavior across the SDK.\n *\n * @example Basic usage\n * ```typescript\n * const config: SDKConfig = {\n *   apiKey: 'your-api-key',\n *   timeout: 30000,\n *   logLevel: 'debug'\n * };\n *\n * const client = new BaseClient(config);\n *\n * // Make GET request\n * const data = await client.get<ProductResponse>(\n *   'https://content-api.wildberries.ru/api/v1/products'\n * );\n * ```\n *\n * @example With custom headers\n * ```typescript\n * const data = await client.post<CreateProductResponse>(\n *   'https://content-api.wildberries.ru/api/v1/products',\n *   { brandName: 'MyBrand', title: 'Product Title' },\n *   { headers: { 'X-Request-ID': '123' } }\n * );\n * ```\n */\nexport class BaseClient {\n  private axios: AxiosInstance;\n  private apiKey: string;\n  private logLevel: 'debug' | 'info' | 'warn' | 'error';\n  private rateLimiter: RateLimiter;\n  private retryHandler: RetryHandler;\n\n  /**\n   * Creates a new BaseClient instance\n   *\n   * @param config - SDK configuration object\n   *\n   * @throws {Error} If apiKey is not provided or invalid\n   *\n   * @example\n   * ```typescript\n   * const client = new BaseClient({\n   *   apiKey: process.env.WB_API_KEY || '',\n   *   timeout: 60000,\n   *   logLevel: 'info'\n   * });\n   * ```\n   */\n  constructor(config: SDKConfig) {\n    this.apiKey = config.apiKey;\n    this.logLevel = config.logLevel ?? 'warn';\n\n    // Initialize Axios instance with configuration\n    this.axios = axios.create({\n      timeout: config.timeout ?? 30000,\n      headers: {\n        'Content-Type': 'application/json',\n        'User-Agent': 'WildberriesSDK/0.1.0',\n      },\n    });\n\n    // Set up request interceptor for authentication\n    this.setupRequestInterceptor();\n\n    // Initialize rate limiter with predefined limits\n    this.rateLimiter = new RateLimiter(ALL_RATE_LIMITS);\n\n    // Initialize retry handler with configuration\n    this.retryHandler = new RetryHandler(config.retryConfig);\n  }\n\n  /**\n   * Make a GET request with automatic retry on transient failures\n   *\n   * Automatically retries on network errors, 5xx server errors, and 429 rate limits.\n   * Does NOT retry on authentication errors (401/403) or validation errors (400/422).\n   *\n   * @typeParam T - Expected response type\n   * @param url - Full URL for the request\n   * @param options - Optional request options\n   * @returns Promise resolving to typed response data\n   *\n   * @throws {AuthenticationError} On 401/403 responses\n   * @throws {RateLimitError} On 429 responses (after retries exhausted)\n   * @throws {ValidationError} On 400/422 responses\n   * @throws {NetworkError} On network failures or 5xx responses (after retries exhausted)\n   *\n   * @example\n   * ```typescript\n   * interface Product {\n   *   id: string;\n   *   name: string;\n   * }\n   *\n   * const product = await client.get<Product>(\n   *   'https://content-api.wildberries.ru/api/v1/products/123'\n   * );\n   * console.log(product.name);\n   * ```\n   */\n  async get<T>(url: string, options?: RequestOptions): Promise<T> {\n    return this.retryHandler.executeWithRetry(async () => {\n      // Apply rate limiting if rateLimitKey provided\n      if (options?.rateLimitKey) {\n        await this.rateLimiter.waitForSlot(options.rateLimitKey);\n      }\n\n      try {\n        this.log('debug', 'GET request', { url });\n\n        const response = await this.axios.get<T>(url, {\n          headers: options?.headers,\n          params: options?.params,\n          responseType: options?.responseType,\n        });\n\n        this.log('debug', 'GET response', {\n          url,\n          status: response.status,\n        });\n\n        return response.data;\n      } catch (error) {\n        this.transformError(error);\n      }\n    }, `GET ${url}`);\n  }\n\n  /**\n   * Make a POST request with automatic retry on transient failures\n   *\n   * Automatically retries on network errors, 5xx server errors, and 429 rate limits.\n   * Does NOT retry on authentication errors (401/403) or validation errors (400/422).\n   *\n   * @typeParam T - Expected response type\n   * @param url - Full URL for the request\n   * @param data - Request body data\n   * @param options - Optional request options\n   * @returns Promise resolving to typed response data\n   *\n   * @throws {AuthenticationError} On 401/403 responses\n   * @throws {RateLimitError} On 429 responses (after retries exhausted)\n   * @throws {ValidationError} On 400/422 responses\n   * @throws {NetworkError} On network failures or 5xx responses (after retries exhausted)\n   *\n   * @example\n   * ```typescript\n   * interface CreateProductRequest {\n   *   brandName: string;\n   *   title: string;\n   * }\n   *\n   * interface CreateProductResponse {\n   *   id: string;\n   * }\n   *\n   * const result = await client.post<CreateProductResponse>(\n   *   'https://content-api.wildberries.ru/api/v1/products',\n   *   { brandName: 'MyBrand', title: 'New Product' }\n   * );\n   * ```\n   */\n  async post<T>(\n    url: string,\n    data?: unknown,\n    options?: RequestOptions\n  ): Promise<T> {\n    return this.retryHandler.executeWithRetry(async () => {\n      // Apply rate limiting if rateLimitKey provided\n      if (options?.rateLimitKey) {\n        await this.rateLimiter.waitForSlot(options.rateLimitKey);\n      }\n\n      try {\n        this.log('debug', 'POST request', { url });\n\n        const response = await this.axios.post<T>(url, data, {\n          headers: options?.headers,\n          params: options?.params,\n        });\n\n        this.log('debug', 'POST response', {\n          url,\n          status: response.status,\n        });\n\n        return response.data;\n      } catch (error) {\n        this.transformError(error);\n      }\n    }, `POST ${url}`);\n  }\n\n  /**\n   * Make a PUT request with automatic retry on transient failures\n   *\n   * Automatically retries on network errors, 5xx server errors, and 429 rate limits.\n   * Does NOT retry on authentication errors (401/403) or validation errors (400/422).\n   *\n   * @typeParam T - Expected response type\n   * @param url - Full URL for the request\n   * @param data - Request body data\n   * @param options - Optional request options\n   * @returns Promise resolving to typed response data\n   *\n   * @throws {AuthenticationError} On 401/403 responses\n   * @throws {RateLimitError} On 429 responses (after retries exhausted)\n   * @throws {ValidationError} On 400/422 responses\n   * @throws {NetworkError} On network failures or 5xx responses (after retries exhausted)\n   *\n   * @example\n   * ```typescript\n   * const updated = await client.put<ProductResponse>(\n   *   'https://content-api.wildberries.ru/api/v1/products/123',\n   *   { title: 'Updated Title' }\n   * );\n   * ```\n   */\n  async put<T>(\n    url: string,\n    data?: unknown,\n    options?: RequestOptions\n  ): Promise<T> {\n    return this.retryHandler.executeWithRetry(async () => {\n      // Apply rate limiting if rateLimitKey provided\n      if (options?.rateLimitKey) {\n        await this.rateLimiter.waitForSlot(options.rateLimitKey);\n      }\n\n      try {\n        this.log('debug', 'PUT request', { url });\n\n        const response = await this.axios.put<T>(url, data, {\n          headers: options?.headers,\n          params: options?.params,\n        });\n\n        this.log('debug', 'PUT response', {\n          url,\n          status: response.status,\n        });\n\n        return response.data;\n      } catch (error) {\n        this.transformError(error);\n      }\n    }, `PUT ${url}`);\n  }\n\n  /**\n   * Make a PATCH request with automatic retry on transient failures\n   *\n   * Automatically retries on network errors, 5xx server errors, and 429 rate limits.\n   * Does NOT retry on authentication errors (401/403) or validation errors (400/422).\n   *\n   * @typeParam T - Expected response type\n   * @param url - Full URL for the request\n   * @param data - Request body data\n   * @param options - Optional request options\n   * @returns Promise resolving to typed response data\n   *\n   * @throws {AuthenticationError} On 401/403 responses\n   * @throws {RateLimitError} On 429 responses (after retries exhausted)\n   * @throws {ValidationError} On 400/422 responses\n   * @throws {NetworkError} On network failures or 5xx responses (after retries exhausted)\n   *\n   * @example\n   * ```typescript\n   * const patched = await client.patch<ProductResponse>(\n   *   'https://content-api.wildberries.ru/api/v1/products/123',\n   *   { stock: 100 }\n   * );\n   * ```\n   */\n  async patch<T>(\n    url: string,\n    data?: unknown,\n    options?: RequestOptions\n  ): Promise<T> {\n    return this.retryHandler.executeWithRetry(async () => {\n      // Apply rate limiting if rateLimitKey provided\n      if (options?.rateLimitKey) {\n        await this.rateLimiter.waitForSlot(options.rateLimitKey);\n      }\n\n      try {\n        this.log('debug', 'PATCH request', { url });\n\n        const response = await this.axios.patch<T>(url, data, {\n          headers: options?.headers,\n          params: options?.params,\n        });\n\n        this.log('debug', 'PATCH response', {\n          url,\n          status: response.status,\n        });\n\n        return response.data;\n      } catch (error) {\n        this.transformError(error);\n      }\n    }, `PATCH ${url}`);\n  }\n\n  /**\n   * Make a DELETE request with automatic retry on transient failures\n   *\n   * Automatically retries on network errors, 5xx server errors, and 429 rate limits.\n   * Does NOT retry on authentication errors (401/403) or validation errors (400/422).\n   *\n   * @typeParam T - Expected response type\n   * @param url - Full URL for the request\n   * @param data - Optional request body data (RFC 7231 allows DELETE with body)\n   * @param options - Optional request options\n   * @returns Promise resolving to typed response data\n   *\n   * @throws {AuthenticationError} On 401/403 responses\n   * @throws {RateLimitError} On 429 responses (after retries exhausted)\n   * @throws {ValidationError} On 400/422 responses\n   * @throws {NetworkError} On network failures or 5xx responses (after retries exhausted)\n   *\n   * @example\n   * ```typescript\n   * // DELETE without body\n   * await client.delete<void>(\n   *   'https://content-api.wildberries.ru/api/v1/products/123'\n   * );\n   *\n   * // DELETE with body (RFC 7231 allows this)\n   * await client.delete<void>(\n   *   'https://marketplace-api.wildberries.ru/api/v3/stocks/123',\n   *   { skus: ['SKU123', 'SKU456'] }\n   * );\n   * ```\n   */\n  async delete<T>(url: string, data?: unknown, options?: RequestOptions): Promise<T> {\n    return this.retryHandler.executeWithRetry(async () => {\n      // Apply rate limiting if rateLimitKey provided\n      if (options?.rateLimitKey) {\n        await this.rateLimiter.waitForSlot(options.rateLimitKey);\n      }\n\n      try {\n        this.log('debug', 'DELETE request', { url, hasBody: !!data });\n\n        const response = await this.axios.delete<T>(url, {\n          headers: options?.headers,\n          params: options?.params,\n          data,\n        });\n\n        this.log('debug', 'DELETE response', {\n          url,\n          status: response.status,\n        });\n\n        return response.data;\n      } catch (error) {\n        this.transformError(error);\n      }\n    }, `DELETE ${url}`);\n  }\n\n  /**\n   * Set up Axios request interceptor for authentication\n   *\n   * Automatically injects the Authorization header on all requests\n   * and logs request details in debug mode.\n   *\n   * @private\n   */\n  private setupRequestInterceptor(): void {\n    this.axios.interceptors.request.use((config) => {\n      // Inject authentication header\n      config.headers.Authorization = `Bearer ${this.apiKey}`;\n\n      // Debug logging with sanitized headers\n      if (this.logLevel === 'debug') {\n        this.log('debug', 'HTTP Request Interceptor', {\n          method: config.method?.toUpperCase(),\n          url: config.url,\n          headers: this.sanitizeHeaders(config.headers),\n        });\n      }\n\n      return config;\n    });\n  }\n\n  /**\n   * Transform Axios errors to typed SDK errors\n   *\n   * Maps HTTP status codes and network errors to appropriate error classes:\n   * - 401/403 → AuthenticationError\n   * - 429 → RateLimitError\n   * - 400/422 → ValidationError\n   * - 5xx → NetworkError\n   * - Network failures → NetworkError\n   *\n   * @param error - Error from Axios request\n   * @throws Typed SDK error\n   *\n   * @private\n   */\n  private transformError(error: unknown): never {\n    // Type guard for Axios errors\n    if (!axios.isAxiosError(error)) {\n      this.log('error', 'Unknown error occurred', { error });\n      throw new NetworkError(\n        'Unknown error occurred',\n        false,\n        0,\n        error as Error\n      );\n    }\n\n    const axiosError = error as AxiosError;\n\n    // No response = network failure\n    if (!axiosError.response) {\n      const isTimeout =\n        axiosError.code === 'ECONNABORTED' || axiosError.code === 'ETIMEDOUT';\n\n      this.log('error', 'Network error', {\n        code: axiosError.code,\n        isTimeout,\n        message: axiosError.message,\n      });\n\n      throw new NetworkError(\n        isTimeout ? 'Request timed out' : 'Network error occurred',\n        isTimeout,\n        0,\n        axiosError\n      );\n    }\n\n    const status = axiosError.response.status;\n    const responseData = axiosError.response.data;\n\n    this.log('warn', 'HTTP error response', {\n      status,\n      url: axiosError.config?.url,\n    });\n\n    // Transform based on status code\n    if (status === 401 || status === 403) {\n      throw new AuthenticationError(\n        'Authentication failed. Please verify your API key.',\n        status\n      );\n    }\n\n    if (status === 429) {\n      const retryAfter = this.parseRetryAfter(\n        axiosError.response.headers['retry-after'] as string | undefined\n      );\n      throw new RateLimitError(\n        `Rate limit exceeded. Retry after ${retryAfter.toString()}ms`,\n        retryAfter\n      );\n    }\n\n    if (status === 400 || status === 422) {\n      const fieldErrors = this.extractFieldErrors(responseData);\n      throw new ValidationError(\n        'Validation failed',\n        fieldErrors,\n        status\n      );\n    }\n\n    if (status >= 500) {\n      throw new NetworkError(\n        `Server error: ${status.toString()}`,\n        false,\n        status,\n        axiosError\n      );\n    }\n\n    // Fallback for unexpected status codes\n    throw new WBAPIError(`HTTP error ${status.toString()}`, status, responseData);\n  }\n\n  /**\n   * Parse Retry-After header to milliseconds\n   *\n   * @param header - Retry-After header value (in seconds)\n   * @returns Retry delay in milliseconds\n   *\n   * @private\n   */\n  private parseRetryAfter(header?: string): number {\n    if (!header) return 5000; // Default 5 seconds\n    const seconds = parseInt(header, 10);\n    return isNaN(seconds) ? 5000 : seconds * 1000; // Convert to milliseconds\n  }\n\n  /**\n   * Extract field-level validation errors from API response\n   *\n   * @param responseData - API response data\n   * @returns Field errors map or undefined\n   *\n   * @private\n   */\n  private extractFieldErrors(\n    responseData: unknown\n  ): Record<string, string> | undefined {\n    // Parse API-specific error format\n    if (\n      responseData &&\n      typeof responseData === 'object' &&\n      'errors' in responseData &&\n      responseData.errors &&\n      typeof responseData.errors === 'object'\n    ) {\n      return responseData.errors as Record<string, string>;\n    }\n    return undefined;\n  }\n\n  /**\n   * Log message with structured format and sanitization\n   *\n   * Only logs if message level meets or exceeds configured logLevel.\n   * Automatically sanitizes sensitive information (API keys, PII).\n   *\n   * @param level - Log level\n   * @param message - Log message\n   * @param meta - Optional metadata\n   *\n   * @private\n   */\n  private log(\n    level: 'debug' | 'info' | 'warn' | 'error',\n    message: string,\n    meta?: unknown\n  ): void {\n    const levels = { debug: 0, info: 1, warn: 2, error: 3 };\n    const currentLevel = levels[this.logLevel];\n    const messageLevel = levels[level];\n\n    if (messageLevel < currentLevel) return; // Skip if below threshold\n\n    const logData = {\n      timestamp: new Date().toISOString(),\n      level,\n      service: 'WildberriesSDK',\n      message,\n      meta: this.sanitizeMeta(meta),\n    };\n\n    const consoleMethods = {\n      // eslint-disable-next-line no-console\n      debug: console.debug,\n      // eslint-disable-next-line no-console\n      info: console.info,\n      // eslint-disable-next-line no-console\n      warn: console.warn,\n      // eslint-disable-next-line no-console\n      error: console.error,\n    };\n\n    consoleMethods[level](JSON.stringify(logData));\n  }\n\n  /**\n   * Sanitize metadata to remove sensitive information\n   *\n   * @param meta - Raw metadata object\n   * @returns Sanitized metadata\n   *\n   * @private\n   */\n  private sanitizeMeta(meta: unknown): unknown {\n    if (!meta) return undefined;\n\n    try {\n      // Deep clone to avoid modifying original\n      const sanitized: unknown = JSON.parse(JSON.stringify(meta));\n\n      // Sanitize Authorization headers with proper type guards\n      if (\n        sanitized &&\n        typeof sanitized === 'object' &&\n        'headers' in sanitized &&\n        sanitized.headers &&\n        typeof sanitized.headers === 'object'\n      ) {\n        const headers = sanitized.headers as Record<string, unknown>;\n        if ('Authorization' in headers) {\n          headers.Authorization = 'Bearer ***';\n        }\n      }\n\n      return sanitized;\n    } catch {\n      return undefined;\n    }\n  }\n\n  /**\n   * Sanitize headers for logging\n   *\n   * @param headers - Request headers\n   * @returns Sanitized headers\n   *\n   * @private\n   */\n  private sanitizeHeaders(\n    headers: Record<string, string>\n  ): Record<string, string> {\n    const sanitized = { ...headers };\n    if (sanitized.Authorization) {\n      sanitized.Authorization = 'Bearer ***';\n    }\n    return sanitized;\n  }\n}\n","/**\n * Auto-generated module\n * Generated from: wildberries_api_doc/01-general.yaml\n * DO NOT EDIT MANUALLY - Changes will be overwritten on next generation\n */\n\nimport { BaseClient } from '../../client/base-client';\n\nexport class GeneralModule {\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Проверка подключения\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.ping();\n  console.log(result);\n   */\n  async ping(): Promise<{ TS?: string; Status?: 'OK' }> {\n    return this.client.get<{ TS?: string; Status?: 'OK' }>('https://common-api.wildberries.ru/ping');\n  }\n\n  /**\n   * Получение новостей портала продавцов\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.news({});\n  console.log(result);\n   */\n  async news(options?: { from?: string; fromID?: number }): Promise<{ data?: { content?: string; date?: string; header?: string; id?: number; types?: { id?: number; name?: string }[] }[] }> {\n    return this.client.get<{ data?: { content?: string; date?: string; header?: string; id?: number; types?: { id?: number; name?: string }[] }[] }>('https://common-api.wildberries.ru/api/communications/v2/news', { params: options });\n  }\n\n  /**\n   * Получение информации о продавце\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.sellerInfo();\n  console.log(result);\n   */\n  async sellerInfo(): Promise<{ name?: string; sid?: string; tradeMark?: string }> {\n    return this.client.get<{ name?: string; sid?: string; tradeMark?: string }>('https://common-api.wildberries.ru/api/v1/seller-info');\n  }\n\n}","/**\n * Auto-generated module\n * Generated from: wildberries_api_doc/02-products.yaml\n * DO NOT EDIT MANUALLY - Changes will be overwritten on next generation\n */\n\nimport { BaseClient } from '../../client/base-client';\nimport { ValidationError } from '../../errors/validation-error';\nimport type { Office, RequestMoveNmsImtConn, RequestMoveNmsImtDisconn, RequestPublicViewerPublicErrorsTableListV2, ResponseCardCreate, ResponseContentError, ResponsePublicViewerPublicErrorsTableListV2, StoreContactRequestBody, Warehouse, CreateProductRequest, CreateProductResponse, ProductListRequest, ProductListResponse, ProductListCursor, UpdateProductRequest, UpdateProductResponse, DeleteProductResponse, ProductCard, MediaUploadResponse, PricingUpdate, PricingTaskResponse, PricingInfo, GetPricingResponse, PricingTaskStatusResponse, StockUpdate, StockInfo } from '../../types/products.types';\n\nexport class ProductsModule {\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Родительские категории товаров\n   *\n   * Метод возвращает названия и ID всех родительских категорий для [создания карточек товаров](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov): например, `Электроника`, `Бытовая химия`, `Рукоделие`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getParentAll({});\n  console.log(result);\n   */\n  async getParentAll(options?: { locale?: string }): Promise<{ data?: unknown; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: unknown; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/object/parent/all', { params: options });\n  }\n\n  /**\n   * Список предметов\n   *\n   * Метод возвращает список названий [родительских категорий предметов](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1parent~1all/get) и их предметов с ID. Например, у категории `Игрушки` будут предметы `Калейдоскопы`, `Куклы`, `Мячики`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getObjectAll({});\n  console.log(result);\n   */\n  async getObjectAll(options?: { locale?: string; name?: string; limit?: number; offset?: number; parentID?: number }): Promise<{ data?: { subjectID?: number; parentID?: number; subjectName?: string; parentName?: string }[]; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: { subjectID?: number; parentID?: number; subjectName?: string; parentName?: string }[]; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/object/all', { params: options });\n  }\n\n  /**\n   * Характеристики предмета\n   *\n   * Метод возвращает параметры характеристик предмета: названия, типы данных, единицы измерения и так далее. В запросе необходимо указать ID [предмета](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1all/get). <div class=\"description_important\"> Для получения значений характеристик <a href=\"/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1colors/get\">Цвет</a>, <a href=\"/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1kinds/get\">Пол</a>, <a href=\"/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1countries/get\">Страна производства</a>, <a href=\"/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1seasons/get\">Сезон</a>, <a href=\"/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1vat/get\">Ставка НДС</a> и <a href=\"/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1directory~1tnved/get\">ТНВЭД-код</a> используйте отдельные методы </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param subjectId - ID предмета\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getObjectCharc('subjectId-value', {});\n  console.log(result);\n   */\n  async getObjectCharc(subjectId: number, options?: { locale?: string }): Promise<{ data?: { charcID?: number; subjectName?: string; subjectID?: number; name?: string; required?: boolean; unitName?: string; maxCount?: number; popular?: boolean; charcType?: number }[]; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: { charcID?: number; subjectName?: string; subjectID?: number; name?: string; required?: boolean; unitName?: string; maxCount?: number; popular?: boolean; charcType?: number }[]; error?: boolean; errorText?: string; additionalErrors?: string }>(`https://content-api.wildberries.ru/content/v2/object/charcs/${subjectId}`, { params: options });\n  }\n\n  /**\n   * Цвет\n   *\n   * Метод возвращает возможные значения [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Цвет`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getDirectoryColors({});\n  console.log(result);\n   */\n  async getDirectoryColors(options?: { locale?: string }): Promise<{ data?: unknown; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: unknown; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/directory/colors', { params: options });\n  }\n\n  /**\n   * Пол\n   *\n   * Метод возвращает возможные значения [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Пол`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getDirectoryKinds({});\n  console.log(result);\n   */\n  async getDirectoryKinds(options?: { locale?: string }): Promise<{ data?: string[]; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: string[]; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/directory/kinds', { params: options });\n  }\n\n  /**\n   * Страна производства\n   *\n   * Метод возвращает возможные значения [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Страна производства`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getDirectoryCountries({});\n  console.log(result);\n   */\n  async getDirectoryCountries(options?: { locale?: string }): Promise<{ data?: unknown; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: unknown; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/directory/countries', { params: options });\n  }\n\n  /**\n   * Сезон\n   *\n   * Метод возвращает возможные значения [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Сезон`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getDirectorySeasons({});\n  console.log(result);\n   */\n  async getDirectorySeasons(options?: { locale?: string }): Promise<{ data?: string[]; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: string[]; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/directory/seasons', { params: options });\n  }\n\n  /**\n   * Ставка НДС\n   *\n   * Метод возвращает возможные значения [характеристики](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1charcs~1%7BsubjectId%7D/get) предмета `Ставка НДС`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getDirectoryVat({});\n  console.log(result);\n   */\n  async getDirectoryVat(options?: { locale?: string }): Promise<{ data?: string[]; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: string[]; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/directory/vat', { params: options });\n  }\n\n  /**\n   * ТНВЭД-код\n   *\n   * Метод возвращает список ТНВЭД-кодов по ID [предмета](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1all/get) и фрагменту ТНВЭД-кода. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getDirectoryTnved({});\n  console.log(result);\n   */\n  async getDirectoryTnved(options?: { subjectID: number; search?: number; locale?: string }): Promise<{ data?: { tnved?: string; isKiz?: boolean }[]; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: { tnved?: string; isKiz?: boolean }[]; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/directory/tnved', { params: options });\n  }\n\n  /**\n   * Список ярлыков\n   *\n   * Метод возвращает список и характеристики всех ярлыков продавца для группировки и фильтрации товаров. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getContentTags();\n  console.log(result);\n   */\n  async getContentTags(): Promise<{ data?: unknown; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: unknown; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/tags');\n  }\n\n  /**\n   * Создание ярлыка\n   *\n   * Метод добавляет один ярлык продавца. Можно создать максимум 15 ярлыков для одного продавца. Максимальная длина ярлыка — 15 символов. <br>Созданный ярлык можно получить в общем [списке](/openapi/work-with-products#tag/Yarlyki/paths/~1content~1v2~1tags/get). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createContentTag({});\n  console.log(result);\n   */\n  async createContentTag(data: { color?: string; name?: string }): Promise<ResponseContentError> {\n    return this.client.post<ResponseContentError>('https://content-api.wildberries.ru/content/v2/tag', data);\n  }\n\n  /**\n   * Изменение ярлыка\n   *\n   * Метод заменяет данные ярлыка: имя и цвет. <br>Новые данные можно получить в общем [списке](/openapi/work-with-products#tag/Yarlyki/paths/~1content~1v2~1tags/get). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param id - Числовой ID ярлыка\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.updateContentTag('id-value', {});\n  console.log(result);\n   */\n  async updateContentTag(id: number, data: { color?: string; name?: string }): Promise<ResponseContentError> {\n    return this.client.patch<ResponseContentError>(`https://content-api.wildberries.ru/content/v2/tag/${id}`, data);\n  }\n\n  /**\n   * Удаление ярлыка\n   *\n   * Метод удаляет ярлык из [списка ярлыков](/openapi/work-with-products#tag/Yarlyki/paths/~1content~1v2~1tags/get) продавца. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param id - Числовой ID ярлыка\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.deleteContentTag('id-value');\n  console.log(result);\n   */\n  async deleteContentTag(id: number): Promise<ResponseContentError> {\n    return this.client.delete<ResponseContentError>(`https://content-api.wildberries.ru/content/v2/tag/${id}`);\n  }\n\n  /**\n   * Управление ярлыками в карточке товара\n   *\n   * Метод добавляет или снимает ярлык с карточки товара. К карточке можно добавить максимум 15 ярлыков.<br> При удалении ярлыка из карточки товара он не удаляется из [списка ярлыков](/openapi/work-with-products#tag/Yarlyki/paths/~1content~1v2~1tags/get) продавца. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createNomenclatureLink({});\n  console.log(result);\n   */\n  async createNomenclatureLink(data: { nmID?: number; tagsIDs?: number[] }): Promise<ResponseContentError> {\n    return this.client.post<ResponseContentError>('https://content-api.wildberries.ru/content/v2/tag/nomenclature/link', data);\n  }\n\n  /**\n   * Список карточек товаров\n   *\n   * <div class=\"description_auth\"> Метод доступен по <a href=\"/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token\">токену</a> с категорией <strong>Контент</strong> или <strong>Продвижение</strong> </div> Метод возвращает список созданных карточек товаров. <div class=\"description_important\"> В ответе метода не будет карточек, находящихся в корзине. Получить такие карточки можно через <a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post\">отдельный метод</a>. </div> Чтобы получить **больше 100** карточек товаров, используйте пагинацию: 1. Сделайте первый запрос: <br> <pre style=\"background-color: rgb(38 50 56 / 5%); color: #e53935\"> { \"settings\": { \"cursor\": { \"limit\": 100 }, \"filter\": { \"withPhoto\": -1 } } }</pre> 2. Пройдите в конец полученного списка карточек товаров. 3. Скопируйте из `cursor` две строки: - `\"updatedAt\": \"***\"` - `\"nmID\": ***` 4. Вставьте скопированные строки в параметр запроса `cursor`. 5. Повторите запрос. 6. Повторяйте пункты 2-5, пока поле `total` в ответе не станет меньше чем параметр `limit` в запросе. Это будет означать, что вы получили все карточки. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param data - Request body data\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createCardsList({}, {});\n  console.log(result);\n   */\n  async createCardsList(data: { settings?: { sort?: { ascending?: boolean }; filter?: { withPhoto?: number; textSearch?: string; tagIDs?: number[]; allowedCategoriesOnly?: boolean; objectIDs?: number[]; brands?: string[]; imtID?: number }; cursor?: { limit?: number; updatedAt?: string; nmID?: number } } }, options?: { locale?: string }): Promise<{ cards?: { nmID?: number; imtID?: number; nmUUID?: string; subjectID?: number; subjectName?: string; vendorCode?: string; brand?: string; title?: string; description?: string; needKiz?: boolean; photos?: { big?: string; c246x328?: string; c516x688?: string; square?: string; tm?: string }[]; video?: string; wholesale?: { enabled?: boolean; quantum?: number }; dimensions?: { length?: number; width?: number; height?: number; weightBrutto?: number; isValid?: boolean }; characteristics?: { id?: number; name?: string; value?: unknown }[]; sizes?: { chrtID?: number; techSize?: string; wbSize?: string; skus?: string[] }[]; tags?: { id?: number; name?: string; color?: string }[]; createdAt?: string; updatedAt?: string }[]; cursor?: { updatedAt?: string; nmID?: number; total?: number } }> {\n    return this.client.post<{ cards?: { nmID?: number; imtID?: number; nmUUID?: string; subjectID?: number; subjectName?: string; vendorCode?: string; brand?: string; title?: string; description?: string; needKiz?: boolean; photos?: { big?: string; c246x328?: string; c516x688?: string; square?: string; tm?: string }[]; video?: string; wholesale?: { enabled?: boolean; quantum?: number }; dimensions?: { length?: number; width?: number; height?: number; weightBrutto?: number; isValid?: boolean }; characteristics?: { id?: number; name?: string; value?: unknown }[]; sizes?: { chrtID?: number; techSize?: string; wbSize?: string; skus?: string[] }[]; tags?: { id?: number; name?: string; color?: string }[]; createdAt?: string; updatedAt?: string }[]; cursor?: { updatedAt?: string; nmID?: number; total?: number } }>('https://content-api.wildberries.ru/content/v2/get/cards/list', data, { params: options });\n  }\n\n  /**\n   * Список несозданных карточек товаров с ошибками\n   *\n   * Метод возвращает список карточек товаров ([черновиков](https://seller.wildberries.ru/new-goods/error-cards)), при создании или редактировании которых произошли ошибки, с описанием этих ошибок. <br><br> Данные в ответе возвращаются пакетами `batch`. Один пакет содержит: - все ошибки по одной объединённой карточке товара `imtID` одного запроса при [создании](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post) карточек товаров - все ошибки одного запроса при [создании с присоединением](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post) или [редактировании](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post) карточек товаров <br><br> Чтобы получить более 100 пакетов, используйте пагинацию: 1. Сделайте первый запрос: <br> <pre style=\"background-color: rgb(38 50 56 / 5%); color: #e53935\"> { \"cursor\": { \"limit\": 100 }, \"order\": { \"ascending\": true } }</pre> 2. Скопируйте `\"updatedAt\": \"***\"`,`\"batchUUID\": \"***\" `из `cursor` ответа и вставьте в `cursor` запроса. 3. Повторите запрос. 4. Повторяйте пункты 2 и 3, пока не получите в ответе `\"next\": false`. Это будет означать, что вы получили все пакеты. <div class=\"description_important\"> Чтобы удалить карточку товара из списка, сделайте ещё один запрос на создание, создание с присоединением или редактирование карточки товара с исправленными ошибками </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 10 запросов | 6 секунд | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createErrorList({}, {});\n  console.log(result);\n   */\n  async createErrorList(data: RequestPublicViewerPublicErrorsTableListV2, options?: { locale?: string }): Promise<ResponsePublicViewerPublicErrorsTableListV2> {\n    return this.client.post<ResponsePublicViewerPublicErrorsTableListV2>('https://content-api.wildberries.ru/content/v2/cards/error/list', data, { params: options });\n  }\n\n  /**\n   * Редактирование карточек товаров\n   *\n   * Метод обновляет карточки товаров. Данные для обновления можно получить через [список карточек товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1list/post) и [список карточек товаров в корзине](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post). <div class=\"description_important\"> Карточка товара перезаписывается при обновлении. Поэтому в запросе нужно передать <strong>все</strong> параметры карточки, в том числе те, которые вы не собираетесь обновлять. </div> Нельзя редактировать или удалять баркоды, но можно добавить дополнительный баркод к карточке товара. Параметры `photos`, `video` и `tags` редактировать или удалять через данный метод нельзя.<br> Габариты товаров можно указать только в `сантиметрах`, вес товара с упаковкой — в `килограммах`. <br><br> В одном запросе можно отредактировать максимум 3000 карточек товаров (`nmID`). Максимальный размер запроса 10 Мб.<br> Если ответ `Успешно` (`200`), но какие-то карточки не обновились, проверьте [список несозданных карточек товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 10 запросов | 6 секунд | 5 запросов | </div>\n   *\n   * @param [data] - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createCardsUpdate({});\n  console.log(result);\n   */\n  async createCardsUpdate(data?: { nmID: number; vendorCode: string; brand?: string; title?: string; description?: string; dimensions?: { length?: number; width?: number; height?: number; weightBrutto?: number }; characteristics?: { id: number; value: unknown }[]; sizes: { chrtID?: number; techSize?: string; wbSize?: string; skus?: string[] }[] }[]): Promise<ResponseCardCreate> {\n    return this.client.post<ResponseCardCreate>('https://content-api.wildberries.ru/content/v2/cards/update', data);\n  }\n\n  /**\n   * Объединение и разъединение карточек товаров\n   *\n   * Метод объединяет и разъединяет карточки товаров. Карточки товаров считаются объединёнными, если у них одинаковый `imtID`. <br><br> Для объединения карточек товаров сделайте запрос **с указанием** `imtID`. Можно объединять не более 30 карточек товаров.<br> Для разъединения карточек товаров сделайте запрос **без указания** `imtID`. Для разъединенных карточек будут сгенерированы новые `imtID`. <br><br> Если вы разъедините одновременно несколько карточек товаров, эти карточки объединятся в одну и получат новый `imtID`.<br> Чтобы присвоить каждой карточке товара уникальный `imtID`, необходимо передавать по одной карточке товара за запрос.<br> <br> Максимальный размер запроса 10 Мб. <div class=\"description_important\"> Объединить можно только карточки товаров с одинаковыми предметами. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param [data] - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createCardsMovenm({});\n  console.log(result);\n   */\n  async createCardsMovenm(data?: RequestMoveNmsImtConn | RequestMoveNmsImtDisconn): Promise<ResponseCardCreate> {\n    return this.client.post<ResponseCardCreate>('https://content-api.wildberries.ru/content/v2/cards/moveNm', data);\n  }\n\n  /**\n   * Перенос карточек товаров в корзину\n   *\n   * Метод переносит [карточки товаров в корзину](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post). При этом карточки товаров не удаляются, их можно [восстановить](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1recover/post). <div class=\"description_important\"> После переноса в корзину карточке товара присваивается новый <code>imtID</code>. </div> Карточки товаров удаляются автоматически, если лежат в корзине больше 30 дней. Очистка корзины происходит каждую ночь по московскому времени.<br> Карточки товаров можно удалить в любое время в [личном кабинете](https://seller.wildberries.ru/new-goods/basket-cards). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createDeleteTrash({});\n  console.log(result);\n   */\n  async createDeleteTrash(data: { nmIDs?: number[] }): Promise<{ data?: Record<string, never>; error?: boolean; errorText?: string; additionalErrors?: Record<string, never> }> {\n    return this.client.post<{ data?: Record<string, never>; error?: boolean; errorText?: string; additionalErrors?: Record<string, never> }>('https://content-api.wildberries.ru/content/v2/cards/delete/trash', data);\n  }\n\n  /**\n   * Восстановление карточек товаров из корзины\n   *\n   * Метод восстанавливает [карточки товаров из корзины](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post). <div class=\"description_important\"> Карточка товара сохраняет тот же <code>imtID</code>, что был присвоен ей при <a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1delete~1trash/post\">перемещении в корзину</a>. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createCardsRecover({});\n  console.log(result);\n   */\n  async createCardsRecover(data: { nmIDs?: number[] }): Promise<{ data?: Record<string, never>; error?: boolean; errorText?: string; additionalErrors?: Record<string, never> }> {\n    return this.client.post<{ data?: Record<string, never>; error?: boolean; errorText?: string; additionalErrors?: Record<string, never> }>('https://content-api.wildberries.ru/content/v2/cards/recover', data);\n  }\n\n  /**\n   * Список карточек товаров в корзине\n   *\n   * <div class=\"description_auth\"> Метод доступен по <a href=\"/openapi/api-information#tag/Avtorizaciya/Kak-sozdat-token\">токену</a> с категорией <strong>Контент</strong> или <strong>Продвижение</strong> </div> Метод возвращает список карточек товаров в корзине.<br><br> Чтобы получить **больше 100** карточек товаров, воспользуйтесь пагинацией: 1. Сделайте первый запрос: <br> <pre style=\"background-color: rgb(38 50 56 / 5%); color: #e53935\"> { \"settings\": { \"cursor\": { \"limit\": 100 }, \"filter\": { \"withPhoto\": -1 } } }</pre> 2. Пройдите в конец полученного списка карточек товаров. 3. Скопируйте из `cursor` две строки: - `\"trashedAt\": \"***\"` - `\"nmID\": ***` 4. Вставьте скопированные строки в параметр запроса `cursor`. 5. Повторите запрос. 6. Повторяйте пункты 2-5, пока поле `total` в ответе не станет меньше чем параметр `limit` в запросе. Это будет означать, что вы получили все карточки. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param data - Request body data\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createCardsTrash({}, {});\n  console.log(result);\n   */\n  async createCardsTrash(data: { settings?: { sort?: { ascending?: boolean }; cursor?: { limit?: number; trashedAt?: string; nmID?: number }; filter?: { textSearch?: string } } }, options?: { locale?: 'ru' | 'en' | 'zh' }): Promise<{ cards?: { nmID?: number; vendorCode?: string; subjectID?: number; subjectName?: string; photos?: { big?: string; c246x328?: string; c516x688?: string; square?: string; tm?: string }[]; video?: string; wholesale?: { enabled?: boolean; quantum?: number }; sizes?: { chrtID?: number; techSize?: string; wbSize?: string; skus?: string[] }[]; dimensions?: { length?: number; width?: number; height?: number; weightBrutto?: number; isValid?: boolean }; characteristics?: { id?: number; name?: string; value?: unknown }[]; createdAt?: string; trashedAt?: string }[]; cursor?: { trashedAt?: string; nmID?: number; total?: number } }> {\n    return this.client.post<{ cards?: { nmID?: number; vendorCode?: string; subjectID?: number; subjectName?: string; photos?: { big?: string; c246x328?: string; c516x688?: string; square?: string; tm?: string }[]; video?: string; wholesale?: { enabled?: boolean; quantum?: number }; sizes?: { chrtID?: number; techSize?: string; wbSize?: string; skus?: string[] }[]; dimensions?: { length?: number; width?: number; height?: number; weightBrutto?: number; isValid?: boolean }; characteristics?: { id?: number; name?: string; value?: unknown }[]; createdAt?: string; trashedAt?: string }[]; cursor?: { trashedAt?: string; nmID?: number; total?: number } }>('https://content-api.wildberries.ru/content/v2/get/cards/trash', data, { params: options });\n  }\n\n  /**\n   * Лимиты карточек товаров\n   *\n   * Возвращает бесплатные и платные лимиты продавца на [создание карточек товаров](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post).<br><br> Формула для получения количества карточек, которые можно создать: > (`freeLimits` + `paidLimits`) - количество созданных карточек Созданными считаются карточки, которые можно получить через методы [список карточек товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1list/post) и [список карточек товаров в корзине](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1trash/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getCardsLimits();\n  console.log(result);\n   */\n  async getCardsLimits(): Promise<{ data?: { freeLimits?: number; paidLimits?: number }; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.get<{ data?: { freeLimits?: number; paidLimits?: number }; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/cards/limits');\n  }\n\n  /**\n   * Генерация баркодов\n   *\n   * Метод генерирует массив уникальных баркодов для создания размера в [карточке товара](/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post). Можно использовать, если у вас нет собственных баркодов. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createContentBarcodes({});\n  console.log(result);\n   */\n  async createContentBarcodes(data: { count?: number }): Promise<{ data?: string[]; error?: boolean; errorText?: string; additionalErrors?: string }> {\n    return this.client.post<{ data?: string[]; error?: boolean; errorText?: string; additionalErrors?: string }>('https://content-api.wildberries.ru/content/v2/barcodes', data);\n  }\n\n  /**\n   * Создание карточек товаров\n   *\n   * Метод создаёт карточки товаров c указанием описаний и характеристик товаров.<br> <div class=\"description_important\"> Есть две формы запроса: для создания отдельных и объединённых карточек товаров. </div> Габариты товаров можно указать только в `сантиметрах`, вес товара с упаковкой — в `килограммах`. <br><br> Создание карточки товара происходит асинхронно. После отправки запрос становится в очередь на обработку.<br> В одном запросе можно создать максимум 100 объединённых карточек товаров (`imtID`), по 30 карточек товаров в каждой. Максимальный размер запроса 10 Мб.<br> Если ответ `Успешно` (`200`), но какие-то карточки не создались, проверьте [список несозданных карточек товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 10 запросов | 6 секунд | 5 запросов | </div>\n   *\n   * @param [data] - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createCardsUpload({});\n  console.log(result);\n   */\n  async createCardsUpload(data?: { subjectID: number; variants: { brand?: string; title?: string; description?: string; vendorCode: string; wholesale?: { enabled?: boolean; quantum?: number }; dimensions?: { length?: number; width?: number; height?: number; weightBrutto?: number }; sizes?: { techSize?: string; wbSize?: string; price?: number; skus?: string[] }[]; characteristics?: { id: number; value: unknown }[] }[] }[]): Promise<ResponseCardCreate> {\n    return this.client.post<ResponseCardCreate>('https://content-api.wildberries.ru/content/v2/cards/upload', data);\n  }\n\n  /**\n   * Создание карточек товаров с присоединением\n   *\n   * Метод создаёт новые карточки товаров, присоединяя их к существующим карточкам. <br><br> Габариты товаров можно указать только в `сантиметрах`, вес товара с упаковкой — в `килограммах`. <br><br> Создание карточки товара происходит асинхронно. После отправки запрос становится в очередь на обработку.<br>Максимальный размер запроса 10 Мб.<br> Если ответ `Успешно` (`200`), но какие-то карточки не создались, проверьте [список несозданных карточек товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 10 запросов | 6 секунд | 5 запросов | </div>\n   *\n   * @param [data] - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createUploadAdd({});\n  console.log(result);\n   */\n  async createUploadAdd(data?: { imtID?: number; cardsToAdd?: { brand?: string; vendorCode: string; wholesale?: { enabled?: boolean; quantum?: number }; title?: string; description?: string; dimensions?: { length?: number; width?: number; height?: number; weightBrutto?: number }; sizes?: { techSize?: string; wbSize?: string; price?: number; skus?: string[] }[]; characteristics?: { id: number; value: unknown }[] }[] }): Promise<ResponseCardCreate> {\n    return this.client.post<ResponseCardCreate>('https://content-api.wildberries.ru/content/v2/cards/upload/add', data);\n  }\n\n  /**\n   * Загрузить медиафайл\n   *\n   * Метод загружает и добавляет один медиафайл к карточке товара. Требования к изображениям: * максимум изображений для одной карточки товара — 30 * минимальное разрешение — 700x900 px * максимальный размер — 32 Мб * минимальное качество — 65% * форматы — JPG, PNG, BMP, GIF (статичные), WebP Требования к видео: * максимум одно видео для одной карточки товара * максимальный размер — 50 Мб * форматы — MOV, MP4 <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createMediaFile();\n  console.log(result);\n   */\n  async createMediaFile(): Promise<{ data?: Record<string, never>; error?: boolean; errorText?: string; additionalErrors?: Record<string, never> }> {\n    return this.client.post<{ data?: Record<string, never>; error?: boolean; errorText?: string; additionalErrors?: Record<string, never> }>('https://content-api.wildberries.ru/content/v3/media/file', undefined);\n  }\n\n  /**\n   * Загрузить медиафайлы по ссылкам\n   *\n   * Метод загружает набор медиафайлов в карточку товара через указание ссылок в запросе. <div class=\"description_important\"> Новые медиафайлы полностью заменяют старые. Чтобы добавить новые медиафайлы, укажите в запросе ссылки одновременно на новые и старые медиафайлы. </div> Требования к ссылкам: * ссылка должна вести прямо на файл. Убедитесь, что ссылка не ведёт на страницу предпросмотра или авторизации, например. Если по ссылке открывается текстовая страница TXT или HTML, ссылка считается некорректной * для доступа к файлу по ссылке не нужна авторизация Требования к изображениям: * максимум изображений для одной карточки товара — 30 * минимальное разрешение — 700×900 px * максимальный размер — 32 Мб * минимальное качество — 65% * форматы — JPG, PNG, BMP, GIF (статичные), WebP Требования к видео: * максимум одно видео для одной карточки товара * максимальный размер — 50 Мб * форматы — MOV, MP4 Если видео или хотя бы одно изображение в запросе не соответствует требованиям, то даже при успешном ответе (`200`) ни одно изображение/видео не загрузится. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Контент</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 100 запросов | 600 миллисекунд | 5 запросов | Исключение — методы: <ul> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload/post\">создания карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov/paths/~1content~1v2~1cards~1upload~1add/post\">создания карточек товаров с присоединением</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1update/post\">редактирования карточек товаров</a></li> <li><a href=\"/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1cards~1error~1list/post\">получения несозданных карточек товаров с ошибками</a></li> </ul> </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createMediaSave({});\n  console.log(result);\n   */\n  async createMediaSave(data: { nmId?: number; data?: string[] }): Promise<{ data?: Record<string, never>; error?: boolean; errorText?: string; additionalErrors?: Record<string, never> }> {\n    return this.client.post<{ data?: Record<string, never>; error?: boolean; errorText?: string; additionalErrors?: Record<string, never> }>('https://content-api.wildberries.ru/content/v3/media/save', data);\n  }\n\n  /**\n   * Установить цены и скидки\n   *\n   * Метод устанавливает цены и скидки для товаров. <br><br> Чтобы установить цены для размеров товара, используйте [отдельный метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post). <div class=\"description_important\"> Получить информацию о процессе установки цен и скидок можно с помощью методов <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get\">состояния</a> и <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1goods~1task/get\">детализации</a> обработанной загрузки. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createUploadTask();\n  console.log(result);\n   */\n  async createUploadTask(): Promise<unknown> {\n    return this.client.post<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/upload/task', undefined);\n  }\n\n  /**\n   * Установить цены для размеров\n   *\n   * Метод устанавливает цены отдельно для размеров товаров. Работает только для товаров из категорий, где можно устанавливать цены отдельно для разных размеров. Для [таких товаров](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1size~1nm/get) `\"editableSizePrice\":true`. Чтобы установить цены и скидки для самих товаров, используйте [отдельный метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task/post). <div class=\"description_important\"> Получить информацию о процессе установки цен и скидок можно с помощью методов <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get\">состояния</a> и <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1goods~1task/get\">детализации</a> обработанной загрузки. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createTaskSize();\n  console.log(result);\n   */\n  async createTaskSize(): Promise<unknown> {\n    return this.client.post<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/upload/task/size', undefined);\n  }\n\n  /**\n   * Установить скидки WB Клуба\n   *\n   * Устанавливает скидки для товаров в рамках подписки [WB Клуб](https://seller.wildberries.ru/help-center/article/A-337). <div class=\"description_important\"> Получить информацию о процессе установки цен и скидок можно с помощью методов <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get\">состояния</a> и <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1goods~1task/get\">детализации</a> обработанной загрузки. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createTaskClubDiscount();\n  console.log(result);\n   */\n  async createTaskClubDiscount(): Promise<unknown> {\n    return this.client.post<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/upload/task/club-discount', undefined);\n  }\n\n  /**\n   * Состояние обработанной загрузки\n   *\n   * Метод возвращает информацию об обработанной загрузке цен и скидок. <div class=\"description_important\"> Обработанная загрузка — это загрузка цен и скидок для <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task/post\">товаров</a>, цен для <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post\">размеров товаров</a> и скидок <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post\">WB Клуба</a>. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getHistoryTasks();\n  console.log(result);\n   */\n  async getHistoryTasks(): Promise<unknown> {\n    return this.client.get<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/history/tasks');\n  }\n\n  /**\n   * Детализация обработанной загрузки\n   *\n   * Метод возвращает информацию о товарах и об ошибках в товарах в обработанной загрузке. <div class=\"description_important\"> Обработанная загрузка — это загрузка цен и скидок для <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task/post\">товаров</a>, цен для <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post\">размеров товаров</a> и скидок <a href=\"/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post\">WB Клуба</a>. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getGoodsTask();\n  console.log(result);\n   */\n  async getGoodsTask(): Promise<unknown> {\n    return this.client.get<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/history/goods/task');\n  }\n\n  /**\n   * Состояние необработанной загрузки\n   *\n   * Метод возвращает информацию про загрузку скидок в обработке. <div class=\"description_important\"> Необработанная загрузка — это загрузка скидок в <a href=\"/openapi/promotion#tag/Kalendar-akcij\">календаре акций</a>. Такие скидки применятся к товарам только в момент старта акции. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getBufferTasks();\n  console.log(result);\n   */\n  async getBufferTasks(): Promise<unknown> {\n    return this.client.get<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/buffer/tasks');\n  }\n\n  /**\n   * Детализация необработанной загрузки\n   *\n   * Метод возвращает информацию о товарах и ошибках в товарах из загрузки в обработке. <div class=\"description_important\"> Необработанная загрузка — это загрузка скидок в <a href=\"/openapi/promotion#tag/Kalendar-akcij\">календаре акций</a>. Такие скидки применятся к товарам только в момент старта акции. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getGoodsTask();\n  console.log(result);\n   */\n  async getGoodsTask2(): Promise<unknown> {\n    return this.client.get<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/buffer/goods/task');\n  }\n\n  /**\n   * Получить товары с ценами\n   *\n   * Метод возвращает информацию о товарах: цены, валюту, общие скидки и скидки [WB Клуба](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post). <br><br> В одном запросе можно указать только один артикул. <br><br> Чтобы получить информацию обо всех товарах продавца, не указывая артикулы, установите `limit=1000`, в параметре `offset` установите смещение по количеству записей. Количество нужно рассчитать по формуле: `offset` плюс `limit` из предыдущего запроса. Повторяйте запрос, пока вы не получите ответ с пустым массивом.<br><br> Используйте отдельные методы, чтобы получить информацию: - о [нескольких товарах по артикулам](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1filter/post) - о [размерах товара](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1size~1nm/get) <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getGoodsFilter();\n  console.log(result);\n   */\n  async getGoodsFilter(): Promise<unknown> {\n    return this.client.get<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/list/goods/filter');\n  }\n\n  /**\n   * Получить товары с ценами по артикулам\n   *\n   * Метод возвращает информацию о товарах по их артикулам: цены, валюту, общие скидки и скидки [WB Клуба](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post). <br><br> В одном запросе можно указать более одного артикула. <br><br> Используйте отдельные методы, чтобы получить информацию: - обо [всех товарах продавца, не указывая артикулы](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1filter/get) - о [размерах товара](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1size~1nm/get) <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createGoodsFilter();\n  console.log(result);\n   */\n  async createGoodsFilter(): Promise<unknown> {\n    return this.client.post<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/list/goods/filter', undefined);\n  }\n\n  /**\n   * Получить размеры товара с ценами\n   *\n   * Метод возвращает информацию обо всех размерах одного товара: цены, валюту, общие скидки и скидки для [WB Клуба](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1club-discount/post). <br><br> Работает только для товаров из категорий, где можно устанавливать цены отдельно для разных размеров. Для таких товаров `\"editableSizePrice\":true`. <br><br> Чтобы получить информацию о самом товаре, используйте [отдельный метод](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1list~1goods~1filter/get). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getSizeNm();\n  console.log(result);\n   */\n  async getSizeNm(): Promise<unknown> {\n    return this.client.get<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/list/goods/size/nm');\n  }\n\n  /**\n   * Получить товары в карантине\n   *\n   * Метод возвращает информацию о товарах в карантине. <br><br> Если новая цена товара со скидкой будет минимум в 3 раза меньше старой, товар попадёт в [карантин](https://seller.wildberries.ru/instructions/ru/ru/material/price-quarantine) и будет продаваться по старой цене. Ошибка об этом будет в ответах методов [состояний загрузок](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get). <br><br> Вы можете изменить цену или скидку с помощью API либо вывести товар из карантина в [личном кабинете](https://seller.wildberries.ru/discount-and-prices/quarantine). <br><br> Для товаров с [поразмерной установкой цен](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1upload~1task~1size/post) карантин не применяется. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Цены и скидки</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getQuarantineGoods();\n  console.log(result);\n   */\n  async getQuarantineGoods(): Promise<unknown> {\n    return this.client.get<unknown>('https://discounts-prices-api.wildberries.ru/api/v2/quarantine/goods');\n  }\n\n  /**\n   * Получить остатки товаров\n   *\n   * Метод возвращает данные об остатках товаров на [складах продавца](/openapi/work-with-products#tag/Sklady-prodavca). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов <strong>остатков на складах продавца</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | Один запрос с кодом ответа <code>409</code> учитывается как 5 запросов </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createStock({});\n  console.log(result);\n   */\n  async createStock(data: { skus: string[] }): Promise<{ stocks?: { sku?: string; amount?: number }[] }> {\n    return this.client.post<{ stocks?: { sku?: string; amount?: number }[] }>('https://marketplace-api.wildberries.ru/api/v3/stocks/{warehouseId}', data);\n  }\n\n  /**\n   * Обновить остатки товаров\n   *\n   * Метод обновляет количество остатков товаров продавца [в списке](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post). <div class=\"description_important\"> Названия параметров запроса не валидируются. При отправке некорректных названий вы получите успешный ответ (<code>204</code>), но остатки не обновятся. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов <strong>остатков на складах продавца</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | Один запрос с кодом ответа <code>409</code> учитывается как 5 запросов </div>\n   *\n   * @param [data] - Request body data\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.updateStock({});\n   */\n  async updateStock(data?: { stocks: { sku?: string; amount?: number }[] }): Promise<void> {\n    return this.client.put('https://marketplace-api.wildberries.ru/api/v3/stocks/{warehouseId}', data);\n  }\n\n  /**\n   * Удалить остатки товаров\n   *\n   * Метод удаляет запись об остатках товаров продавца из [списка остатков](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post). <div class=\"description_important\"> <strong>Действие необратимо</strong>. Удаленный остаток будет необходимо загрузить повторно для возобновления продаж. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов <strong>остатков на складах продавца</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | Один запрос с кодом ответа <code>409</code> учитывается как 5 запросов </div>\n   *\n   * @param data - Request body data\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.deleteStock({});\n   */\n  async deleteStock(data: { skus?: string[] }): Promise<void> {\n    return this.client.delete('https://marketplace-api.wildberries.ru/api/v3/stocks/{warehouseId}', data);\n  }\n\n  /**\n   * Получить список складов WB\n   *\n   * Метод возвращает список всех складов WB для привязки к складам продавца. Предназначен для определения складов WB, чтобы сдавать готовые заказы по модели [FBS](/openapi/orders-fbs#tag/Zakazy-FBS) (Fulfillment by Seller). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов <strong>складов продавца</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | Один запрос с кодом ответа <code>409</code> учитывается как 5 запросов </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.offices();\n  console.log(result);\n   */\n  async offices(): Promise<Office[]> {\n    return this.client.get<Office[]>('https://marketplace-api.wildberries.ru/api/v3/offices');\n  }\n\n  /**\n   * Получить список складов продавца\n   *\n   * Метод возвращает список всех складов продавца. Может использоваться для получения [остатков товаров](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов <strong>складов продавца</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | Один запрос с кодом ответа <code>409</code> учитывается как 5 запросов </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.warehouses();\n  console.log(result);\n   */\n  async warehouses(): Promise<Warehouse[]> {\n    return this.client.get<Warehouse[]>('https://marketplace-api.wildberries.ru/api/v3/warehouses');\n  }\n\n  /**\n   * Создать склад продавца\n   *\n   * Метод создаёт склад продавца для работы с [остатками товаров](/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca/paths/~1api~1v3~1stocks~1%7BwarehouseId%7D/post). Нужно привязать к складу продавца [склад WB](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1offices/get) для работы по модели [FBS](/openapi/orders-fbs#tag/Zakazy-FBS) (Fulfillment by Seller). <div class=\"description_important\"> Нельзя привязывать склад WB, который уже используется </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов <strong>складов продавца</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | Один запрос с кодом ответа <code>409</code> учитывается как 5 запросов </div>\n   *\n   * @param data - Request body data\n   * @returns Создано\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.createWarehouses({});\n  console.log(result);\n   */\n  async createWarehouses(data: { name: string; officeId: number }): Promise<{ id?: number }> {\n    return this.client.post<{ id?: number }>('https://marketplace-api.wildberries.ru/api/v3/warehouses', data);\n  }\n\n  /**\n   * Обновить склад продавца\n   *\n   * Метод обновляет данные склада продавца в [списке складов](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1warehouses/get). Данные о привязанном [складе WB](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1offices/get) можно изменить один раз в сутки. <div class=\"description_important\"> Нельзя привязывать склад WB, который уже используется </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов <strong>складов продавца</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | Один запрос с кодом ответа <code>409</code> учитывается как 5 запросов </div>\n   *\n   * @param data - Request body data\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.updateWarehous({});\n   */\n  async updateWarehous(data: { name: string; officeId: number }): Promise<void> {\n    return this.client.put('https://marketplace-api.wildberries.ru/api/v3/warehouses/{warehouseId}', data);\n  }\n\n  /**\n   * Удалить склад продавца\n   *\n   * Метод удаляет склад продавца из [списка складов](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1warehouses/get). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов <strong>складов продавца</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | Один запрос с кодом ответа <code>409</code> учитывается как 5 запросов </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.deleteWarehous();\n   */\n  async deleteWarehous(): Promise<void> {\n    return this.client.delete('https://marketplace-api.wildberries.ru/api/v3/warehouses/{warehouseId}');\n  }\n\n  /**\n   * Список контактов\n   *\n   * Метод возвращает список контактов, привязанных к [складу продавца](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1warehouses/get). <br> Только для складов с типом доставки `3` — доставка курьером WB (DBW). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для следующих методов DBW: <ul> <li>получение и обновление списка контактов</li> <li>получение и удаление метаданных</li> <li>методы сборочных заданий</li> </ul> | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.getWarehousesContact();\n  console.log(result);\n   */\n  async getWarehousesContact(): Promise<{ contacts?: { comment?: string; phone?: string }[] }> {\n    return this.client.get<{ contacts?: { comment?: string; phone?: string }[] }>('https://marketplace-api.wildberries.ru/api/v3/dbw/warehouses/{warehouseId}/contacts');\n  }\n\n  /**\n   * Обновить список контактов\n   *\n   * Метод обновляет список контактов [склада продавца](/openapi/work-with-products#tag/Sklady-prodavca/paths/~1api~1v3~1warehouses/get). <div class=\"description_important\"> Список контактов перезаписывается при обновлении. Поэтому в запросе нужно передать <strong>все</strong> параметры списка контактов, в том числе те, которые вы не собираетесь обновлять. </div> Только для складов с типом доставки `3` — курьером WB (DBW). <br><br> К складу можно добавить максимум 5 контактов. Чтобы удалить контакты, отправьте пустой массив `contacts`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для следующих методов DBW: <ul> <li>получение и обновление списка контактов</li> <li>получение и удаление метаданных</li> <li>методы сборочных заданий</li> </ul> | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 300 запросов | 200 миллисекунд | 20 запросов | </div>\n   *\n   * @param data - Request body data\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.general.updateWarehousesContact({});\n   */\n  async updateWarehousesContact(data: StoreContactRequestBody): Promise<void> {\n    return this.client.put('https://marketplace-api.wildberries.ru/api/v3/dbw/warehouses/{warehouseId}/contacts', data);\n  }\n\n  // ============================================================================\n  // User-Friendly CRUD Operations\n  // ============================================================================\n  // These methods provide better naming and documentation for common operations.\n  // They wrap the auto-generated methods above with improved developer experience.\n\n  /**\n   * Create new product cards with descriptions and characteristics\n   *\n   * Creates product cards in the Wildberries marketplace catalog. This operation\n   * is processed **asynchronously** - a 200 OK response means the request was queued,\n   * not that products were created successfully.\n   *\n   * **Important Notes:**\n   * - Request is queued for async processing\n   * - Check error list endpoint if 200 OK but some cards fail: `/content/v2/cards/error/list`\n   * - Dimensions in centimeters, weight in kilograms\n   * - Barcodes auto-generated if not provided\n   *\n   * **Limits:**\n   * - Max 100 unified cards (imtID) per request\n   * - Max 30 cards per imtID\n   * - Max 10MB request size\n   *\n   * **Rate Limit:** 10 requests/min, 6 second interval\n   *\n   * @param data - Product creation request with subjectID and variants\n   * @returns Promise with creation response (check error field for failures)\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429) - automatically retried\n   * @throws {ValidationError} When required fields missing (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * import { WildberriesSDK } from 'daytona-wildberries-typescript-sdk';\n   *\n   * const sdk = new WildberriesSDK({ apiKey: 'your-api-key' });\n   *\n   * // Create a complete product card\n   * const result = await sdk.products.createProduct({\n   *   subjectID: 105,  // Category ID from getCategories\n   *   variants: [{\n   *     vendorCode: 'VENDOR-001',  // Required: Your article ID\n   *     brand: 'My Brand',\n   *     title: 'Example Product',\n   *     description: 'Detailed product description (1000-5000 chars)...',\n   *     dimensions: {\n   *       length: 10,        // cm\n   *       width: 5,          // cm\n   *       height: 2,         // cm\n   *       weightBrutto: 0.5  // kg\n   *     },\n   *     sizes: [{\n   *       techSize: 'XL',\n   *       wbSize: '52',\n   *       skus: ['1234567890123']  // Barcode (auto-generated if omitted)\n   *     }],\n   *     characteristics: [\n   *       { id: 1, value: ['Red'] },     // From getCharacteristics\n   *       { id: 2, value: ['Cotton'] }\n   *     ]\n   *   }]\n   * });\n   *\n   * if (result.error) {\n   *   console.error('Creation failed:', result.errorText);\n   *   // Check /content/v2/cards/error/list for details\n   * } else {\n   *   console.log('Product queued for creation');\n   * }\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Sozdanie-kartochek-tovarov}\n   */\n  async createProduct(data: CreateProductRequest): Promise<CreateProductResponse> {\n    return this.client.post<CreateProductResponse>(\n      'https://content-api.wildberries.ru/content/v2/cards/upload',\n      [data],\n      { rateLimitKey: 'products.postContentCardsUpload' }\n    );\n  }\n\n  /**\n   * Get list of product cards with filtering and cursor-based pagination\n   *\n   * Returns product cards from your catalog with optional filters and pagination.\n   * For large catalogs (>100 products), use cursor-based pagination with updatedAt and nmID.\n   *\n   * **Important Notes:**\n   * - Excludes products in trash (use createCardsTrash to get those)\n   * - Cursor-based pagination for >100 products\n   * - Max 100 products per page\n   * - **When called without parameters, returns only the first page (up to 100 products)**\n   * - For large catalogs (>100 products), use `getAllProducts()` helper method or implement pagination manually\n   *\n   * **Rate Limit:** 100 requests/min, 600ms interval\n   *\n   * @param filters - Optional filtering and pagination parameters. If omitted, returns first page only (up to 100 products).\n   * @returns Promise with product cards array and pagination cursor\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429) - automatically retried\n   * @throws {ValidationError} When filter parameters invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get first page (up to 100 products) - WARNING: For large catalogs, use getAllProducts()\n   * const firstPage = await sdk.products.listProducts();\n   * console.log(`First page: ${firstPage.cards?.length} products`);\n   * console.log(`Total available: ${firstPage.cursor?.total ?? 'unknown'}`);\n   *\n   * // Get first page of products with photos\n   * const page1 = await sdk.products.listProducts({\n   *   filter: {\n   *     withPhoto: 1,              // Only with photos\n   *     brands: ['My Brand']       // Filter by brand\n   *   },\n   *   cursor: { limit: 100 }       // Max 100 per page\n   * });\n   *\n   * console.log(`Found ${page1.cursor?.total} products`);\n   * page1.cards?.forEach(card => {\n   *   console.log(`${card.nmID}: ${card.title}`);\n   * });\n   *\n   * // Get next page using cursor\n   * if (page1.cursor?.updatedAt && page1.cursor?.nmID) {\n   *   const page2 = await sdk.products.listProducts({\n   *     filter: { withPhoto: 1, brands: ['My Brand'] },\n   *     cursor: {\n   *       limit: 100,\n   *       updatedAt: page1.cursor.updatedAt,  // From previous response\n   *       nmID: page1.cursor.nmID             // From previous response\n   *     }\n   *   });\n   *   console.log(`Page 2: ${page2.cards?.length} more products`);\n   * }\n   *\n   * // Search by vendor code or nmID\n   * const searchResult = await sdk.products.listProducts({\n   *   filter: { textSearch: 'VENDOR-001' }\n   * });\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Kartochki-tovarov}\n   */\n  async listProducts(filters?: ProductListRequest): Promise<ProductListResponse> {\n    // Ensure settings object is always sent, even when filters is undefined\n    // API requires settings object in request body\n    return this.client.post<ProductListResponse>(\n      'https://content-api.wildberries.ru/content/v2/get/cards/list',\n      { settings: filters ?? {} },\n      { rateLimitKey: 'products.postContentGetCardsList' }\n    );\n  }\n\n  /**\n   * Get all product cards with automatic pagination\n   *\n   * Automatically handles cursor-based pagination to retrieve all products,\n   * even for large catalogs (>100 products). This method makes multiple API\n   * calls as needed to fetch all pages.\n   *\n   * **Important Notes:**\n   * - Automatically paginates through all pages\n   * - Respects rate limits (100 req/min, 600ms interval)\n   * - For very large catalogs (10,000+ products), this may take several minutes\n   * - Consider using `listProducts()` with manual pagination for better control\n   * - Excludes products in trash (use createCardsTrash to get those)\n   *\n   * **Rate Limit:** 100 requests/min, 600ms interval (automatically handled)\n   *\n   * @param filters - Optional filtering parameters (pagination handled automatically)\n   * @param options - Optional configuration\n   * @param options.maxProducts - Maximum number of products to fetch (default: unlimited). Use to limit large catalogs.\n   * @returns Promise with all product cards array\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429) - automatically retried\n   * @throws {ValidationError} When filter parameters invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get all products (automatically paginates)\n   * const allProducts = await sdk.products.getAllProducts();\n   * console.log(`Total products: ${allProducts.length}`);\n   *\n   * // Get all products with filters\n   * const productsWithPhotos = await sdk.products.getAllProducts({\n   *   filter: { withPhoto: 1 }\n   * });\n   * console.log(`Products with photos: ${productsWithPhotos.length}`);\n   *\n   * // Limit to first 500 products (useful for large catalogs)\n   * const limitedProducts = await sdk.products.getAllProducts(\n   *   { filter: { brands: ['My Brand'] } },\n   *   { maxProducts: 500 }\n   * );\n   * ```\n   *\n   * @see {@link listProducts} For manual pagination control\n   */\n  async getAllProducts(\n    filters?: Omit<ProductListRequest, 'cursor'>,\n    options?: { maxProducts?: number }\n  ): Promise<ProductCard[]> {\n    const allCards: ProductCard[] = [];\n    const maxProducts = options?.maxProducts;\n    let cursor: ProductListCursor | undefined = { limit: 100 };\n    let pageCount = 0;\n\n    // Build base request (without cursor, we'll add it per page)\n    const baseRequest: ProductListRequest = {\n      ...filters,\n      cursor,\n    };\n\n    // Paginate through all pages\n    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, no-constant-condition\n    while (true) {\n      // Check if we've reached the limit\n      if (maxProducts !== undefined && allCards.length >= maxProducts) {\n        break;\n      }\n\n      // Make request with current cursor\n      const response = await this.listProducts(baseRequest);\n\n      // Add cards from this page\n      if (response.cards && response.cards.length > 0) {\n        allCards.push(...response.cards);\n\n        // Check if we've reached the limit after adding this page\n        if (maxProducts !== undefined && allCards.length >= maxProducts) {\n          // Trim to exact limit\n          allCards.splice(maxProducts);\n          break;\n        }\n      }\n\n      // Check if there are more pages\n      const total = response.cursor?.total ?? 0;\n      const cursorData = response.cursor;\n      const hasMore =\n        Boolean(cursorData?.updatedAt) &&\n        Boolean(cursorData?.nmID) &&\n        allCards.length < total;\n\n      if (!hasMore) {\n        // No more pages or we've got everything\n        break;\n      }\n\n      // Update cursor for next page\n      // We know cursorData exists and has updatedAt/nmID from hasMore check above\n      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n      if (cursorData?.updatedAt && cursorData?.nmID) {\n        cursor = {\n          limit: 100,\n          updatedAt: cursorData.updatedAt,\n          nmID: cursorData.nmID,\n        };\n        baseRequest.cursor = cursor;\n      } else {\n        break;\n      }\n\n      pageCount++;\n\n      // Safety check: prevent infinite loops\n      if (pageCount > 1000) {\n        // This would be 100,000+ products, something is wrong\n        throw new Error(\n          'Pagination exceeded 1000 pages. Possible infinite loop or API issue.'\n        );\n      }\n    }\n\n    return allCards;\n  }\n\n  /**\n   * Update existing product cards\n   *\n   * **CRITICAL WARNING:** This endpoint **completely replaces** the product card.\n   * You MUST send ALL parameters, even unchanged ones. Missing fields will be removed!\n   *\n   * **Workflow:**\n   * 1. Get current product: `const product = await sdk.products.getProductCard(nmID)`\n   * 2. Modify desired fields: `product.title = 'New Title'`\n   * 3. Send ALL fields: `await sdk.products.updateProduct([product])`\n   *\n   * **Important Notes:**\n   * - Request processed asynchronously (check error list if needed)\n   * - Cannot edit: barcodes, photos, video, tags (use separate endpoints)\n   * - Can add: additional barcodes to existing products\n   * - Sizes require chrtID for existing sizes\n   *\n   * **Limits:**\n   * - Max 3000 cards per request\n   * - Max 10MB request size\n   *\n   * **Rate Limit:** 10 requests/min, 6 second interval\n   *\n   * @param data - Array of update requests (each with ALL product fields)\n   * @returns Promise with update response (check error field for failures)\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429) - automatically retried\n   * @throws {ValidationError} When required fields missing (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // GOOD: Get product first, then update with all fields\n   * const product = await sdk.products.getProductCard(12345);\n   * if (product) {\n   *   const updateRequest: UpdateProductRequest = {\n   *     nmID: product.nmID!,\n   *     vendorCode: product.vendorCode!,\n   *     sizes: product.sizes?.map(s => ({\n   *       chrtID: s.chrtID,      // Required for existing sizes\n   *       techSize: s.techSize,\n   *       wbSize: s.wbSize,\n   *       skus: s.skus\n   *     })) || [],\n   *     brand: product.brand,\n   *     title: 'Updated Title',  // Changed field\n   *     description: product.description,  // Keep unchanged\n   *     dimensions: product.dimensions,\n   *     characteristics: product.characteristics?.map(c => ({\n   *       id: c.id!,\n   *       value: c.value\n   *     }))\n   *   };\n   *\n   *   const result = await sdk.products.updateProduct([updateRequest]);\n   *   if (result.error) {\n   *     console.error('Update failed:', result.errorText);\n   *   }\n   * }\n   *\n   * // BAD: Only sending changed field - other fields will be lost!\n   * // await sdk.products.updateProduct([{\n   * //   nmID: 12345,\n   * //   vendorCode: 'VENDOR-001',\n   * //   sizes: [],\n   * //   title: 'Updated Title'  // Other fields missing = they'll be removed!\n   * // }]);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Kartochki-tovarov}\n   */\n  async updateProduct(data: UpdateProductRequest[]): Promise<UpdateProductResponse> {\n    return this.client.post<UpdateProductResponse>(\n      'https://content-api.wildberries.ru/content/v2/cards/update',\n      data,\n      { rateLimitKey: 'products.postContentCardsUpdate' }\n    );\n  }\n\n  /**\n   * Move product cards to trash (soft delete)\n   *\n   * Moves specified product cards to trash. This is a **soft delete** - cards are not\n   * permanently removed and can be recovered using the recover endpoint.\n   *\n   * **Important Notes:**\n   * - Soft delete - cards can be recovered before auto-deletion\n   * - Auto-deleted after 30 days in trash (nightly Moscow time)\n   * - New imtID assigned after moving to trash\n   * - Use createCardsRecover to restore deleted cards\n   *\n   * **Limits:**\n   * - Max 1000 nmIDs per request\n   *\n   * **Rate Limit:** 100 requests/min, 600ms interval\n   *\n   * @param nmIDs - Array of Wildberries article IDs to delete (max 1000)\n   * @returns Promise with delete response\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429) - automatically retried\n   * @throws {ValidationError} When nmIDs array empty or invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Delete single product\n   * await sdk.products.deleteProduct([12345]);\n   *\n   * // Batch delete multiple products\n   * const toDelete = [12345, 12346, 12347];\n   * const result = await sdk.products.deleteProduct(toDelete);\n   *\n   * if (result.error) {\n   *   console.error('Deletion failed:', result.errorText);\n   * } else {\n   *   console.log(`${toDelete.length} products moved to trash`);\n   *   console.log('Auto-deletion in 30 days');\n   *   console.log('Recover before then using createCardsRecover()');\n   * }\n   *\n   * // View products in trash\n   * const trashedProducts = await sdk.products.createCardsTrash({\n   *   settings: { cursor: { limit: 100 } }\n   * });\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Kartochki-tovarov}\n   */\n  async deleteProduct(nmIDs: number[]): Promise<DeleteProductResponse> {\n    return this.client.post<DeleteProductResponse>(\n      'https://content-api.wildberries.ru/content/v2/cards/delete/trash',\n      { nmIDs },\n      { rateLimitKey: 'products.postContentCardsDeleteTrash' }\n    );\n  }\n\n  /**\n   * Get single product card by Wildberries article ID (nmID)\n   *\n   * Convenience method to retrieve a single product card. This wraps listProducts()\n   * with a textSearch filter since the API doesn't provide a direct GET endpoint.\n   *\n   * **Note:** Wildberries API doesn't have a single-product GET endpoint, so this\n   * method searches by nmID and returns the first match.\n   *\n   * **Rate Limit:** 100 requests/min, 600ms interval (same as listProducts)\n   *\n   * @param nmID - Wildberries article ID to retrieve\n   * @returns Promise with product card or null if not found\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429) - automatically retried\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get product by nmID\n   * const product = await sdk.products.getProductCard(12345);\n   *\n   * if (product) {\n   *   console.log('Product found:', product.title);\n   *   console.log('Brand:', product.brand);\n   *   console.log('Vendor Code:', product.vendorCode);\n   *   console.log('Stock:', product.sizes?.length, 'sizes');\n   * } else {\n   *   console.log('Product not found (may be in trash or deleted)');\n   * }\n   *\n   * // Use for updates (get current state first)\n   * const current = await sdk.products.getProductCard(12345);\n   * if (current) {\n   *   await sdk.products.updateProduct([{\n   *     ...current,\n   *     title: 'Updated Title'\n   *   }]);\n   * }\n   * ```\n   */\n  async getProductCard(nmID: number): Promise<ProductCard | null> {\n    const response = await this.listProducts({\n      filter: { textSearch: nmID.toString() }\n    });\n\n    // Find exact match by nmID (textSearch may return multiple results)\n    return response.cards?.find(card => card.nmID === nmID) ?? null;\n  }\n\n  // ============================================================================\n  // Media Management (Story 2.3)\n  // ============================================================================\n\n  /**\n   * Upload single media file to product card\n   *\n   * Upload product images or video using multipart/form-data.\n   * Each request uploads ONE file.\n   *\n   * **Media Requirements:**\n   * - **Images**: Max 30, min 700×900px, max 32MB, min 65% quality\n   * - **Formats**: JPG, PNG, BMP, GIF (static only), WebP\n   * - **Video**: Max 1, max 50MB, formats: MOV, MP4\n   *\n   * **Photo Number Rules:**\n   * - Starts at 1 for first photo\n   * - For video, always use 1\n   * - To add to existing photos, use number > current photo count\n   *\n   * **Rate Limit:** 100 requests/min, 600ms interval\n   *\n   * @param nmID - Wildberries article ID\n   * @param file - File data (Buffer or Blob)\n   * @param photoNumber - Photo position 1-30 (video always 1)\n   * @returns Promise with upload response\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When file invalid or doesn't meet requirements (400)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * import { readFileSync } from 'fs';\n   *\n   * // Upload first product image\n   * const imageBuffer = readFileSync('product-photo.jpg');\n   * await sdk.products.uploadMediaFile(12345, imageBuffer, 1);\n   *\n   * // Upload additional image (photoNumber 2)\n   * const image2 = readFileSync('product-photo-2.jpg');\n   * await sdk.products.uploadMediaFile(12345, image2, 2);\n   *\n   * // Upload video (always photoNumber 1)\n   * const videoBuffer = readFileSync('product-video.mp4');\n   * await sdk.products.uploadMediaFile(12345, videoBuffer, 1);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Media}\n   */\n  async uploadMediaFile(nmID: number, file: Buffer | Blob, photoNumber: number): Promise<MediaUploadResponse> {\n    const formData = new FormData();\n    // Convert Buffer to Blob for FormData compatibility\n    const blob = (file instanceof Buffer ? new Blob([file]) : file) as Blob;\n    formData.append('uploadfile', blob);\n\n    return this.client.post<MediaUploadResponse>(\n      'https://content-api.wildberries.ru/content/v3/media/file',\n      formData,\n      {\n        headers: {\n          'X-Nm-Id': nmID.toString(),\n          'X-Photo-Number': photoNumber.toString(),\n          'Content-Type': 'multipart/form-data'\n        },\n        rateLimitKey: 'products.uploadMediaFile'\n      }\n    );\n  }\n\n  /**\n   * Upload media files to product card via URLs\n   *\n   * **CRITICAL WARNING:** This method **COMPLETELY REPLACES** all existing media.\n   * To add new media, you MUST include both new AND old URLs in the request.\n   *\n   * **All-or-Nothing:** If ANY file fails validation, NONE of the files upload.\n   *\n   * **URL Requirements:**\n   * - Direct file link (not preview/HTML page)\n   * - No authentication required\n   * - Must return file content, not text\n   *\n   * **Media Requirements:**\n   * - Max 30 images + 1 video\n   * - Images: min 700×900px, max 32MB, min 65% quality (JPG/PNG/BMP/GIF/WebP)\n   * - Video: max 50MB (MOV/MP4)\n   *\n   * **Rate Limit:** 100 requests/min, 600ms interval\n   *\n   * @param nmID - Wildberries article ID\n   * @param mediaURLs - Array of media URLs (max 30 images + 1 video)\n   * @returns Promise with upload response\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When URLs invalid or media doesn't meet requirements (400)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // BAD - Loses existing media!\n   * await sdk.products.uploadMediaByURLs(12345, [\n   *   'https://example.com/new-photo.jpg'\n   * ]);\n   *\n   * // GOOD - Preserves existing media\n   * const existingMedia = await sdk.products.getMediaList(12345);\n   * await sdk.products.uploadMediaByURLs(12345, [\n   *   ...existingMedia,                    // Keep old media\n   *   'https://example.com/new-photo.jpg'  // Add new media\n   * ]);\n   *\n   * // Upload complete media set\n   * await sdk.products.uploadMediaByURLs(12345, [\n   *   'https://example.com/product-main.jpg',\n   *   'https://example.com/product-side.jpg',\n   *   'https://example.com/product-back.jpg',\n   *   'https://example.com/product-video.mp4'\n   * ]);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Media}\n   */\n  async uploadMediaByURLs(nmID: number, mediaURLs: string[]): Promise<MediaUploadResponse> {\n    return this.client.post<MediaUploadResponse>(\n      'https://content-api.wildberries.ru/content/v3/media/save',\n      { nmId: nmID, data: mediaURLs },\n      { rateLimitKey: 'products.uploadMediaByURLs' }\n    );\n  }\n\n  /**\n   * Get list of media URLs for a product\n   *\n   * Convenience method that retrieves product card and extracts media URLs.\n   *\n   * **Note:** Wildberries API doesn't have a dedicated media list endpoint,\n   * so this wraps getProductCard() and returns the photos array.\n   *\n   * **Rate Limit:** 100 requests/min, 600ms interval (same as getProductCard)\n   *\n   * @param nmID - Wildberries article ID\n   * @returns Promise with array of media URLs (empty if no media)\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get current media\n   * const mediaURLs = await sdk.products.getMediaList(12345);\n   * console.log(`Product has ${mediaURLs.length} media files`);\n   *\n   * // Add new media while preserving existing\n   * const existing = await sdk.products.getMediaList(12345);\n   * await sdk.products.uploadMediaByURLs(12345, [\n   *   ...existing,\n   *   'https://example.com/new-photo.jpg'\n   * ]);\n   * ```\n   */\n  async getMediaList(nmID: number): Promise<string[]> {\n    const product = await this.getProductCard(nmID);\n    return product?.photos?.map(p => p.big ?? '').filter(Boolean) ?? [];\n  }\n\n  // ============================================================================\n  // Pricing Management (Story 2.3)\n  // ============================================================================\n\n  /**\n   * Set prices and discounts for products (async processing)\n   *\n   * **CRITICAL:** This operation is **asynchronous**. A 200 OK response means the task\n   * was queued, NOT that prices were updated. You must poll `getPricingTaskStatus()`\n   * to verify when pricing changes are applied.\n   *\n   * **Pricing Constraints:**\n   * - Prices must be **integers only** (whole numbers, no decimals)\n   * - Discounts: 0-99%\n   * - Price and discount cannot both be empty\n   *\n   * **Quarantine Warning:**\n   * If new price with discount is ≥3x lower than old price, it goes to\n   * [quarantine](https://seller.wildberries.ru/instructions/ru/ru/material/price-quarantine)\n   * and the old price continues until you fix it.\n   *\n   * **Limits:**\n   * - Max 1000 products per request\n   *\n   * **Rate Limit:** 10 requests per 6 seconds, 600ms interval\n   *\n   * @param updates - Array of pricing updates (max 1000)\n   * @returns Promise with task ID for status polling\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When prices invalid (decimals) or discounts out of range (400)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Update pricing for products\n   * const task = await sdk.products.updatePricing([\n   *   { nmID: 12345, price: 2999, discount: 15 },\n   *   { nmID: 67890, price: 1499, discount: 10 }\n   * ]);\n   *\n   * console.log('Pricing task created:', task.uploadID);\n   *\n   * // Poll task status until complete\n   * let status;\n   * do {\n   *   await new Promise(resolve => setTimeout(resolve, 2000));\n   *   status = await sdk.products.getPricingTaskStatus(task.uploadID);\n   *   console.log('Status:', status.status);\n   * } while (status.status === 'processing');\n   *\n   * if (status.status === 'completed') {\n   *   console.log('Prices updated successfully!');\n   *   const pricing = await sdk.products.getPricing([12345, 67890]);\n   *   console.log('New pricing:', pricing);\n   * }\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Ceny-i-skidki}\n   */\n  async updatePricing(updates: PricingUpdate[]): Promise<PricingTaskResponse> {\n    return this.client.post<PricingTaskResponse>(\n      'https://discounts-prices-api.wildberries.ru/api/v2/upload/task',\n      { data: updates },\n      { rateLimitKey: 'products.updatePricing' }\n    );\n  }\n\n  /**\n   * Get current pricing for one or more products\n   *\n   * Retrieves prices, discounts, promo codes, and WB Club discounts.\n   *\n   * **Note:** Single nmID uses GET, multiple nmIDs use POST (handled automatically).\n   *\n   * **Rate Limit:** 10 requests per 6 seconds\n   *\n   * @param nmIDOrIDs - Single nmID or array of nmIDs\n   * @returns Promise with pricing information array\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get pricing for single product\n   * const pricing = await sdk.products.getPricing(12345);\n   * console.log('Price:', pricing[0].price);\n   * console.log('Discount:', pricing[0].discount, '%');\n   *\n   * // Get pricing for multiple products\n   * const bulkPricing = await sdk.products.getPricing([12345, 67890]);\n   * bulkPricing.forEach(p => {\n   *   console.log(`Product ${p.nmID}: ${p.price} ${p.currency}`);\n   *   const finalPrice = p.price * (1 - p.discount / 100);\n   *   console.log(`  Final price: ${finalPrice.toFixed(2)}`);\n   * });\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Ceny-i-skidki}\n   */\n  async getPricing(nmIDOrIDs: number | number[]): Promise<PricingInfo[]> {\n    if (Array.isArray(nmIDOrIDs)) {\n      // POST for multiple products\n      const response = await this.client.post<GetPricingResponse>(\n        'https://discounts-prices-api.wildberries.ru/api/v2/list/goods/filter',\n        { nmIDs: nmIDOrIDs },\n        { rateLimitKey: 'products.getPricing' }\n      );\n      return response.data;\n    } else {\n      // GET for single product\n      const response = await this.client.get<GetPricingResponse>(\n        'https://discounts-prices-api.wildberries.ru/api/v2/list/goods/filter',\n        {\n          params: { filterNmID: nmIDOrIDs },\n          rateLimitKey: 'products.getPricing'\n        }\n      );\n      return response.data;\n    }\n  }\n\n  /**\n   * Get status of pricing update task\n   *\n   * Poll this endpoint after `updatePricing()` to check if prices were applied.\n   *\n   * **Status Values:**\n   * - `pending` - Task queued, not started\n   * - `processing` - Task in progress\n   * - `completed` - All prices updated successfully\n   * - `failed` - Task failed, check error details\n   *\n   * **Rate Limit:** 10 requests per 6 seconds\n   *\n   * @param uploadID - Task ID from updatePricing() response\n   * @returns Promise with task status\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Start pricing update\n   * const task = await sdk.products.updatePricing([\n   *   { nmID: 12345, price: 2999, discount: 15 }\n   * ]);\n   *\n   * // Poll until complete with exponential backoff\n   * let delay = 1000;\n   * let status;\n   *\n   * do {\n   *   await new Promise(resolve => setTimeout(resolve, delay));\n   *   status = await sdk.products.getPricingTaskStatus(task.uploadID);\n   *   if (status.status === 'processing') {\n   *     delay = Math.min(delay * 1.5, 10000);\n   *   }\n   * } while (status.status === 'processing');\n   *\n   * if (status.status === 'completed') {\n   *   console.log('Pricing updated!');\n   * }\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Ceny-i-skidki}\n   */\n  async getPricingTaskStatus(uploadID: string): Promise<PricingTaskStatusResponse> {\n    return this.client.get<PricingTaskStatusResponse>(\n      'https://discounts-prices-api.wildberries.ru/api/v2/history/tasks',\n      {\n        params: { uploadID },\n        rateLimitKey: 'products.getPricingTaskStatus'\n      }\n    );\n  }\n\n  // ============================================================================\n  // Warehouse and Stock Management (Story 2.4)\n  // ============================================================================\n\n  /**\n   * Get list of Wildberries warehouses for FBS binding\n   *\n   * Returns all WB warehouses/offices that can be bound to seller warehouses for\n   * FBS (Fulfillment by Seller) fulfillment. You must get a WB office ID from\n   * this method before creating a seller warehouse.\n   *\n   * **Use Case:**\n   * - Required before creating seller warehouse (need `officeId`)\n   * - Shows available WB warehouses for FBS model\n   * - Contains warehouse location, cargo type, and delivery type info\n   *\n   * **Rate Limit:** 300 requests/min, 200ms interval, 20 burst\n   *\n   * @returns Promise with array of WB warehouses\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get available WB warehouses\n   * const wbOffices = await sdk.products.getWBOffices();\n   *\n   * console.log(`Found ${wbOffices.length} WB warehouses`);\n   * wbOffices.forEach(office => {\n   *   console.log(`Office ${office.id}: ${office.name}`);\n   *   console.log(`  Location: ${office.city}, ${office.address}`);\n   *   console.log(`  Cargo Type: ${office.cargoType} (1=МГТ, 2=СГТ, 3=КГТ+)`);\n   *   console.log(`  Delivery Type: ${office.deliveryType} (1=FBS, 2=DBS)`);\n   * });\n   *\n   * // Use office ID to create seller warehouse\n   * const newWarehouse = await sdk.products.createWarehouse(\n   *   'Склад Коледино',\n   *   wbOffices[0].id  // Bind to first available WB office\n   * );\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Sklady-prodavca}\n   */\n  async getWBOffices(): Promise<Office[]> {\n    return this.client.get<Office[]>(\n      'https://marketplace-api.wildberries.ru/api/v3/offices',\n      { rateLimitKey: 'products.getWBOffices' }\n    );\n  }\n\n  /**\n   * Get list of seller's warehouses\n   *\n   * Returns all seller warehouses with bindings to WB offices. Used for managing\n   * stock locations and FBS fulfillment.\n   *\n   * **Use Case:**\n   * - View all configured seller warehouses\n   * - Get warehouse IDs for stock management operations\n   * - Check warehouse bindings to WB offices\n   *\n   * **Rate Limit:** 300 requests/min, 200ms interval, 20 burst\n   *\n   * @returns Promise with array of seller warehouses\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get seller's warehouse list\n   * const warehouses = await sdk.products.getWarehouses();\n   *\n   * console.log(`You have ${warehouses.length} warehouses`);\n   * warehouses.forEach(warehouse => {\n   *   console.log(`Warehouse ${warehouse.id}: ${warehouse.name}`);\n   *   console.log(`  Bound to WB Office: ${warehouse.officeId}`);\n   *   console.log(`  Cargo Type: ${warehouse.cargoType}`);\n   *   console.log(`  Processing: ${warehouse.isProcessing}`);\n   *   console.log(`  Deleting: ${warehouse.isDeleting}`);\n   * });\n   *\n   * // Use warehouse ID for stock management\n   * const stock = await sdk.products.getStock(\n   *   warehouses[0].id,\n   *   ['BARCODE123']\n   * );\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Sklady-prodavca}\n   */\n  async getWarehouses(): Promise<Warehouse[]> {\n    return this.client.get<Warehouse[]>(\n      'https://marketplace-api.wildberries.ru/api/v3/warehouses',\n      { rateLimitKey: 'products.getWarehouses' }\n    );\n  }\n\n  /**\n   * Create seller warehouse bound to WB office\n   *\n   * Creates a new seller warehouse and binds it to a Wildberries office for FBS\n   * (Fulfillment by Seller) model.\n   *\n   * **CRITICAL Constraints:**\n   * - Name: 1-200 characters\n   * - Cannot bind WB office already in use (409 error)\n   * - Office binding enables FBS fulfillment\n   *\n   * **Rate Limit:** 300 requests/min, 200ms interval, 20 burst\n   *\n   * @param name - Warehouse name (1-200 characters)\n   * @param officeId - WB office/warehouse ID from getWBOffices()\n   * @returns Promise with new warehouse ID\n   * @throws {ValidationError} When name invalid or office already bound (409)\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get available WB offices\n   * const offices = await sdk.products.getWBOffices();\n   * console.log(`Selected: ${offices[0].name} (ID: ${offices[0].id})`);\n   *\n   * // Create seller warehouse\n   * try {\n   *   const newWarehouse = await sdk.products.createWarehouse(\n   *     'Склад Коледино',\n   *     offices[0].id\n   *   );\n   *   console.log(`Warehouse created with ID: ${newWarehouse.id}`);\n   * } catch (error) {\n   *   if (error.statusCode === 409) {\n   *     console.error('Office already bound to another warehouse');\n   *   }\n   *   throw error;\n   * }\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Sklady-prodavca}\n   */\n  async createWarehouse(name: string, officeId: number): Promise<{ id: number }> {\n    // Validate name length\n    if (!name || name.length < 1 || name.length > 200) {\n      throw new ValidationError('Warehouse name must be 1-200 characters');\n    }\n\n    // Validate officeId\n    if (!officeId || officeId < 1) {\n      throw new ValidationError('Office ID must be a positive integer');\n    }\n\n    return this.client.post<{ id: number }>(\n      'https://marketplace-api.wildberries.ru/api/v3/warehouses',\n      { name, officeId },\n      { rateLimitKey: 'products.createWarehouse' }\n    );\n  }\n\n  /**\n   * Update seller warehouse details\n   *\n   * Updates warehouse name and/or WB office binding.\n   *\n   * **IMPORTANT:**\n   * - Office binding can only be changed once per 24 hours\n   * - Cannot reuse WB office already bound to another warehouse\n   *\n   * **Rate Limit:** 300 requests/min, 200ms interval, 20 burst\n   *\n   * @param warehouseId - Seller warehouse ID\n   * @param name - New warehouse name (1-200 chars)\n   * @param officeId - New WB office ID (can change max once/day)\n   * @returns Promise<void> - 204 on success\n   * @throws {ValidationError} When warehouse not found (404) or office conflict (409)\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Update warehouse name\n   * await sdk.products.updateWarehouse(\n   *   123,\n   *   'Склад Москва Обновлённый',\n   *   456  // Same or different office (max once/day)\n   * );\n   *\n   * console.log('Warehouse updated successfully');\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Sklady-prodavca}\n   */\n  async updateWarehouse(warehouseId: number, name: string, officeId: number): Promise<void> {\n    return this.client.put(\n      `https://marketplace-api.wildberries.ru/api/v3/warehouses/${warehouseId}`,\n      { name, officeId },\n      { rateLimitKey: 'products.updateWarehouse' }\n    );\n  }\n\n  /**\n   * Delete seller warehouse\n   *\n   * Removes warehouse from seller's list and unbinds WB office for reuse.\n   *\n   * **Rate Limit:** 300 requests/min, 200ms interval, 20 burst\n   *\n   * @param warehouseId - Warehouse ID to delete\n   * @returns Promise<void> - 204 on success\n   * @throws {NotFoundError} When warehouse doesn't exist (404)\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Delete warehouse\n   * await sdk.products.deleteWarehouse(123);\n   * console.log('Warehouse deleted (WB office unbound for reuse)');\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Sklady-prodavca}\n   */\n  async deleteWarehouse(warehouseId: number): Promise<void> {\n    return this.client.delete(\n      `https://marketplace-api.wildberries.ru/api/v3/warehouses/${warehouseId}`,\n      { rateLimitKey: 'products.deleteWarehouse' }\n    );\n  }\n\n  /**\n   * Get stock levels for products at warehouse\n   *\n   * Retrieves current stock quantities for specified SKUs at a warehouse.\n   *\n   * **Constraints:**\n   * - Batch size: 1-1000 SKUs\n   *\n   * **Rate Limit:** 300 requests/min, 200ms interval, 20 burst\n   *\n   * @param warehouseId - Warehouse ID\n   * @param skus - Array of product barcodes (1-1000 SKUs)\n   * @returns Promise with array of stock info\n   * @throws {ValidationError} When SKU array invalid or warehouse not found\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get stock for multiple products\n   * const stocks = await sdk.products.getStock(\n   *   123,\n   *   ['BARCODE123', 'BARCODE456', 'BARCODE789']\n   * );\n   *\n   * stocks.forEach(stock => {\n   *   console.log(`SKU: ${stock.sku}, Stock: ${stock.amount}`);\n   * });\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca}\n   */\n  async getStock(warehouseId: number, skus: string[]): Promise<StockInfo[]> {\n    // Validate SKU array\n    if (skus.length < 1 || skus.length > 1000) {\n      throw new ValidationError('SKUs array must contain 1-1000 items');\n    }\n\n    const response = await this.client.post<{ stocks: StockInfo[] }>(\n      `https://marketplace-api.wildberries.ru/api/v3/stocks/${warehouseId}`,\n      { skus },\n      { rateLimitKey: 'products.getStock' }\n    );\n\n    return response.stocks;\n  }\n\n  /**\n   * Update stock quantities for products (user-friendly wrapper)\n   *\n   * Updates stock levels for multiple SKUs at a warehouse.\n   *\n   * **CRITICAL:**\n   * - Parameter names NOT validated! Incorrect names = silent failure with 200 OK\n   * - Correct field names: `stocks` (array), `sku` (string), `amount` (number)\n   *\n   * **Constraints:**\n   * - Max 1000 SKUs per request\n   * - Amount: 0-100,000 per SKU\n   *\n   * **409 Errors (count as 5 requests!):**\n   * - DBS/FBS warehouse restrictions\n   * - Cargo type warehouse restrictions (LCL, ODC, CD+)\n   * - Warehouse processing in progress\n   *\n   * **Rate Limit:** 300 requests/min, 200ms interval, 20 burst\n   *\n   * @param warehouseId - Warehouse ID\n   * @param updates - Array of stock updates (SKU + amount, 1-1000 items)\n   * @returns Promise<void> - 204 on success\n   * @throws {ValidationError} When amounts invalid (0-100,000) or warehouse not found\n   * @throws {ConflictError} 409 for warehouse restrictions (DBS/FBS/cargo type conflicts)\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Update stock for multiple products\n   * await sdk.products.updateStockLevels(123, [\n   *   { sku: 'BARCODE123', amount: 100 },\n   *   { sku: 'BARCODE456', amount: 50 },\n   *   { sku: 'BARCODE789', amount: 200 }\n   * ]);\n   *\n   * console.log('Stock updated for 3 products');\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca}\n   */\n  async updateStockLevels(warehouseId: number, updates: StockUpdate[]): Promise<void> {\n    // Validate updates array\n    if (updates.length < 1 || updates.length > 1000) {\n      throw new ValidationError('Stock updates array must contain 1-1000 items');\n    }\n\n    // Validate each amount\n    for (const update of updates) {\n      if (update.amount < 0 || update.amount > 100000) {\n        throw new ValidationError(`Stock amount must be 0-100000, got ${update.amount} for SKU ${update.sku}`);\n      }\n    }\n\n    return this.client.put(\n      `https://marketplace-api.wildberries.ru/api/v3/stocks/${warehouseId}`,\n      { stocks: updates },\n      { rateLimitKey: 'products.updateStock' }\n    );\n  }\n\n  /**\n   * Delete stock records for products (user-friendly wrapper)\n   *\n   * **IRREVERSIBLE:** Deleted stock must be re-uploaded to resume sales.\n   * No undo functionality available.\n   *\n   * **Constraints:**\n   * - Batch size: 1-1000 SKUs\n   *\n   * **409 Errors (count as 5 requests!):**\n   * - Warehouse processing in progress\n   *\n   * **Rate Limit:** 300 requests/min, 200ms interval, 20 burst\n   *\n   * @param warehouseId - Warehouse ID\n   * @param skus - Array of barcodes to delete (1-1000 SKUs)\n   * @returns Promise<void> - 204 on success\n   * @throws {NotFoundError} 404 if SKUs not found in warehouse\n   * @throws {ConflictError} 409 if warehouse processing in progress\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // WARNING: This is irreversible!\n   * await sdk.products.deleteStockRecords(123, ['BARCODE789']);\n   * console.log('Stock deleted (IRREVERSIBLE - must re-upload to resume sales)');\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/work-with-products#tag/Ostatki-na-skladah-prodavca}\n   */\n  async deleteStockRecords(warehouseId: number, skus: string[]): Promise<void> {\n    // Validate SKU array\n    if (skus.length < 1 || skus.length > 1000) {\n      throw new ValidationError('SKUs array must contain 1-1000 items');\n    }\n\n    return this.client.delete(\n      `https://marketplace-api.wildberries.ru/api/v3/stocks/${warehouseId}`,\n      { skus },\n      { rateLimitKey: 'products.deleteStock' }\n    );\n  }\n\n}","/**\n * Orders FBS (Fulfillment by Seller) Module\n *\n * Manage FBS orders - seller processes and ships from own warehouse to WB offices.\n *\n * This differs from FBW (Fulfillment by Wildberries) where WB handles logistics\n * from WB warehouses. FBS gives sellers more control over order processing and\n * shipping while WB handles final delivery to customers.\n *\n * @module modules/orders-fbs\n */\n\nimport type { BaseClient } from '../../client/base-client';\nimport type {\n  OrderNew,\n  OrderFilters,\n  OrderStatus,\n  GetNewOrdersResponse,\n  GetOrdersResponse,\n  GetOrderStatusesResponse,\n  Supply,\n  SupplyFilters,\n  CreateSupplyResponse,\n  GetSuppliesResponse,\n  StickerOptions,\n  OrderSticker,\n  GetOrderStickersResponse,\n  BarcodeType,\n  SupplyBarcode,\n} from '../../types/orders-fbs.types';\nimport { ValidationError } from '../../errors/validation-error';\n\n/**\n * Orders FBS (Fulfillment by Seller) module\n *\n * Provides methods for managing FBS orders including:\n * - Retrieving new orders awaiting processing\n * - Filtering orders by date range with pagination\n * - Checking order statuses (both supplier and WB system status)\n *\n * @example\n * ```typescript\n * const sdk = new WildberriesSDK({ apiKey: 'your-api-key' });\n *\n * // Get new orders\n * const newOrders = await sdk.ordersFBS.getNewOrders();\n *\n * // Get orders from last 7 days\n * const sevenDaysAgo = Math.floor(Date.now() / 1000) - (7 * 24 * 60 * 60);\n * const orders = await sdk.ordersFBS.getOrders({\n *   dateFrom: sevenDaysAgo,\n *   limit: 100\n * });\n *\n * // Check order statuses\n * const orderIds = orders.orders.map(o => o.id);\n * const statuses = await sdk.ordersFBS.getOrderStatuses(orderIds);\n * ```\n */\nexport class OrdersFBSModule {\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Get all new FBS orders awaiting processing\n   *\n   * Returns all new assembly tasks (сборочные задания) available at request time.\n   * New orders need to be confirmed and added to supply for processing.\n   *\n   * Rate limit: 300 requests per minute, 200ms interval, 20 burst\n   *\n   * @returns Promise resolving to array of new orders\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * const newOrders = await sdk.ordersFBS.getNewOrders();\n   * console.log(`Found ${newOrders.length} new orders`);\n   *\n   * newOrders.forEach(order => {\n   *   console.log(`Order ${order.id}: ${order.article}`);\n   *   console.log(`Customer comment: ${order.comment || 'None'}`);\n   * });\n   * ```\n   */\n  async getNewOrders(): Promise<OrderNew[]> {\n    const response = await this.client.get<GetNewOrdersResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/orders/new',\n      { rateLimitKey: 'ordersFBS.getNewOrders' }\n    );\n\n    return response.orders;\n  }\n\n  /**\n   * Get FBS orders with filters and pagination\n   *\n   * IMPORTANT: Returns orders WITHOUT current status. Use getOrderStatuses()\n   * separately to get order status information.\n   *\n   * Maximum date range: 30 calendar days per request.\n   * Default date range: Last 30 days if not specified.\n   *\n   * Pagination pattern:\n   * - First request: next = 0\n   * - Subsequent requests: Use next value from previous response\n   * - Continue until next is 0 or null\n   *\n   * Rate limit: 300 requests per minute, 200ms interval\n   *\n   * @param filters - Optional filters (dateFrom/dateTo as Unix timestamps, limit 1-1000, next for pagination)\n   * @returns Promise resolving to orders array and next pagination cursor\n   * @throws {ValidationError} When date range exceeds 30 days\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * // Get orders from last 7 days with pagination\n   * const sevenDaysAgo = Math.floor(Date.now() / 1000) - (7 * 24 * 60 * 60);\n   * const now = Math.floor(Date.now() / 1000);\n   *\n   * let allOrders = [];\n   * let nextCursor = 0;\n   *\n   * do {\n   *   const response = await sdk.ordersFBS.getOrders({\n   *     dateFrom: sevenDaysAgo,\n   *     dateTo: now,\n   *     limit: 100,\n   *     next: nextCursor\n   *   });\n   *\n   *   allOrders = allOrders.concat(response.orders);\n   *   nextCursor = response.next;\n   * } while (nextCursor > 0);\n   *\n   * console.log(`Retrieved ${allOrders.length} orders`);\n   * ```\n   */\n  async getOrders(filters?: OrderFilters): Promise<GetOrdersResponse> {\n    const params: Record<string, number> = {\n      limit: filters?.limit ?? 1000,\n      next: filters?.next ?? 0,\n    };\n\n    // Add optional date filters (Unix timestamps)\n    if (filters?.dateFrom) {\n      params.dateFrom = filters.dateFrom;\n    }\n    if (filters?.dateTo) {\n      params.dateTo = filters.dateTo;\n    }\n\n    return this.client.get<GetOrdersResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/orders',\n      {\n        params,\n        rateLimitKey: 'ordersFBS.getOrders',\n      }\n    );\n  }\n\n  /**\n   * Get current statuses for FBS orders\n   *\n   * Returns both supplier status (controlled by seller) and WB status (system).\n   * Use to check order states.\n   *\n   * Supplier Status:\n   * - new: New assembly task\n   * - confirm: On assembly (added to supply)\n   * - complete: In delivery (supply delivered)\n   * - cancel: Canceled by seller\n   *\n   * WB Status:\n   * - waiting: Order in progress\n   * - sorted: Order sorted at WB\n   * - sold: Customer received order\n   * - canceled: Order canceled\n   * - canceled_by_client: Customer canceled on pickup\n   * - declined_by_client: Customer canceled (first hour, before assembly)\n   * - defect: Canceled due to defect\n   * - ready_for_pickup: Arrived at pickup point\n   * - postponed_delivery: Delivery postponed\n   *\n   * Note: Status transitions controlled by supply operations (see Story 2.6)\n   *\n   * Rate limit: 300 requests per minute, 200ms interval\n   *\n   * @param orderIds - Array of order IDs (1-1000 items)\n   * @returns Promise resolving to array with id, supplierStatus, wbStatus\n   * @throws {ValidationError} When orderIds array is invalid\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * const orderIds = [12345, 67890, 11111];\n   * const statuses = await sdk.ordersFBS.getOrderStatuses(orderIds);\n   *\n   * statuses.forEach(status => {\n   *   console.log(`Order ${status.id}:`);\n   *   console.log(`  Supplier: ${status.supplierStatus}`);\n   *   console.log(`  WB System: ${status.wbStatus}`);\n   * });\n   * ```\n   */\n  async getOrderStatuses(orderIds: number[]): Promise<OrderStatus[]> {\n    // Validate order IDs array\n    if (orderIds.length < 1 || orderIds.length > 1000) {\n      throw new ValidationError(\n        `Order IDs array must contain 1-1000 items (received: ${orderIds.length})`,\n        { orderIds: `Array size must be between 1 and 1000, received ${orderIds.length}` }\n      );\n    }\n\n    const response = await this.client.post<GetOrderStatusesResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/orders/status',\n      { orders: orderIds },\n      { rateLimitKey: 'ordersFBS.getOrderStatuses' }\n    );\n\n    return response.orders;\n  }\n\n  // ============================================================================\n  // Supply Management Methods\n  // ============================================================================\n\n  /**\n   * Create new supply for grouping FBS orders\n   *\n   * IMPORTANT: Empty supply has no cargo type. The first order added to the supply\n   * sets the cargo type (cargoType: 1=МГТ, 2=СГТ, 3=КГТ+). Only orders with the\n   * same cargo type can be added to the supply after that.\n   *\n   * Supply workflow:\n   * 1. Create supply (empty, no cargoType)\n   * 2. Add first order → supply gets cargoType, order: new → confirm\n   * 3. Add more orders (must match cargoType) → orders: new → confirm\n   * 4. Get order stickers (orders must be in confirm status)\n   * 5. Deliver supply → orders: confirm → complete, supply closed\n   * 6. Get supply QR code (only available after delivery)\n   *\n   * Rate limit: 300 requests per minute, 200ms interval\n   *\n   * @param name - Supply name (1-128 characters)\n   * @returns Promise resolving to object with new supply ID (format: WB-GI-1234567)\n   * @throws {ValidationError} When name is invalid (empty or >128 chars)\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * const supply = await sdk.ordersFBS.createSupply('Morning Batch 2024-01-15');\n   * console.log(`Created supply: ${supply.id}`); // WB-GI-1234567\n   * ```\n   */\n  async createSupply(name: string): Promise<CreateSupplyResponse> {\n    // Validate name length\n    if (!name || name.length < 1 || name.length > 128) {\n      throw new ValidationError(\n        'Supply name must be 1-128 characters',\n        { name: `Name length must be 1-128, received ${name.length}` }\n      );\n    }\n\n    return this.client.post<CreateSupplyResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/supplies',\n      { name },\n      { rateLimitKey: 'ordersFBS.createSupply' }\n    );\n  }\n\n  /**\n   * Get list of FBS supplies with pagination\n   *\n   * Returns supplies with details including status (done flag), timestamps,\n   * and pagination cursor for retrieving additional supplies.\n   *\n   * Pagination pattern:\n   * - First request: next = 0\n   * - Subsequent requests: Use next value from previous response\n   * - Continue until next is 0\n   *\n   * Rate limit: 300 requests per minute, 200ms interval\n   *\n   * @param filters - Optional filters (limit 1-1000, next for pagination)\n   * @returns Promise resolving to supplies array and next pagination cursor\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * // Get all supplies with pagination\n   * let allSupplies = [];\n   * let nextCursor = 0;\n   *\n   * do {\n   *   const response = await sdk.ordersFBS.getSupplies({ limit: 100, next: nextCursor });\n   *   allSupplies = allSupplies.concat(response.supplies);\n   *   nextCursor = response.next;\n   * } while (nextCursor > 0);\n   *\n   * console.log(`Retrieved ${allSupplies.length} supplies`);\n   * ```\n   */\n  async getSupplies(filters?: SupplyFilters): Promise<GetSuppliesResponse> {\n    const params: Record<string, number> = {\n      limit: filters?.limit ?? 1000,\n      next: filters?.next ?? 0,\n    };\n\n    return this.client.get<GetSuppliesResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/supplies',\n      {\n        params,\n        rateLimitKey: 'ordersFBS.getSupplies',\n      }\n    );\n  }\n\n  /**\n   * Get details for specific supply\n   *\n   * Returns supply information including status (done flag indicates if supply\n   * is closed/delivered), timestamps (createdAt, closedAt, scanDt), and metadata.\n   *\n   * Rate limit: 300 requests per minute, 200ms interval\n   *\n   * @param supplyId - Supply ID (format: WB-GI-1234567)\n   * @returns Promise resolving to supply details\n   * @throws {NotFoundError} When supply doesn't exist\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * const supply = await sdk.ordersFBS.getSupply('WB-GI-1234567');\n   * console.log(`Supply: ${supply.name}`);\n   * console.log(`Status: ${supply.done ? 'Closed' : 'Open'}`);\n   * console.log(`Created: ${supply.createdAt}`);\n   * ```\n   */\n  async getSupply(supplyId: string): Promise<Supply> {\n    return this.client.get<Supply>(\n      `https://marketplace-api.wildberries.ru/api/v3/supplies/${supplyId}`,\n      { rateLimitKey: 'ordersFBS.getSupply' }\n    );\n  }\n\n  /**\n   * Add order to supply (changes order status to 'confirm')\n   *\n   * CRITICAL CONSTRAINTS:\n   * 1. Empty supply gets cargoType from first order added\n   * 2. Can only add orders with matching cargoType after first order\n   * 3. All orders must be from same warehouse\n   * 4. Order status changes: new → confirm\n   *\n   * Cargo types:\n   * - 1 = МГТ (small cargo)\n   * - 2 = СГТ (oversized cargo)\n   * - 3 = КГТ+ (large cargo)\n   *\n   * NOTE: 409 errors count as 5 requests toward rate limit.\n   *\n   * Rate limit: 1000 requests per minute, 60ms interval (HIGHER than other endpoints)\n   *\n   * @param supplyId - Supply ID\n   * @param orderId - Order ID to add\n   * @returns Promise<void> - 204 on success\n   * @throws {ValidationError} (409) When cargo type mismatch or warehouse mismatch\n   * @throws {NotFoundError} When supply or order doesn't exist\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * const supply = await sdk.ordersFBS.createSupply('Mixed Cargo Test');\n   *\n   * // Add first order (sets cargoType)\n   * await sdk.ordersFBS.addOrderToSupply(supply.id, 12345); // cargoType: 1 (МГТ)\n   *\n   * // Add second order (must match cargoType: 1)\n   * await sdk.ordersFBS.addOrderToSupply(supply.id, 12346); // OK - same cargoType\n   *\n   * // Try to add order with different cargoType\n   * try {\n   *   await sdk.ordersFBS.addOrderToSupply(supply.id, 99999); // cargoType: 2 (СГТ)\n   * } catch (error) {\n   *   // Error: cargo type mismatch (409 conflict)\n   * }\n   * ```\n   */\n  async addOrderToSupply(supplyId: string, orderId: number): Promise<void> {\n    await this.client.patch<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/supplies/${supplyId}/orders/${orderId}`,\n      {},\n      { rateLimitKey: 'ordersFBS.addOrderToSupply' }\n    );\n  }\n\n  /**\n   * Mark supply as delivered (changes all order statuses to 'complete')\n   *\n   * WORKFLOW: Closes supply and transitions ALL orders to \"in delivery\" status.\n   * After delivery, cannot add more orders. Required before getting supply QR code.\n   *\n   * CONSTRAINT: Supply must have ≥1 order before delivery.\n   *\n   * NOTE: Supply auto-closes on first acceptance scan if not manually delivered.\n   * NOTE: 409 errors count as 5 requests toward rate limit.\n   *\n   * Rate limit: 300 requests per minute, 200ms interval\n   *\n   * @param supplyId - Supply ID\n   * @returns Promise<void> - 204 on success\n   * @throws {ValidationError} (409) When supply has zero orders or UINs not filled\n   * @throws {NotFoundError} When supply doesn't exist\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * // After adding orders and generating stickers, deliver the supply\n   * await sdk.ordersFBS.deliverSupply('WB-GI-1234567');\n   * console.log('Supply delivered, orders transitioned to complete status');\n   * ```\n   */\n  async deliverSupply(supplyId: string): Promise<void> {\n    await this.client.patch<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/supplies/${supplyId}/deliver`,\n      {},\n      { rateLimitKey: 'ordersFBS.deliverSupply' }\n    );\n  }\n\n  /**\n   * Delete supply\n   *\n   * CONSTRAINT: Can only delete supply with zero orders attached.\n   * Remove all orders from supply before deletion.\n   *\n   * NOTE: 409 errors count as 5 requests toward rate limit.\n   *\n   * Rate limit: 300 requests per minute, 200ms interval\n   *\n   * @param supplyId - Supply ID to delete\n   * @returns Promise<void> - 204 on success\n   * @throws {ValidationError} (409) When supply has orders\n   * @throws {NotFoundError} When supply doesn't exist\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * // Delete empty supply after removing all orders\n   * await sdk.ordersFBS.deleteSupply('WB-GI-1234567');\n   * console.log('Supply deleted');\n   * ```\n   */\n  async deleteSupply(supplyId: string): Promise<void> {\n    await this.client.delete<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/supplies/${supplyId}`,\n      { rateLimitKey: 'ordersFBS.deleteSupply' }\n    );\n  }\n\n  // ============================================================================\n  // Shipping Labels and Barcodes\n  // ============================================================================\n\n  /**\n   * Get shipping label stickers for orders (base64-encoded)\n   *\n   * CONSTRAINTS:\n   * 1. Max 100 stickers per request\n   * 2. Orders must be in \"confirm\" status (on assembly)\n   * 3. Returns base64-encoded file in specified format\n   *\n   * Supported formats:\n   * - svg: Vector graphics\n   * - png: Raster image\n   * - zplv: Zebra printer (vertical)\n   * - zplh: Zebra printer (horizontal)\n   *\n   * Valid size combinations:\n   * - 580×400 px (width=58, height=40)\n   * - 400×300 px (width=40, height=30)\n   *\n   * Rate limit: 300 requests per minute, 200ms interval\n   *\n   * @param orderIds - Order IDs (1-100 items)\n   * @param options - Sticker format and size ({ type: 'svg'|'png'|'zplv'|'zplh', width: 58|40, height: 40|30 })\n   * @returns Promise resolving to array of stickers with orderId, partA, partB, barcode, file (base64)\n   * @throws {ValidationError} When >100 orders, invalid size, or orders not in \"confirm\" status\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * import { writeFileSync } from 'fs';\n   *\n   * // Get PNG stickers for orders\n   * const stickers = await sdk.ordersFBS.getOrderStickers(\n   *   [12345, 67890],\n   *   { type: 'png', width: 58, height: 40 }\n   * );\n   *\n   * // Save first sticker to file\n   * const imageBuffer = Buffer.from(stickers[0].file, 'base64');\n   * writeFileSync('order-12345-label.png', imageBuffer);\n   * console.log(`Barcode: ${stickers[0].barcode}`);\n   * ```\n   */\n  async getOrderStickers(\n    orderIds: number[],\n    options: StickerOptions\n  ): Promise<OrderSticker[]> {\n    // Validate orderIds array size\n    if (orderIds.length < 1 || orderIds.length > 100) {\n      throw new ValidationError(\n        `Order IDs array must contain 1-100 items (received: ${orderIds.length})`,\n        { orderIds: `Array size must be 1-100, received ${orderIds.length}` }\n      );\n    }\n\n    // Validate size combination\n    const validSizes = [\n      { width: 58, height: 40 },\n      { width: 40, height: 30 },\n    ];\n    const isValidSize = validSizes.some(\n      (s) => s.width === options.width && s.height === options.height\n    );\n    if (!isValidSize) {\n      throw new ValidationError(\n        'Invalid size combination. Use 58×40 or 40×30',\n        {\n          size: `Valid combinations: 58×40 or 40×30, received ${options.width}×${options.height}`,\n        }\n      );\n    }\n\n    const response = await this.client.post<GetOrderStickersResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/orders/stickers',\n      { orders: orderIds },\n      {\n        params: {\n          type: options.type,\n          width: options.width,\n          height: options.height,\n        },\n        rateLimitKey: 'ordersFBS.getOrderStickers',\n      }\n    );\n\n    return response.stickers;\n  }\n\n  /**\n   * Get supply QR code (base64-encoded)\n   *\n   * REQUIREMENT: Supply must be delivered (via deliverSupply) before QR code is available.\n   * Size: 580×400px.\n   *\n   * Supported formats:\n   * - svg: Vector graphics\n   * - png: Raster image\n   * - zplv: Zebra printer (vertical)\n   * - zplh: Zebra printer (horizontal)\n   *\n   * NOTE: 409 errors count as 5 requests toward rate limit.\n   *\n   * Rate limit: 300 requests per minute, 200ms interval\n   *\n   * @param supplyId - Supply ID\n   * @param type - Barcode format ('svg'|'png'|'zplv'|'zplh')\n   * @returns Promise resolving to QR code with barcode value and file (base64)\n   * @throws {ValidationError} (409) When supply not delivered\n   * @throws {NotFoundError} When supply doesn't exist\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * import { writeFileSync } from 'fs';\n   *\n   * // First deliver the supply\n   * await sdk.ordersFBS.deliverSupply('WB-GI-1234567');\n   *\n   * // Then get QR code\n   * const qrCode = await sdk.ordersFBS.getSupplyBarcode('WB-GI-1234567', 'png');\n   *\n   * // Save QR code to file\n   * const imageBuffer = Buffer.from(qrCode.file, 'base64');\n   * writeFileSync('supply-qrcode.png', imageBuffer);\n   * console.log(`QR code encodes: ${qrCode.barcode}`);\n   * ```\n   */\n  async getSupplyBarcode(supplyId: string, type: BarcodeType): Promise<SupplyBarcode> {\n    return this.client.get<SupplyBarcode>(\n      `https://marketplace-api.wildberries.ru/api/v3/supplies/${supplyId}/barcode`,\n      {\n        params: { type },\n        rateLimitKey: 'ordersFBS.getSupplyBarcode',\n      }\n    );\n  }\n\n  /**\n   * Cancel FBS order (changes status to 'cancel')\n   *\n   * AUTO-REMOVAL: If order was in a supply, it's automatically removed from the supply.\n   *\n   * CONSTRAINT: Cannot cancel if order already completed/delivered.\n   *\n   * NOTE: 409 errors count as 5 requests toward rate limit.\n   *\n   * Rate limit: 100 requests per minute, 600ms interval (LOWER than other endpoints)\n   *\n   * @param orderId - Order ID to cancel\n   * @returns Promise<void> - 204 on success\n   * @throws {ValidationError} (409) When status transition not allowed\n   * @throws {NotFoundError} When order doesn't exist\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @example\n   * ```typescript\n   * // Cancel order (auto-removes from supply if present)\n   * await sdk.ordersFBS.cancelOrder(12345);\n   * console.log('Order canceled and removed from supply');\n   * ```\n   */\n  async cancelOrder(orderId: number): Promise<void> {\n    await this.client.patch<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/orders/${orderId}/cancel`,\n      {},\n      { rateLimitKey: 'ordersFBS.cancelOrder' }\n    );\n  }\n}\n","/**\n * Orders FBW (Fulfillment by Wildberries) Module\n *\n * Provides access to warehouse operations for supplies managed by Wildberries:\n * - Warehouse information and acceptance coefficients\n * - Supply management and details\n * - Transit tariff calculations\n *\n * All operations use base URL: https://supplies-api.wildberries.ru\n *\n * @module modules/orders-fbw\n */\n\nimport { BaseClient } from '../../client/base-client';\nimport { ValidationError } from '../../errors/validation-error';\nimport type {\n  ModelsAcceptanceCoefficient,\n  ModelsBox,\n  ModelsGood,\n  ModelsGoodInSupply,\n  ModelsOptionsResultModel,\n  ModelsSuppliesFiltersRequest,\n  ModelsSupply,\n  ModelsSupplyDetails,\n  ModelsTransitTariff,\n  ModelsWarehousesResultItems,\n} from '../../types/orders-fbw.types';\n\nexport class OrdersFBWModule {\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Get list of Wildberries warehouses\n   *\n   * Rate limit: 6 requests per minute (10 second intervals)\n   *\n   * @returns List of warehouses with details (ID, name, address, work time, capabilities)\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * const warehouses = await sdk.ordersFBW.getWarehouses();\n   * console.log(warehouses[0].name); // \"Коледино\"\n   * ```\n   */\n  async getWarehouses(): Promise<ModelsWarehousesResultItems[]> {\n    return this.client.get<ModelsWarehousesResultItems[]>(\n      'https://supplies-api.wildberries.ru/api/v1/warehouses',\n      { rateLimitKey: 'ordersFBW.getWarehouses' }\n    );\n  }\n\n  /**\n   * Get acceptance coefficients for warehouses\n   *\n   * Returns acceptance coefficients for specific warehouses for the next 14 days.\n   * Acceptance is only available when: coefficient = 0 or 1 AND allowUnload = true\n   *\n   * Rate limit: 6 requests per minute (10 second intervals)\n   *\n   * @param warehouseIDs - Optional comma-separated warehouse IDs (e.g., \"507,117501\")\n   * @returns List of acceptance coefficients with warehouse details and pricing\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // All warehouses\n   * const allCoeffs = await sdk.ordersFBW.getAcceptanceCoefficients();\n   *\n   * // Specific warehouses\n   * const coeffs = await sdk.ordersFBW.getAcceptanceCoefficients('507,117501');\n   * ```\n   */\n  async getAcceptanceCoefficients(warehouseIDs?: string): Promise<ModelsAcceptanceCoefficient[]> {\n    const params = warehouseIDs ? { warehouseIDs } : {};\n\n    return this.client.get<ModelsAcceptanceCoefficient[]>(\n      'https://supplies-api.wildberries.ru/api/v1/acceptance/coefficients',\n      { params, rateLimitKey: 'ordersFBW.getAcceptanceCoefficients' }\n    );\n  }\n\n  /**\n   * Get acceptance options for goods\n   *\n   * Returns information about which warehouses and package types are available for supply.\n   * List of warehouses is determined by barcode and quantity.\n   *\n   * Rate limit: 6 requests per minute (10 second intervals)\n   *\n   * @param goods - Array of goods with barcodes and quantities (1-5000 items)\n   * @param warehouseID - Optional warehouse ID to filter results\n   * @returns Acceptance options including available warehouses and packaging types\n   * @throws {ValidationError} When goods array is empty, too large, or contains invalid data\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * const goods = [\n   *   { barcode: '1234567891234', quantity: 10 },\n   *   { barcode: '9876543210987', quantity: 5 }\n   * ];\n   *\n   * const options = await sdk.ordersFBW.getAcceptanceOptions(goods);\n   * console.log(options.result[0].warehouses); // Available warehouses\n   *\n   * // Filter by warehouse\n   * const warehouseOptions = await sdk.ordersFBW.getAcceptanceOptions(goods, '507');\n   * ```\n   */\n  async getAcceptanceOptions(\n    goods: ModelsGood[],\n    warehouseID?: string\n  ): Promise<ModelsOptionsResultModel> {\n    // Validation\n    if (goods.length === 0) {\n      throw new ValidationError('Goods array cannot be empty');\n    }\n\n    if (goods.length > 5000) {\n      throw new ValidationError('Maximum 5000 goods per request');\n    }\n\n    // Validate each good\n    for (let i = 0; i < goods.length; i++) {\n      const good = goods[i];\n\n      if (!good.barcode || good.barcode.trim() === '') {\n        throw new ValidationError(`Good at index ${i} is missing barcode`);\n      }\n\n      if (!good.quantity || good.quantity < 1 || good.quantity > 999999) {\n        throw new ValidationError(`Good at index ${i}: quantity must be 1-999999`);\n      }\n    }\n\n    const params = warehouseID ? { warehouseID } : {};\n\n    return this.client.post<ModelsOptionsResultModel>(\n      'https://supplies-api.wildberries.ru/api/v1/acceptance/options',\n      goods,\n      { params, rateLimitKey: 'ordersFBW.getAcceptanceOptions' }\n    );\n  }\n\n  /**\n   * Get transit tariffs\n   *\n   * Returns information about available transit directions and their pricing.\n   *\n   * Rate limit: 6 requests per minute (10 second intervals, burst: 10)\n   *\n   * @returns List of transit tariffs with pricing for boxes and pallets\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * const tariffs = await sdk.ordersFBW.getTransitTariffs();\n   * console.log(tariffs[0].transitWarehouseName); // \"Москва (транзит)\"\n   * console.log(tariffs[0].palletTariff); // 1200.0\n   * ```\n   */\n  async getTransitTariffs(): Promise<ModelsTransitTariff[]> {\n    return this.client.get<ModelsTransitTariff[]>(\n      'https://supplies-api.wildberries.ru/api/v1/transit-tariffs',\n      { rateLimitKey: 'ordersFBW.getTransitTariffs' }\n    );\n  }\n\n  /**\n   * Get list of supplies\n   *\n   * Returns list of supplies with optional filters. Default: last 1000 supplies.\n   *\n   * Rate limit: 30 requests per minute (2 second intervals)\n   *\n   * @param filters - Date and status filters\n   * @param limit - Number of supplies to return (1-1000, default: 1000)\n   * @param offset - Number of supplies to skip (>= 0, default: 0)\n   * @returns List of supplies matching filters\n   * @throws {ValidationError} When limit/offset are invalid or filters contain invalid data\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Get all supplies\n   * const allSupplies = await sdk.ordersFBW.getSupplies({\n   *   dates: [],\n   *   statusIDs: []\n   * });\n   *\n   * // Filter by date and status\n   * const filteredSupplies = await sdk.ordersFBW.getSupplies({\n   *   dates: [{\n   *     from: '2024-01-01',\n   *     till: '2024-12-31',\n   *     type: 'createDate'\n   *   }],\n   *   statusIDs: [2, 3, 4] // Planned, Allowed, In Acceptance\n   * }, 100, 0);\n   * ```\n   */\n  async getSupplies(\n    filters: ModelsSuppliesFiltersRequest,\n    limit = 1000,\n    offset = 0\n  ): Promise<ModelsSupply[]> {\n    // Validate pagination\n    if (limit < 1 || limit > 1000) {\n      throw new ValidationError('Limit must be 1-1000');\n    }\n\n    if (offset < 0) {\n      throw new ValidationError('Offset must be >= 0');\n    }\n\n    // Validate date filters\n    if (filters.dates) {\n      for (const dateFilter of filters.dates) {\n        // Simple date format validation (YYYY-MM-DD or ISO 8601)\n        const dateRegex = /^\\d{4}-\\d{2}-\\d{2}/;\n\n        if (dateFilter.from && !dateRegex.test(dateFilter.from)) {\n          throw new ValidationError('Invalid from date format. Use YYYY-MM-DD or ISO 8601');\n        }\n\n        if (dateFilter.till && !dateRegex.test(dateFilter.till)) {\n          throw new ValidationError('Invalid till date format. Use YYYY-MM-DD or ISO 8601');\n        }\n      }\n    }\n\n    // Validate status IDs (must be 1-6)\n    if (filters.statusIDs) {\n      for (const statusID of filters.statusIDs) {\n        if (statusID < 1 || statusID > 6) {\n          throw new ValidationError(`Invalid status ID: ${statusID}. Status must be 1-6`);\n        }\n      }\n    }\n\n    return this.client.post<ModelsSupply[]>(\n      `https://supplies-api.wildberries.ru/api/v1/supplies?limit=${limit}&offset=${offset}`,\n      filters,\n      { rateLimitKey: 'ordersFBW.getSupplies' }\n    );\n  }\n\n  /**\n   * Get supply details by ID\n   *\n   * Returns detailed information about a specific supply or preorder.\n   *\n   * Rate limit: 30 requests per minute (2 second intervals)\n   *\n   * @param ID - Supply ID or Preorder ID\n   * @param isPreorderID - Whether ID is a preorder ID (default: false)\n   * @returns Detailed supply information including quantities, costs, and coefficients\n   * @throws {ValidationError} When ID is invalid\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Get supply details\n   * const supply = await sdk.ordersFBW.getSupplyDetails(12345);\n   * console.log(supply.statusName); // \"Принято\"\n   * console.log(supply.warehouseName); // \"Коледино\"\n   *\n   * // Get preorder details\n   * const preorder = await sdk.ordersFBW.getSupplyDetails(67890, true);\n   * ```\n   */\n  async getSupplyDetails(ID: number, isPreorderID = false): Promise<ModelsSupplyDetails> {\n    // Validate ID\n    if (!ID || ID <= 0) {\n      throw new ValidationError('Supply/Preorder ID must be > 0');\n    }\n\n    return this.client.get<ModelsSupplyDetails>(\n      `https://supplies-api.wildberries.ru/api/v1/supplies/${ID}?isPreorderID=${isPreorderID}`,\n      { rateLimitKey: 'ordersFBW.getSupplyDetails' }\n    );\n  }\n\n  /**\n   * Get goods in supply\n   *\n   * Returns information about goods in a supply with pagination.\n   *\n   * Rate limit: 30 requests per minute (2 second intervals)\n   *\n   * @param ID - Supply ID or Preorder ID\n   * @param isPreorderID - Whether ID is a preorder ID (default: false)\n   * @param limit - Number of goods to return (1-1000, default: 100)\n   * @param offset - Number of goods to skip (>= 0, default: 0)\n   * @returns List of goods with barcodes, quantities, and acceptance status\n   * @throws {ValidationError} When ID, limit, or offset are invalid\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Get first 100 goods\n   * const goods = await sdk.ordersFBW.getSupplyGoods(12345);\n   *\n   * // Get next 100 goods\n   * const moreGoods = await sdk.ordersFBW.getSupplyGoods(12345, false, 100, 100);\n   *\n   * // Get goods from preorder\n   * const preorderGoods = await sdk.ordersFBW.getSupplyGoods(67890, true);\n   * ```\n   */\n  async getSupplyGoods(\n    ID: number,\n    isPreorderID = false,\n    limit = 100,\n    offset = 0\n  ): Promise<ModelsGoodInSupply[]> {\n    // Validate ID\n    if (!ID || ID <= 0) {\n      throw new ValidationError('Supply/Preorder ID must be > 0');\n    }\n\n    // Validate pagination\n    if (limit < 1 || limit > 1000) {\n      throw new ValidationError('Limit must be 1-1000');\n    }\n\n    if (offset < 0) {\n      throw new ValidationError('Offset must be >= 0');\n    }\n\n    return this.client.get<ModelsGoodInSupply[]>(\n      `https://supplies-api.wildberries.ru/api/v1/supplies/${ID}/goods?limit=${limit}&offset=${offset}&isPreorderID=${isPreorderID}`,\n      { rateLimitKey: 'ordersFBW.getSupplyGoods' }\n    );\n  }\n\n  /**\n   * Get supply package information\n   *\n   * Returns information about packaging for a supply.\n   *\n   * Rate limit: 30 requests per minute (2 second intervals)\n   *\n   * @param ID - Supply ID\n   * @returns List of boxes with package codes and contained goods\n   * @throws {ValidationError} When ID is invalid\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * const packages = await sdk.ordersFBW.getSupplyPackage(12345);\n   * console.log(packages[0].packageCode); // \"WB-PKG-12345\"\n   * console.log(packages[0].quantity); // 15\n   * console.log(packages[0].barcodes); // [{ barcode: '...', quantity: 10 }, ...]\n   * ```\n   */\n  async getSupplyPackage(ID: number): Promise<ModelsBox[]> {\n    // Validate ID\n    if (!ID || ID <= 0) {\n      throw new ValidationError('Supply ID must be > 0');\n    }\n\n    return this.client.get<ModelsBox[]>(\n      `https://supplies-api.wildberries.ru/api/v1/supplies/${ID}/package`,\n      { rateLimitKey: 'ordersFBW.getSupplyPackage' }\n    );\n  }\n}\n","/**\n * Finances Module\n * Provides access to Wildberries financial data including balance, transactions, and reports\n *\n * Generated from: wildberries_api_doc/13-finances.yaml\n */\n\nimport { BaseClient } from '../../client/base-client';\nimport { ValidationError } from '../../errors/validation-error';\nimport type {\n  BalanceResponse,\n  TransactionFilters,\n  TransactionListResponse,\n  TransactionDetailResponse,\n  DocumentCategoriesResponse,\n  DocumentsListResponse,\n  DocumentListFilters,\n  DocumentDownloadRequest,\n  DocumentDownloadResponse,\n  DocumentsDownloadResponse,\n  FinancialReportType,\n  ReportFormat,\n  DateRange,\n  GenerateReportResponse,\n  Report,\n  ReportDownloadResponse,\n  PayoutFilters,\n  PayoutListResponse,\n  PayoutDetailResponse,\n} from '../../types/finances.types';\n\n/**\n * FinancesModule\n *\n * Manages financial operations for Wildberries sellers including:\n * - Balance retrieval\n * - Transaction history\n * - Financial reports\n * - Document management\n *\n * @example\n * ```typescript\n * const sdk = new WildberriesSDK({ apiKey: 'your-api-key' });\n *\n * // Get current balance\n * const balance = await sdk.finances.getBalance();\n * console.log(`Available: ${balance.for_withdraw} ${balance.currency}`);\n *\n * // Get transaction history\n * const transactions = await sdk.finances.getTransactions({\n *   dateFrom: '2024-01-01',\n *   dateTo: '2024-01-31',\n *   limit: 100\n * });\n * ```\n */\nexport class FinancesModule {\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Get current account balance\n   *\n   * Retrieves the balance widget data from the seller portal main page,\n   * including current balance and amount available for withdrawal.\n   *\n   * Rate limit: 1 request per minute\n   *\n   * @returns Promise resolving to balance information\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * const balance = await sdk.finances.getBalance();\n   * console.log(`Current: ${balance.current} ${balance.currency}`);\n   * console.log(`Available to withdraw: ${balance.for_withdraw} ${balance.currency}`);\n   * ```\n   */\n  async getBalance(): Promise<BalanceResponse> {\n    return this.client.get<BalanceResponse>(\n      'https://finance-api.wildberries.ru/api/v1/account/balance',\n      { rateLimitKey: 'finances.getBalance' }\n    );\n  }\n\n  /**\n   * Get sales report details by period\n   *\n   * Retrieves detailed sales reports (реализация) with financial transaction data.\n   * Data is available from January 29, 2024.\n   *\n   * The report must be fetched in parts if results exceed 100,000 rows:\n   * 1. Start with rrdid=0\n   * 2. Use the last rrd_id from response for next request\n   * 3. Continue until response is empty []\n   *\n   * Rate limit: 1 request per minute\n   *\n   * @param filters - Date range and pagination filters\n   * @returns Promise resolving to array of transaction/report items\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request parameters invalid (400)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get this week's transactions\n   * const transactions = await sdk.finances.getTransactions({\n   *   dateFrom: '2024-01-15',\n   *   dateTo: '2024-01-22',\n   *   limit: 10000,\n   *   period: 'weekly'\n   * });\n   *\n   * // Paginate through large dataset\n   * let allTransactions = [];\n   * let rrdid = 0;\n   * let hasMore = true;\n   *\n   * while (hasMore) {\n   *   const batch = await sdk.finances.getTransactions({\n   *     dateFrom: '2024-01-01',\n   *     dateTo: '2024-01-31',\n   *     rrdid,\n   *     limit: 100000\n   *   });\n   *\n   *   if (batch.length === 0) {\n   *     hasMore = false;\n   *   } else {\n   *     allTransactions.push(...batch);\n   *     rrdid = batch[batch.length - 1].rrd_id;\n   *   }\n   * }\n   * ```\n   */\n  async getTransactions(filters: TransactionFilters): Promise<TransactionListResponse> {\n    // Validate required parameters\n    if (!filters.dateFrom || !filters.dateTo) {\n      throw new ValidationError(\n        'Both dateFrom and dateTo are required for transaction queries',\n        {\n          dateFrom: filters.dateFrom || 'missing',\n          dateTo: filters.dateTo || 'missing',\n        }\n      );\n    }\n\n    return this.client.get<TransactionListResponse>(\n      'https://statistics-api.wildberries.ru/api/v5/supplier/reportDetailByPeriod',\n      {\n        params: filters,\n        rateLimitKey: 'finances.getTransactions',\n      }\n    );\n  }\n\n  /**\n   * Get single transaction details by ID\n   *\n   * Retrieves complete details for a specific transaction using its rrd_id.\n   * This is a convenience method that filters the transaction list for a specific ID.\n   *\n   * @param transactionId - Unique transaction ID (rrd_id)\n   * @param dateRange - Date range to search within\n   * @returns Promise resolving to transaction details\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When transaction ID invalid or not found\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * const transaction = await sdk.finances.getTransactionById(\n   *   1232610467,\n   *   { dateFrom: '2024-01-01', dateTo: '2024-01-31' }\n   * );\n   * console.log(`Amount: ${transaction.ppvz_for_pay} ${transaction.currency_name}`);\n   * ```\n   */\n  async getTransactionById(\n    transactionId: number,\n    dateRange: { dateFrom: string; dateTo: string }\n  ): Promise<TransactionDetailResponse> {\n    if (!transactionId || transactionId <= 0) {\n      throw new ValidationError('Transaction ID must be a positive number', {\n        transactionId: String(transactionId),\n      });\n    }\n\n    // Fetch transactions and find the specific one\n    // Note: The API doesn't have a direct endpoint for single transaction,\n    // so we filter the list\n    const transactions = await this.getTransactions({\n      ...dateRange,\n      limit: 100000, // Use max limit to ensure we get the transaction\n    });\n\n    const transaction = transactions.find((t) => t.rrd_id === transactionId);\n\n    if (!transaction) {\n      throw new ValidationError('Transaction not found with the given ID', {\n        transactionId: String(transactionId),\n        searchRange: JSON.stringify(dateRange),\n      });\n    }\n\n    return transaction;\n  }\n\n  /**\n   * Get document categories\n   *\n   * Retrieves the list of available document categories for filtering documents.\n   *\n   * Rate limit: 1 request per 10 seconds (burst: 5 requests)\n   *\n   * @param locale - Language for category titles ('ru', 'en', or 'zh')\n   * @returns Promise resolving to document categories\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * const categories = await sdk.finances.getDocumentCategories('ru');\n   * categories.data.categories.forEach(cat => {\n   *   console.log(`${cat.name}: ${cat.title}`);\n   * });\n   * ```\n   */\n  async getDocumentCategories(\n    locale: 'ru' | 'en' | 'zh' = 'en'\n  ): Promise<DocumentCategoriesResponse> {\n    return this.client.get<DocumentCategoriesResponse>(\n      'https://documents-api.wildberries.ru/api/v1/documents/categories',\n      {\n        params: { locale },\n        rateLimitKey: 'finances.getDocumentCategories',\n      }\n    );\n  }\n\n  /**\n   * Get list of documents\n   *\n   * Retrieves the seller's document list with optional filtering by date range and category.\n   *\n   * Rate limit: 1 request per 10 seconds (burst: 5 requests)\n   *\n   * @param filters - Optional filters for document list\n   * @returns Promise resolving to documents list\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get all documents\n   * const docs = await sdk.finances.getDocuments();\n   *\n   * // Filter by date range\n   * const recentDocs = await sdk.finances.getDocuments({\n   *   beginTime: '2024-07-09',\n   *   endTime: '2024-07-15',\n   *   sort: 'date',\n   *   order: 'desc'\n   * });\n   * ```\n   */\n  async getDocuments(filters?: DocumentListFilters): Promise<DocumentsListResponse> {\n    return this.client.get<DocumentsListResponse>(\n      'https://documents-api.wildberries.ru/api/v1/documents/list',\n      {\n        params: filters,\n        rateLimitKey: 'finances.getDocuments',\n      }\n    );\n  }\n\n  /**\n   * Download a single document\n   *\n   * Downloads a specific document by its service name in the requested format.\n   * The document is returned as base64-encoded content.\n   *\n   * Rate limit: 1 request per 10 seconds (burst: 5 requests)\n   *\n   * @param serviceName - Unique document ID\n   * @param extension - Document format (e.g., 'pdf', 'zip', 'xlsx')\n   * @returns Promise resolving to document download response with base64 content\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When document not found or format invalid\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * const doc = await sdk.finances.downloadDocument(\n   *   'redeem-notification-44841941',\n   *   'zip'\n   * );\n   *\n   * // Decode base64 and save to file\n   * const buffer = Buffer.from(doc.data.document, 'base64');\n   * fs.writeFileSync(doc.data.fileName, buffer);\n   * ```\n   */\n  async downloadDocument(\n    serviceName: string,\n    extension: string\n  ): Promise<DocumentDownloadResponse> {\n    if (!serviceName || !extension) {\n      throw new ValidationError('Service name and extension are required', {\n        serviceName: serviceName || 'missing',\n        extension: extension || 'missing',\n      });\n    }\n\n    return this.client.get<DocumentDownloadResponse>(\n      'https://documents-api.wildberries.ru/api/v1/documents/download',\n      {\n        params: { serviceName, extension },\n        rateLimitKey: 'finances.downloadDocument',\n      }\n    );\n  }\n\n  /**\n   * Download multiple documents as archive\n   *\n   * Downloads multiple documents in a single ZIP archive.\n   * Maximum 50 documents per request.\n   *\n   * Rate limit: 1 request per 10 seconds (burst: 5 requests)\n   *\n   * @param documents - Array of document specifications (max 50 items)\n   * @returns Promise resolving to ZIP archive download with base64 content\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request invalid (empty, too many docs, etc)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * const archive = await sdk.finances.downloadDocuments([\n   *   { serviceName: 'doc-123', extension: 'pdf' },\n   *   { serviceName: 'doc-456', extension: 'xlsx' }\n   * ]);\n   *\n   * // Save the ZIP file\n   * const buffer = Buffer.from(archive.data.document, 'base64');\n   * fs.writeFileSync('documents.zip', buffer);\n   * ```\n   */\n  async downloadDocuments(\n    documents: { serviceName: string; extension: string }[]\n  ): Promise<DocumentsDownloadResponse> {\n    if (documents.length === 0) {\n      throw new ValidationError('At least one document must be specified', {\n        count: '0',\n      });\n    }\n\n    if (documents.length > 50) {\n      throw new ValidationError('Maximum 50 documents allowed per request', {\n        count: String(documents.length),\n        max: '50',\n      });\n    }\n\n    const requestBody: DocumentDownloadRequest = {\n      params: documents,\n    };\n\n    return this.client.post<DocumentsDownloadResponse>(\n      'https://documents-api.wildberries.ru/api/v1/documents/download/all',\n      requestBody,\n      { rateLimitKey: 'finances.downloadDocuments' }\n    );\n  }\n\n  // ============================================================================\n  // Financial Reports Methods (Story 3.2)\n  // ============================================================================\n\n  /**\n   * Get financial report for specified date range\n   *\n   * Convenience method that retrieves financial transaction data (реализация) for the specified period.\n   * This is an alias for getTransactions() providing a more intuitive name for financial reporting use cases.\n   *\n   * The report includes detailed sales transactions, commissions, fees, and financial settlements.\n   * For large datasets (>100,000 rows), results must be fetched in parts using rrdid pagination.\n   *\n   * Rate limit: 1 request per minute\n   *\n   * @param filters - Date range filters (dateFrom and dateTo required)\n   * @returns Promise resolving to array of financial transactions\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request parameters invalid (400)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get Q1 financial report\n   * const report = await sdk.finances.getFinancialReport({\n   *   dateFrom: '2024-01-01',\n   *   dateTo: '2024-03-31'\n   * });\n   *\n   * console.log(`Total transactions: ${report.length}`);\n   * report.forEach(transaction => {\n   *   console.log(`${transaction.date}: ${transaction.ppvz_for_pay} ${transaction.currency_name}`);\n   * });\n   * ```\n   */\n  async getFinancialReport(filters: { dateFrom: string; dateTo: string }): Promise<TransactionListResponse> {\n    // Validate required parameters\n    if (!filters.dateFrom || !filters.dateTo) {\n      throw new ValidationError(\n        'Both dateFrom and dateTo are required for financial report queries',\n        {\n          dateFrom: filters.dateFrom || 'missing',\n          dateTo: filters.dateTo || 'missing',\n        }\n      );\n    }\n\n    // Delegate to getTransactions with the date range filters\n    return this.getTransactions(filters);\n  }\n\n  /**\n   * Generate financial report for specified period\n   *\n   * Initiates asynchronous report generation. The report is generated in the background\n   * and the method returns immediately with a report ID and status.\n   *\n   * To get the completed report:\n   * 1. Call this method to initiate generation (returns reportId with 'pending' status)\n   * 2. Poll getReport(reportId) until status becomes 'completed'\n   * 3. Use downloadReport(reportId) to get the download URL\n   *\n   * Rate limit: 2 requests per minute (resource-intensive operation)\n   *\n   * @param reportType - Type of report (sales_summary, tax_report, commission_breakdown, detailed_transactions)\n   * @param dateRange - Date range for report data (from/to dates)\n   * @param format - Optional output format (defaults to PDF)\n   * @returns Promise resolving to report generation status with reportId\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request parameters invalid (400)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Generate sales summary report for Q1\n   * const reportGen = await sdk.finances.generateReport(\n   *   'sales_summary',\n   *   { from: '2024-01-01', to: '2024-03-31' },\n   *   'pdf'\n   * );\n   * console.log(`Report generation started: ${reportGen.reportId}`);\n   * console.log(`Status: ${reportGen.status}`);\n   *\n   * // Poll for completion\n   * let report;\n   * do {\n   *   await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds\n   *   report = await sdk.finances.getReport(reportGen.reportId);\n   * } while (report.status !== 'completed' && report.status !== 'failed');\n   * ```\n   */\n  async generateReport(\n    reportType: FinancialReportType,\n    dateRange: DateRange,\n    format: ReportFormat = 'pdf'\n  ): Promise<GenerateReportResponse> {\n    // Validate date range\n    const fromDate = typeof dateRange.from === 'string' ? new Date(dateRange.from) : dateRange.from;\n    const toDate = typeof dateRange.to === 'string' ? new Date(dateRange.to) : dateRange.to;\n\n    if (fromDate >= toDate) {\n      throw new ValidationError('dateFrom must be before dateTo', {\n        dateFrom: dateRange.from.toString(),\n        dateTo: dateRange.to.toString(),\n      });\n    }\n\n    return this.client.post<GenerateReportResponse>(\n      'https://finance-api.wildberries.ru/api/v1/reports/generate',\n      {\n        reportType,\n        dateRange: {\n          from: typeof dateRange.from === 'string' ? dateRange.from : dateRange.from.toISOString(),\n          to: typeof dateRange.to === 'string' ? dateRange.to : dateRange.to.toISOString(),\n        },\n        format,\n      },\n      { rateLimitKey: 'finances.generateReport' }\n    );\n  }\n\n  /**\n   * Get report status and download URL\n   *\n   * Retrieves current status and details for a report. When status is 'completed',\n   * the response includes a download URL that expires after a certain period.\n   *\n   * Report lifecycle:\n   * - 'pending': Report generation queued\n   * - 'processing': Report being generated\n   * - 'completed': Report ready, download URL available\n   * - 'failed': Report generation failed (check error field)\n   *\n   * Note: Download URLs typically expire after 24 hours.\n   *\n   * Rate limit: 10 requests per minute\n   *\n   * @param reportId - Report identifier from generateReport()\n   * @returns Promise resolving to report details with download URL if completed\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When report ID invalid or not found (404)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Check report status\n   * const report = await sdk.finances.getReport('rpt_abc123');\n   *\n   * if (report.status === 'completed') {\n   *   console.log(`Download URL: ${report.url}`);\n   *   console.log(`Expires at: ${report.expiresAt}`);\n   * } else if (report.status === 'failed') {\n   *   console.error(`Report failed: ${report.error}`);\n   * } else {\n   *   console.log(`Report ${report.status}... please wait`);\n   * }\n   * ```\n   */\n  async getReport(reportId: string): Promise<Report> {\n    if (!reportId.trim()) {\n      throw new ValidationError('Report ID cannot be empty', {\n        reportId: reportId || 'empty',\n      });\n    }\n\n    return this.client.get<Report>(\n      `https://finance-api.wildberries.ru/api/v1/reports/${reportId}`,\n      { rateLimitKey: 'finances.getReport' }\n    );\n  }\n\n  /**\n   * Get download URL for completed report\n   *\n   * Convenience method that validates the report is ready before returning the download URL.\n   * Throws an error if the report is not yet completed.\n   *\n   * @param reportId - Report identifier\n   * @returns Download URL with expiration info\n   * @throws {ValidationError} If report not completed (pending, processing, or failed)\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * try {\n   *   const download = await sdk.finances.downloadReport('rpt_abc123');\n   *   console.log(`Download from: ${download.url}`);\n   *   console.log(`Format: ${download.format}`);\n   *   console.log(`URL expires: ${download.expiresAt}`);\n   * } catch (error) {\n   *   if (error instanceof ValidationError) {\n   *     console.log('Report not ready yet, try again later');\n   *   }\n   * }\n   * ```\n   */\n  async downloadReport(reportId: string): Promise<ReportDownloadResponse> {\n    const report = await this.getReport(reportId);\n\n    if (report.status !== 'completed') {\n      throw new ValidationError(\n        `Report not ready for download. Current status: ${report.status}`,\n        {\n          reportId,\n          status: report.status,\n          error: report.error ?? 'none',\n        }\n      );\n    }\n\n    if (!report.url || !report.expiresAt) {\n      throw new ValidationError('Report completed but download URL not available', {\n        reportId,\n        status: report.status,\n      });\n    }\n\n    return {\n      url: report.url,\n      format: report.format,\n      expiresAt: report.expiresAt,\n    };\n  }\n\n  // ============================================================================\n  // Payouts Methods (Story 3.2)\n  // ============================================================================\n\n  /**\n   * Get payout history with optional filtering\n   *\n   * Retrieves paginated list of payouts with optional filters for date range,\n   * status, and bank account. Includes pagination support for large datasets.\n   *\n   * Payout statuses:\n   * - 'pending': Payout scheduled\n   * - 'processing': Transfer in progress\n   * - 'completed': Successfully transferred\n   * - 'failed': Transfer failed\n   * - 'cancelled': Payout cancelled\n   *\n   * Rate limit: 10 requests per minute\n   *\n   * @param filters - Optional filters for date range, status, bank account, pagination\n   * @returns Promise resolving to paginated payout list\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When filter parameters invalid (400)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * // Get all completed payouts from last month\n   * const payouts = await sdk.finances.getPayouts({\n   *   dateFrom: '2024-01-01',\n   *   dateTo: '2024-01-31',\n   *   status: 'completed',\n   *   limit: 50\n   * });\n   *\n   * console.log(`Found ${payouts.data.length} payouts`);\n   * payouts.data.forEach(payout => {\n   *   console.log(`${payout.date}: ${payout.amount} ${payout.currency}`);\n   * });\n   *\n   * // Paginate through results\n   * if (payouts.pagination?.hasMore) {\n   *   const nextPage = await sdk.finances.getPayouts({\n   *     ...filters,\n   *     offset: payouts.pagination.offset + payouts.pagination.limit\n   *   });\n   * }\n   * ```\n   */\n  async getPayouts(filters?: PayoutFilters): Promise<PayoutListResponse> {\n    return this.client.get<PayoutListResponse>(\n      'https://finance-api.wildberries.ru/api/v1/payouts',\n      {\n        params: filters,\n        rateLimitKey: 'finances.getPayouts',\n      }\n    );\n  }\n\n  /**\n   * Get single payout details with fee breakdown\n   *\n   * Retrieves complete payout information including detailed fee breakdown,\n   * bank transfer information, and list of transactions included in the payout.\n   *\n   * Fee breakdown includes:\n   * - Marketplace commission\n   * - Payment processing fee\n   * - Total fees deducted\n   * - Net amount transferred to seller\n   *\n   * Rate limit: 20 requests per minute\n   *\n   * @param payoutId - Unique payout identifier\n   * @returns Promise resolving to complete payout details with fee breakdown\n   * @throws {AuthenticationError} When API key is invalid (401)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When payout ID invalid or not found (404)\n   * @throws {NetworkError} When network request fails or times out\n   *\n   * @example\n   * ```typescript\n   * const payout = await sdk.finances.getPayoutById('payout_xyz789');\n   *\n   * console.log(`Payout Amount: ${payout.amount} ${payout.currency}`);\n   * console.log(`Status: ${payout.status}`);\n   * console.log(`\\nFee Breakdown:`);\n   * console.log(`  Commission: ${payout.feeBreakdown.commission}`);\n   * console.log(`  Processing Fee: ${payout.feeBreakdown.processingFee}`);\n   * console.log(`  Total Fees: ${payout.feeBreakdown.totalFees}`);\n   * console.log(`  Net Amount: ${payout.feeBreakdown.netAmount}`);\n   * console.log(`\\nBank Transfer:`);\n   * console.log(`  Bank: ${payout.bankInfo.bankName}`);\n   * console.log(`  Account: ${payout.bankInfo.accountNumber}`);\n   * console.log(`  Transfer Date: ${payout.bankInfo.transferDate}`);\n   * ```\n   */\n  async getPayoutById(payoutId: string): Promise<PayoutDetailResponse> {\n    if (!payoutId.trim()) {\n      throw new ValidationError('Payout ID cannot be empty', {\n        payoutId: payoutId || 'empty',\n      });\n    }\n\n    return this.client.get<PayoutDetailResponse>(\n      `https://finance-api.wildberries.ru/api/v1/payouts/${payoutId}`,\n      { rateLimitKey: 'finances.getPayoutById' }\n    );\n  }\n}\n","/**\n * Analytics Module\n * Provides access to Wildberries seller analytics including sales funnel, product performance, and search queries\n *\n * Generated from: wildberries_api_doc/11-analytics.yaml\n */\n\nimport { BaseClient } from '../../client/base-client';\nimport { ValidationError } from '../../errors/validation-error';\nimport type {\n  DateRange,\n  ProductStatisticsRequest,\n  ProductStatisticsResponse,\n  HistoricalStatisticsRequest,\n  HistoricalStatisticsResponse,\n  SearchQueriesResponse,\n  ProductPerformanceResponse,\n  CategoryPerformanceResponse,\n  GenerateReportRequest,\n  GenerateReportResponse,\n  ReportInfo,\n  StockHistoryResponse,\n  AnalyticsReportType,\n  CSVFormatOptions,\n  CSVExportResponse,\n  CSVReport,\n} from '../../types/analytics.types';\n\n/**\n * AnalyticsModule\n *\n * Manages analytics and reporting operations for Wildberries sellers including:\n * - Sales funnel conversion metrics (views → cart → purchases)\n * - Product performance tracking and comparison\n * - Search query analysis and optimization\n * - Category-level performance metrics\n * - Time-series data for trend analysis\n * - CSV report generation\n *\n * @example\n * ```typescript\n * const sdk = new WildberriesSDK({ apiKey: 'your-api-key' });\n *\n * // Get sales funnel metrics\n * const funnel = await sdk.analytics.getSalesFunnel({\n *   from: '2024-01-01',\n *   to: '2024-01-31'\n * });\n * console.log(`Conversion Rate: ${funnel.data.cards[0].statistics.selectedPeriod.conversions.buyoutsPercent}%`);\n *\n * // Compare product performance\n * const performance = await sdk.analytics.getProductPerformance(\n *   ['12345', '67890'],\n *   { from: '2024-01-01', to: '2024-01-31' }\n * );\n * ```\n */\nexport class AnalyticsModule {\n  /**\n   * Creates an instance of AnalyticsModule\n   * @param client - BaseClient instance for making HTTP requests\n   */\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Get sales funnel conversion metrics for products\n   *\n   * Retrieves detailed statistics about product performance including views,\n   * add-to-cart actions, orders, and purchases with conversion rates at each stage.\n   * Compares selected period with previous period to track trends.\n   *\n   * @param request - Product statistics request with filters and period\n   * @returns Promise resolving to product statistics with funnel metrics\n   * @throws {ValidationError} When date range is invalid\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded (3 requests/minute)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Get sales funnel for last 30 days\n   * const funnel = await sdk.analytics.getSalesFunnel({\n   *   period: {\n   *     begin: '2024-01-01 00:00:00',\n   *     end: '2024-01-31 23:59:59'\n   *   },\n   *   page: 1,\n   *   pageSize: 100\n   * });\n   *\n   * funnel.data.cards.forEach(card => {\n   *   const stats = card.statistics.selectedPeriod;\n   *   console.log(`${card.brandName}: ${stats.conversions.buyoutsPercent}% conversion`);\n   * });\n   * ```\n   */\n  async getSalesFunnel(request: ProductStatisticsRequest): Promise<ProductStatisticsResponse> {\n    // Validate period\n    if (request.period.begin >= request.period.end) {\n      throw new ValidationError(\n        'Invalid period: begin date must be before end date',\n        { period: 'Begin date must be before end date' }\n      );\n    }\n\n    return this.client.post<ProductStatisticsResponse>(\n      'https://seller-analytics-api.wildberries.ru/api/v2/nm-report/detail',\n      request,\n      { rateLimitKey: 'analytics.getSalesFunnel' }\n    );\n  }\n\n  /**\n   * Get daily historical statistics for product cards\n   *\n   * Returns time-series data showing product performance by day.\n   * Maximum 7 days of data can be retrieved per request.\n   *\n   * @param request - Historical statistics request with date range and filters\n   * @returns Promise resolving to daily product statistics\n   * @throws {ValidationError} When date range exceeds 7 days\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded (3 requests/minute)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Get daily statistics for specific products\n   * const history = await sdk.analytics.getProductHistory({\n   *   period: {\n   *     begin: '2024-01-01 00:00:00',\n   *     end: '2024-01-07 23:59:59'\n   *   },\n   *   nmIDs: [12345, 67890]\n   * });\n   *\n   * history.data.forEach(product => {\n   *   product.history.forEach(day => {\n   *     console.log(`${day.date}: ${day.ordersCount} orders`);\n   *   });\n   * });\n   * ```\n   */\n  async getProductHistory(request: HistoricalStatisticsRequest): Promise<HistoricalStatisticsResponse> {\n    return this.client.post<HistoricalStatisticsResponse>(\n      'https://seller-analytics-api.wildberries.ru/api/v2/nm-report/detail/history',\n      request,\n      { rateLimitKey: 'analytics.getProductHistory' }\n    );\n  }\n\n  /**\n   * Get performance metrics for specific products\n   *\n   * Analyzes performance of individual products with revenue, units sold,\n   * conversion rates, and return rates. Useful for product comparison.\n   *\n   * @param productIds - Array of product article numbers (nmIDs) to analyze\n   * @param dateRange - Date range for performance data\n   * @returns Promise resolving to product performance metrics\n   * @throws {ValidationError} When productIds is empty or exceeds limit (max 50)\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Compare performance of multiple products\n   * const performance = await sdk.analytics.getProductPerformance(\n   *   [12345, 67890, 11111],\n   *   { from: '2024-01-01', to: '2024-01-31' }\n   * );\n   *\n   * // Sort by revenue\n   * const topPerformers = performance.products\n   *   .sort((a, b) => b.revenue - a.revenue)\n   *   .slice(0, 5);\n   * ```\n   */\n  async getProductPerformance(\n    productIds: number[],\n    dateRange: DateRange\n  ): Promise<ProductPerformanceResponse> {\n    // Validate product IDs\n    if (productIds.length === 0) {\n      throw new ValidationError(\n        'Product IDs array cannot be empty',\n        { productIds: 'Array cannot be empty' }\n      );\n    }\n\n    if (productIds.length > 50) {\n      throw new ValidationError(\n        'Product IDs array cannot exceed 50 items. For larger sets, make multiple requests.',\n        { productIds: `Exceeded maximum of 50 items (received: ${productIds.length})` }\n      );\n    }\n\n    // Validate date range\n    if (dateRange.from >= dateRange.to) {\n      throw new ValidationError(\n        'Invalid date range: from date must be before to date',\n        { dateRange: 'From date must be before to date' }\n      );\n    }\n\n    // Use getSalesFunnel with product IDs filter\n    const response = await this.getSalesFunnel({\n      period: {\n        begin: dateRange.from,\n        end: dateRange.to,\n      },\n      nmIDs: productIds,\n      page: 1,\n      pageSize: productIds.length,\n    });\n\n    // Transform to ProductPerformanceResponse\n    const products = response.data.cards.map(card => ({\n      nmID: card.nmID,\n      vendorCode: card.vendorCode,\n      productName: card.brandName,\n      revenue: card.statistics.selectedPeriod.buyoutsSumRub,\n      unitsSold: card.statistics.selectedPeriod.buyoutsCount,\n      avgPrice: card.statistics.selectedPeriod.avgPriceRub,\n      returnRate: this.calculateReturnRate(\n        card.statistics.selectedPeriod.cancelCount,\n        card.statistics.selectedPeriod.buyoutsCount\n      ),\n      conversionRate: card.statistics.selectedPeriod.conversions.buyoutsPercent,\n    }));\n\n    return {\n      products,\n      error: response.error,\n      errorText: response.errorText,\n      additionalErrors: response.additionalErrors,\n    };\n  }\n\n  /**\n   * Get search queries that led to product views\n   *\n   * Note: This endpoint returns search query data. The actual implementation\n   * depends on the search-report endpoints in the OpenAPI spec.\n   *\n   * @param dateRange - Date range for search query data\n   * @returns Promise resolving to search query metrics\n   * @throws {ValidationError} When date range is invalid\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Get top search queries\n   * const queries = await sdk.analytics.getSearchQueries({\n   *   from: '2024-01-01',\n   *   to: '2024-01-31'\n   * });\n   *\n   * // Find high-volume low-conversion queries for optimization\n   * const opportunities = queries.data\n   *   .filter(q => q.searchCount > 1000 && q.conversionRate < 2)\n   *   .sort((a, b) => b.searchCount - a.searchCount);\n   * ```\n   */\n  async getSearchQueries(dateRange: DateRange): Promise<SearchQueriesResponse> {\n    // Validate date range\n    if (dateRange.from >= dateRange.to) {\n      throw new ValidationError(\n        'Invalid date range: from date must be before to date',\n        { dateRange: 'From date must be before to date' }\n      );\n    }\n\n    // Note: Using placeholder endpoint - actual endpoint may differ\n    return this.client.get<SearchQueriesResponse>(\n      'https://seller-analytics-api.wildberries.ru/api/v2/search-report/report',\n      {\n        params: {\n          dateFrom: dateRange.from,\n          dateTo: dateRange.to,\n        },\n        rateLimitKey: 'analytics.getSearchQueries',\n      }\n    );\n  }\n\n  /**\n   * Get category-level performance metrics\n   *\n   * Analyzes performance at category level including revenue, units sold,\n   * product count, and top performers within the category.\n   *\n   * @param categoryId - Category identifier (object ID)\n   * @param dateRange - Date range for category analysis\n   * @returns Promise resolving to category performance metrics\n   * @throws {ValidationError} When categoryId is invalid or date range is invalid\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Analyze category performance\n   * const category = await sdk.analytics.getCategoryPerformance(\n   *   '447',  // Category ID\n   *   { from: '2024-01-01', to: '2024-01-31' }\n   * );\n   *\n   * console.log(`Category Revenue: ${category.data.revenue} RUB`);\n   * console.log(`Top Products:`, category.data.topProducts.slice(0, 5));\n   * ```\n   */\n  async getCategoryPerformance(\n    categoryId: string,\n    dateRange: DateRange\n  ): Promise<CategoryPerformanceResponse> {\n    // Validate category ID\n    if (!categoryId || categoryId.trim() === '') {\n      throw new ValidationError(\n        'Category ID cannot be empty',\n        { categoryId: 'Category ID cannot be empty' }\n      );\n    }\n\n    // Validate date range\n    if (dateRange.from >= dateRange.to) {\n      throw new ValidationError(\n        'Invalid date range: from date must be before to date',\n        { dateRange: 'From date must be before to date' }\n      );\n    }\n\n    // Get products in this category\n    const response = await this.getSalesFunnel({\n      period: {\n        begin: dateRange.from,\n        end: dateRange.to,\n      },\n      objectIDs: [parseInt(categoryId, 10)],\n      page: 1,\n      pageSize: 1000,\n    });\n\n    // Aggregate category metrics\n    const cards = response.data.cards;\n    const totalRevenue = cards.reduce((sum, card) =>\n      sum + card.statistics.selectedPeriod.buyoutsSumRub, 0\n    );\n    const totalUnitsSold = cards.reduce((sum, card) =>\n      sum + card.statistics.selectedPeriod.buyoutsCount, 0\n    );\n\n    // Get top 10 products by revenue\n    const topProducts = cards\n      .sort((a, b) =>\n        b.statistics.selectedPeriod.buyoutsSumRub - a.statistics.selectedPeriod.buyoutsSumRub\n      )\n      .slice(0, 10)\n      .map(card => ({\n        nmID: card.nmID,\n        name: card.brandName,\n        revenue: card.statistics.selectedPeriod.buyoutsSumRub,\n        unitsSold: card.statistics.selectedPeriod.buyoutsCount,\n      }));\n\n    return {\n      data: {\n        categoryId,\n        categoryName: cards[0]?.object.name || 'Unknown',\n        revenue: totalRevenue,\n        unitsSold: totalUnitsSold,\n        productCount: cards.length,\n        topProducts,\n      },\n      error: false,\n      errorText: '',\n    };\n  }\n\n  /**\n   * Generate CSV/Excel report for analytics data\n   *\n   * Creates an asynchronous report generation task. Use getReport() to\n   * check status and retrieve download URL when complete.\n   *\n   * @param request - Report generation request with type, format, and filters\n   * @returns Promise resolving to report generation response with reportId\n   * @throws {ValidationError} When request parameters are invalid\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded (2 requests/minute)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Generate sales funnel CSV report\n   * const report = await sdk.analytics.generateReport({\n   *   reportType: 'sales_funnel',\n   *   dateRange: { from: '2024-01-01', to: '2024-01-31' },\n   *   format: 'CSV'\n   * });\n   *\n   * console.log(`Report ID: ${report.reportId}`);\n   * console.log(`Status: ${report.status}`);\n   * ```\n   */\n  async generateReport(request: GenerateReportRequest): Promise<GenerateReportResponse> {\n    // Validate date range\n    if (request.dateRange.from >= request.dateRange.to) {\n      throw new ValidationError(\n        'Invalid date range: from date must be before to date',\n        { dateRange: 'From date must be before to date' }\n      );\n    }\n\n    return this.client.post<GenerateReportResponse>(\n      'https://seller-analytics-api.wildberries.ru/api/v2/nm-report/downloads',\n      request,\n      { rateLimitKey: 'analytics.generateReport' }\n    );\n  }\n\n  /**\n   * Get report status and download information\n   *\n   * Checks the status of a previously generated report and provides\n   * download URL when the report is ready.\n   *\n   * @param reportId - Report identifier from generateReport()\n   * @returns Promise resolving to report info with status and download URL\n   * @throws {ValidationError} When reportId is invalid\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded (10 requests/minute)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Check report status\n   * const info = await sdk.analytics.getReport(reportId);\n   *\n   * if (info.status === 'completed') {\n   *   console.log(`Download: ${info.downloadUrl}`);\n   *   console.log(`Expires: ${info.expiresAt}`);\n   * } else {\n   *   console.log(`Status: ${info.status}`);\n   * }\n   * ```\n   */\n  async getReport(reportId: string): Promise<ReportInfo> {\n    // Validate report ID\n    if (!reportId || reportId.trim() === '') {\n      throw new ValidationError(\n        'Report ID cannot be empty',\n        { reportId: 'Report ID cannot be empty' }\n      );\n    }\n\n    return this.client.get<ReportInfo>(\n      `https://seller-analytics-api.wildberries.ru/api/v2/nm-report/downloads/file/${reportId}`,\n      { rateLimitKey: 'analytics.getReport' }\n    );\n  }\n\n  /**\n   * Download completed report (helper method)\n   *\n   * Convenience method that checks report status and returns download URL\n   * only when the report is completed.\n   *\n   * @param reportId - Report identifier from generateReport()\n   * @returns Promise resolving to download information\n   * @throws {ValidationError} When report is not completed\n   *\n   * @example\n   * ```typescript\n   * const download = await sdk.analytics.downloadReport(reportId);\n   * console.log(`Download URL: ${download.url}`);\n   * console.log(`Format: ${download.format}`);\n   * ```\n   */\n  async downloadReport(reportId: string): Promise<{ url: string; format: string; expiresAt?: string }> {\n    const info = await this.getReport(reportId);\n\n    if (info.status !== 'completed') {\n      throw new ValidationError(\n        `Report is not ready for download. Current status: ${info.status}`,\n        { status: `Report status is ${info.status}, expected 'completed'` }\n      );\n    }\n\n    if (!info.downloadUrl) {\n      throw new ValidationError(\n        'Report is completed but download URL is not available',\n        { downloadUrl: 'Download URL is not available' }\n      );\n    }\n\n    return {\n      url: info.downloadUrl,\n      format: info.format,\n      expiresAt: info.expiresAt,\n    };\n  }\n\n  /**\n   * Get historical stock level changes for a product\n   *\n   * Retrieves complete stock history showing all stock level changes over time,\n   * including the reason for each change (sales, returns, adjustments, transfers,\n   * damaged goods, lost inventory).\n   *\n   * Use this data for:\n   * - Inventory trend analysis\n   * - Stock velocity calculations (average daily sales)\n   * - Restock date predictions\n   * - Identifying slow-moving inventory\n   * - Tracking warehouse transfers and adjustments\n   *\n   * Rate limit: 10 requests per minute\n   *\n   * @param productId - Product article number (nmID) or vendor code\n   * @param dateRange - Date range for stock history (max 90 days recommended)\n   * @returns Promise resolving to stock changes with time-series summary\n   * @throws {ValidationError} When productId is empty or dateRange is invalid\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded (10 requests/minute)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Get stock history for product\n   * const history = await sdk.analytics.getStockHistory(\n   *   'prod_123',\n   *   { from: '2024-01-01', to: '2024-12-31' }\n   * );\n   *\n   * console.log('Stock Changes:', history.changes.length);\n   * console.log('Starting Stock:', history.summary.startingStock);\n   * console.log('Ending Stock:', history.summary.endingStock);\n   * console.log('Net Change:', history.summary.netChange);\n   * console.log('Avg Daily Velocity:', history.summary.avgDailyVelocity.toFixed(2), 'units/day');\n   *\n   * // Analyze stock changes by reason\n   * const salesChanges = history.changes.filter(c => c.reason === 'sale');\n   * const returnChanges = history.changes.filter(c => c.reason === 'return');\n   * console.log(`Sales: ${salesChanges.length}, Returns: ${returnChanges.length}`);\n   * ```\n   */\n  async getStockHistory(\n    productId: string,\n    dateRange: DateRange\n  ): Promise<StockHistoryResponse> {\n    // Validate product ID\n    if (!productId || productId.trim() === '') {\n      throw new ValidationError(\n        'Product ID cannot be empty',\n        { productId: 'Product ID cannot be empty' }\n      );\n    }\n\n    // Validate date range\n    if (dateRange.from >= dateRange.to) {\n      throw new ValidationError(\n        'Invalid date range: from date must be before to date',\n        { dateRange: 'From date must be before to date' }\n      );\n    }\n\n    return this.client.get<StockHistoryResponse>(\n      `https://seller-analytics-api.wildberries.ru/api/v1/analytics/stock-history/${encodeURIComponent(productId)}`,\n      {\n        params: {\n          dateFrom: dateRange.from,\n          dateTo: dateRange.to,\n        },\n        rateLimitKey: 'analytics.getStockHistory',\n      }\n    );\n  }\n\n  /**\n   * Generate CSV export of analytics data (asynchronous)\n   *\n   * Initiates CSV generation for analytics data. The export is processed\n   * asynchronously, returning a report ID immediately. Use getCSVReportStatus()\n   * to poll for completion and retrieve the download URL.\n   *\n   * Supported report types:\n   * - `sales_funnel`: Sales conversion funnel data\n   * - `product_performance`: Product-level performance metrics\n   * - `stock_history`: Historical stock changes\n   * - `search_queries`: Search query analytics\n   *\n   * CSV format options:\n   * - Delimiter: comma (`,`), semicolon (`;`), or tab (`\\t`)\n   * - Headers: Include/exclude column headers\n   * - Encoding: UTF-8 or UTF-8 with BOM (for Excel compatibility)\n   *\n   * Rate limit: 2 requests per minute (stricter due to resource-intensive operation)\n   *\n   * @param reportType - Type of analytics data to export\n   * @param dateRange - Date range for the exported data\n   * @param options - Optional CSV formatting options\n   * @returns Promise resolving to export status with reportId for tracking\n   * @throws {ValidationError} When reportType is invalid or dateRange exceeds limits\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded (2 requests/minute)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Export product performance to CSV for Excel\n   * const csvExport = await sdk.analytics.exportAnalyticsCSV(\n   *   'product_performance',\n   *   { from: '2024-01-01', to: '2024-12-31' },\n   *   {\n   *     delimiter: ';',           // European Excel format\n   *     includeHeaders: true,\n   *     encoding: 'utf-8-bom'     // Excel compatibility\n   *   }\n   * );\n   *\n   * console.log(`CSV export started: ${csvExport.reportId}`);\n   * console.log(`Status: ${csvExport.status}`);\n   * console.log(`ETA: ${csvExport.estimatedCompletionTime}`);\n   *\n   * // Poll for completion (see getCSVReportStatus example)\n   * ```\n   */\n  async exportAnalyticsCSV(\n    reportType: AnalyticsReportType,\n    dateRange: DateRange,\n    options?: CSVFormatOptions\n  ): Promise<CSVExportResponse> {\n    // Validate report type\n    const validTypes: AnalyticsReportType[] = [\n      'sales_funnel',\n      'product_performance',\n      'stock_history',\n      'search_queries',\n    ];\n\n    if (!validTypes.includes(reportType)) {\n      throw new ValidationError(\n        `Invalid report type: ${reportType}. Must be one of: ${validTypes.join(', ')}`,\n        { reportType: `Invalid type: ${reportType}` }\n      );\n    }\n\n    // Validate date range\n    if (dateRange.from >= dateRange.to) {\n      throw new ValidationError(\n        'Invalid date range: from date must be before to date',\n        { dateRange: 'From date must be before to date' }\n      );\n    }\n\n    // Build request body with format options\n    const requestBody = {\n      reportType,\n      dateRange,\n      delimiter: options?.delimiter ?? ',',\n      includeHeaders: options?.includeHeaders ?? true,\n      encoding: options?.encoding ?? 'utf-8',\n    };\n\n    return this.client.post<CSVExportResponse>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/export/csv',\n      requestBody,\n      { rateLimitKey: 'analytics.exportCSV' }\n    );\n  }\n\n  /**\n   * Check CSV export status and get download URL\n   *\n   * Checks the status of a previously initiated CSV export and provides\n   * download URL when the report is ready. Poll this endpoint until status\n   * becomes 'completed'.\n   *\n   * Status lifecycle:\n   * - `pending`: Export queued, not yet started\n   * - `processing`: CSV generation in progress\n   * - `completed`: CSV ready for download (downloadUrl available)\n   * - `failed`: Export failed (check errorMessage)\n   *\n   * Download URLs:\n   * - Pre-signed URLs (typically S3/CDN)\n   * - Expire after 24 hours (check expiresAt field)\n   * - Direct file download, not through API\n   *\n   * Rate limit: 10 requests per minute\n   *\n   * @param reportId - Report identifier from exportAnalyticsCSV()\n   * @returns Promise resolving to CSV report details with download URL if completed\n   * @throws {ValidationError} When reportId is invalid\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded (10 requests/minute)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Poll for CSV completion\n   * const reportId = 'csv_abc123';\n   * let csvReport;\n   *\n   * do {\n   *   await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5s\n   *   csvReport = await sdk.analytics.getCSVReportStatus(reportId);\n   *   console.log(`Status: ${csvReport.status}`);\n   * } while (csvReport.status === 'pending' || csvReport.status === 'processing');\n   *\n   * if (csvReport.status === 'completed') {\n   *   console.log(`Download: ${csvReport.downloadUrl}`);\n   *   console.log(`File size: ${csvReport.fileSize} bytes`);\n   *   console.log(`Rows: ${csvReport.rowCount}`);\n   *   console.log(`Expires: ${csvReport.expiresAt}`);\n   * } else {\n   *   console.error(`Export failed: ${csvReport.errorMessage}`);\n   * }\n   * ```\n   */\n  async getCSVReportStatus(reportId: string): Promise<CSVReport> {\n    // Validate report ID\n    if (!reportId || reportId.trim() === '') {\n      throw new ValidationError(\n        'Report ID cannot be empty',\n        { reportId: 'Report ID cannot be empty' }\n      );\n    }\n\n    return this.client.get<CSVReport>(\n      `https://seller-analytics-api.wildberries.ru/api/v1/analytics/export/csv/${encodeURIComponent(reportId)}`,\n      { rateLimitKey: 'analytics.getCSVReportStatus' }\n    );\n  }\n\n  /**\n   * Get download URL for completed CSV report (helper method)\n   *\n   * Convenience method that checks report status and returns download details\n   * only when the report is completed. Throws ValidationError if report is not ready.\n   *\n   * Use this when you want to fail fast if the report isn't ready, rather than\n   * checking status manually.\n   *\n   * @param reportId - Report identifier from exportAnalyticsCSV()\n   * @returns Promise resolving to CSV report with download URL\n   * @throws {ValidationError} When report is not completed or URL is missing\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit is exceeded\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * try {\n   *   const csvReport = await sdk.analytics.downloadCSVReport(reportId);\n   *   console.log(`Download: ${csvReport.downloadUrl}`);\n   *   console.log(`File size: ${csvReport.fileSize} bytes`);\n   *\n   *   // Download file using HTTP client\n   *   // In browser: window.open(csvReport.downloadUrl)\n   *   // In Node.js: axios.get(csvReport.downloadUrl, { responseType: 'stream' })\n   * } catch (error) {\n   *   if (error instanceof ValidationError) {\n   *     console.error('Report not ready yet, try again later');\n   *   }\n   * }\n   * ```\n   */\n  async downloadCSVReport(reportId: string): Promise<CSVReport> {\n    const report = await this.getCSVReportStatus(reportId);\n\n    if (report.status !== 'completed') {\n      throw new ValidationError(\n        `CSV report not ready. Current status: ${report.status}`,\n        { status: `Report status is ${report.status}, expected 'completed'` }\n      );\n    }\n\n    if (!report.downloadUrl) {\n      throw new ValidationError(\n        'CSV report has no download URL',\n        { downloadUrl: 'Download URL is missing' }\n      );\n    }\n\n    return report;\n  }\n\n  // ==================== Helper Methods ====================\n\n  /**\n   * Calculate return rate percentage\n   *\n   * @param returns - Number of returns/cancellations\n   * @param sales - Number of sales/purchases\n   * @returns Return rate as percentage (0-100)\n   * @private\n   */\n  private calculateReturnRate(returns: number, sales: number): number {\n    if (sales === 0) return 0;\n    return (returns / sales) * 100;\n  }\n\n  // NOTE: Stock analysis utilities removed for v1.0 (aggregateStockChanges, calculateStockVelocity, predictRestockDate)\n  // These analytics features are planned for v1.1 as public utility methods\n  // Track implementation progress in project roadmap\n}\n","/**\n * Communications Module\n *\n * This module implements the Wildberries Chat with Customers API,\n * enabling sellers to communicate with buyers through the marketplace.\n *\n * ## Event-Based Architecture\n *\n * The Chat API uses an event-based architecture where:\n * - A single events stream contains messages for ALL chats\n * - Events are retrieved using cursor-based pagination\n * - Client-side filtering is required to view specific conversations\n * - The `replySign` is required to send messages and is obtained from:\n *   1. `Chat.replySign` from `getChats()`\n *   2. `Event.replySign` from `getChatEvents()` when `isNewChat: true`\n *\n * ## Typical Workflow\n *\n * 1. **Get All Chats**: Call `getChats()` to fetch all active conversations\n * 2. **Poll for Events**: Call `getChatEvents()` periodically to monitor new messages\n * 3. **Filter Events**: Filter events by `chatID` and `sender` as needed (client-side)\n * 4. **Extract replySign**: Get `replySign` from Chat or new chat events\n * 5. **Send Messages**: Use `sendMessage(replySign, message)` to reply\n *\n * ## Rate Limits\n *\n * All chat endpoints have the same rate limit:\n * - **10 requests per 10 seconds** (1 request/second average, burst of 10)\n *\n * For polling, use a minimum interval of 10 seconds to stay within limits.\n *\n * @module CommunicationsModule\n *\n * @example\n * ```typescript\n * // Get all chats\n * const chatsResponse = await sdk.communications.getChats();\n * const chats = chatsResponse.result;\n *\n * // Poll for new events\n * const eventsResponse = await sdk.communications.getChatEvents();\n * const { events, next, totalEvents } = eventsResponse.result;\n *\n * // Continue pagination\n * if (totalEvents > 0) {\n *   const moreEvents = await sdk.communications.getChatEvents(next);\n * }\n *\n * // Send message\n * const replySign = chats[0].replySign;\n * await sdk.communications.sendMessage(replySign, 'Thank you for your message!');\n * ```\n */\n\nimport type { BaseClient } from '../../client/base-client';\nimport type {\n  ChatsResponse,\n  EventsResponse,\n  MessageResponse,\n  ChatEvent,\n  Chat,\n  QuestionFilters,\n  QuestionsResponse,\n  AnswerQuestionRequest,\n  MarkQuestionViewedRequest,\n  ReviewFilters,\n  ReviewsResponse,\n  RespondToReviewRequest,\n} from '../../types/communications.types';\nimport { ValidationError } from '../../errors/validation-error';\n\n/**\n * CommunicationsModule class\n *\n * Provides methods for interacting with the Wildberries Chat with Customers API.\n */\nexport class CommunicationsModule {\n  /**\n   * Creates a new CommunicationsModule instance\n   *\n   * @param client - The BaseClient instance for making HTTP requests\n   */\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Get all chat conversations\n   *\n   * This method retrieves ALL active chat conversations with customers.\n   * The API does not support filtering, so all chats are returned in a single response.\n   *\n   * Each chat includes a `replySign` field which is required for sending messages\n   * to that chat via `sendMessage()`.\n   *\n   * **Rate Limit**: 10 requests per 10 seconds\n   *\n   * @returns Promise resolving to list of all chats with replySign for each\n   *\n   * @throws {AuthenticationError} When API key is invalid or missing\n   * @throws {RateLimitError} When rate limit is exceeded (429)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * const chatsResponse = await sdk.communications.getChats();\n   * const chats = chatsResponse.result;\n   *\n   * console.log(`You have ${chats.length} active chats`);\n   *\n   * // Extract replySign for sending messages\n   * chats.forEach(chat => {\n   *   console.log(`Chat ${chat.chatID} with ${chat.clientName}`);\n   *   console.log(`Reply sign: ${chat.replySign}`);\n   * });\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/user-communication#tag/Chat-s-pokupatelyami/paths/~1api~1v1~1seller~1chats/get}\n   */\n  async getChats(): Promise<ChatsResponse> {\n    return this.client.get<ChatsResponse>(\n      'https://buyer-chat-api.wildberries.ru/api/v1/seller/chats',\n      { rateLimitKey: 'communications.getChats' }\n    );\n  }\n\n  /**\n   * Get chat events using cursor pagination\n   *\n   * This method retrieves events for ALL chats (not per-chat).\n   * The API uses cursor-based pagination with the `next` parameter.\n   *\n   * **Event-Based Architecture**:\n   * - Returns events for ALL chats in a single stream\n   * - Use `next` parameter for pagination (Unix timestamp with milliseconds)\n   * - Continue fetching until `totalEvents` equals 0\n   * - Client-side filtering required to view events for specific chats\n   *\n   * **Cursor Pagination Pattern**:\n   * 1. First request: Call without `next` parameter\n   * 2. Subsequent requests: Use `next` value from previous response\n   * 3. Stop when `totalEvents` is 0 (no more events)\n   *\n   * **Rate Limit**: 10 requests per 10 seconds\n   *\n   * @param next - Optional cursor timestamp (Unix timestamp with milliseconds) from previous response\n   * @returns Promise resolving to events with pagination cursor\n   *\n   * @throws {ValidationError} When next parameter is invalid (must be positive number)\n   * @throws {AuthenticationError} When API key is invalid or missing\n   * @throws {RateLimitError} When rate limit is exceeded (429)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // First request (no cursor)\n   * const firstPage = await sdk.communications.getChatEvents();\n   * console.log(`Found ${firstPage.result.totalEvents} events`);\n   *\n   * // Continue pagination\n   * let cursor = firstPage.result.next;\n   * while (firstPage.result.totalEvents > 0) {\n   *   const nextPage = await sdk.communications.getChatEvents(cursor);\n   *   console.log(`Fetched ${nextPage.result.events.length} more events`);\n   *\n   *   if (nextPage.result.totalEvents === 0) break;\n   *   cursor = nextPage.result.next;\n   * }\n   * ```\n   *\n   * @example\n   * ```typescript\n   * // Filter events for specific chat\n   * const eventsResponse = await sdk.communications.getChatEvents();\n   * const chatID = '1:4019cd7d-cca8-4e90-8b11-f78afbea42e3';\n   * const chatEvents = eventsResponse.result.events.filter(e => e.chatID === chatID);\n   *\n   * // Filter only customer messages\n   * const customerMessages = eventsResponse.result.events.filter(e => e.sender === 'client');\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/user-communication#tag/Chat-s-pokupatelyami/paths/~1api~1v1~1seller~1events/get}\n   */\n  async getChatEvents(next?: number): Promise<EventsResponse> {\n    // Validate next parameter if provided\n    if (next !== undefined) {\n      if (typeof next !== 'number' || next <= 0) {\n        throw new ValidationError(\n          'Invalid next parameter: must be a positive number (Unix timestamp with milliseconds)',\n          { next: `Invalid value: ${next}. Expected positive number (Unix timestamp with milliseconds).` }\n        );\n      }\n    }\n\n    const params = next ? { next } : {};\n\n    return this.client.get<EventsResponse>(\n      'https://buyer-chat-api.wildberries.ru/api/v1/seller/events',\n      { params, rateLimitKey: 'communications.getChatEvents' }\n    );\n  }\n\n  /**\n   * Send message to customer chat\n   *\n   * Sends a text message and/or file attachments to a customer chat conversation.\n   * Uses multipart/form-data format for file uploads.\n   *\n   * **Required Parameters**:\n   * - `replySign`: Chat signature from `getChats()` or `getChatEvents()` (when isNewChat=true)\n   * - At least one of: `message` (text) or `files` (attachments)\n   *\n   * **Message Constraints**:\n   * - Text: Maximum 1000 characters\n   * - Files: JPEG, PDF, PNG only\n   * - File size: 5MB per file, 30MB total\n   *\n   * **Rate Limit**: 10 requests per 10 seconds\n   *\n   * @param replySign - Chat signature (required, max 255 characters)\n   * @param message - Optional message text (max 1000 characters)\n   * @param files - Optional file attachments (File[] or Blob[])\n   * @returns Promise resolving to sent message confirmation with chatID and addTime\n   *\n   * @throws {ValidationError} When replySign is empty, too long, or message exceeds 1000 chars\n   * @throws {ValidationError} When neither message nor files are provided\n   * @throws {ValidationError} When file type is unsupported or size exceeds limits\n   * @throws {AuthenticationError} When API key is invalid or missing\n   * @throws {RateLimitError} When rate limit is exceeded (429)\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Text-only message\n   * const replySign = chat.replySign;\n   * await sdk.communications.sendMessage(\n   *   replySign,\n   *   'Thank you for your message! We will help you shortly.'\n   * );\n   * ```\n   *\n   * @example\n   * ```typescript\n   * // Message with file attachments\n   * const files = [\n   *   new File([pdfBlob], 'receipt.pdf', { type: 'application/pdf' }),\n   *   new File([imageBlob], 'photo.jpg', { type: 'image/jpeg' })\n   * ];\n   *\n   * await sdk.communications.sendMessage(\n   *   replySign,\n   *   'Here are the requested documents.',\n   *   files\n   * );\n   * ```\n   *\n   * @example\n   * ```typescript\n   * // Files only (no text)\n   * await sdk.communications.sendMessage(replySign, undefined, files);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/user-communication#tag/Chat-s-pokupatelyami/paths/~1api~1v1~1seller~1message/post}\n   */\n  async sendMessage(\n    replySign: string,\n    message?: string,\n    files?: File[] | Blob[]\n  ): Promise<MessageResponse> {\n    // Validate replySign (required, max 255 characters)\n    if (replySign.trim().length === 0) {\n      throw new ValidationError(\n        'replySign is required',\n        { replySign: 'This field is required. Obtain from Chat.replySign or Event.replySign (when isNewChat=true).' }\n      );\n    }\n\n    if (replySign.length > 255) {\n      throw new ValidationError(\n        'replySign exceeds maximum length',\n        { replySign: `Maximum length is 255 characters. Received ${replySign.length} characters.` }\n      );\n    }\n\n    // Validate message length if provided\n    if (message !== undefined && message.length > 1000) {\n      throw new ValidationError(\n        'message exceeds maximum length',\n        { message: `Maximum length is 1000 characters. Received ${message.length} characters.` }\n      );\n    }\n\n    // Validate that at least one of message or files is provided\n    if (!message && (!files || files.length === 0)) {\n      throw new ValidationError(\n        'At least one of message or files must be provided',\n        {\n          message: 'Either provide message text or file attachments.',\n          files: 'Either provide message text or file attachments.',\n        }\n      );\n    }\n\n    // Build FormData for multipart/form-data request\n    // Based on Context7 axios documentation for file uploads\n    const formData = new FormData();\n    formData.append('replySign', replySign);\n\n    if (message) {\n      formData.append('message', message);\n    }\n\n    if (files && files.length > 0) {\n      files.forEach((file) => {\n        formData.append('file', file);\n      });\n    }\n\n    return this.client.post<MessageResponse>(\n      'https://buyer-chat-api.wildberries.ru/api/v1/seller/message',\n      formData,\n      {\n        rateLimitKey: 'communications.sendMessage',\n        headers: { 'Content-Type': 'multipart/form-data' },\n      }\n    );\n  }\n\n  /**\n   * Poll for new chat events (message-based updates)\n   *\n   * Sets up periodic polling for new chat events using cursor-based pagination.\n   * Automatically tracks the cursor across polling cycles and invokes the callback\n   * with new events when they arrive.\n   *\n   * **Polling Pattern**:\n   * - Uses cursor from previous response for subsequent requests\n   * - Only invokes callback when `totalEvents > 0`\n   * - Continues polling until `stop()` is called\n   * - Handles errors gracefully (continues polling on transient errors)\n   *\n   * **Best Practices**:\n   * - Minimum interval: 10 seconds (matches rate limit: 10 req/10s)\n   * - Use `stop()` function for graceful shutdown\n   * - Handle errors in callback to prevent polling interruption\n   *\n   * @param intervalMs - Polling interval in milliseconds (default: 10000ms, min recommended: 10000ms)\n   * @param callback - Function called with new events (can be async)\n   * @returns Object with `stop()` method to cancel polling\n   *\n   * @example\n   * ```typescript\n   * // Start polling for new events every 10 seconds\n   * const polling = sdk.communications.pollForNewEvents(10000, async (events) => {\n   *   console.log(`Received ${events.length} new events`);\n   *\n   *   // Process customer messages\n   *   const customerMessages = events.filter(e => e.sender === 'client');\n   *   for (const event of customerMessages) {\n   *     console.log(`New message from ${event.clientName}: ${event.message?.text}`);\n   *\n   *     // Auto-respond (example)\n   *     if (event.isNewChat && event.replySign) {\n   *       await sdk.communications.sendMessage(\n   *         event.replySign,\n   *         'Thank you for contacting us! We will respond shortly.'\n   *       );\n   *     }\n   *   }\n   * });\n   *\n   * // Stop polling when done (e.g., on application shutdown)\n   * process.on('SIGTERM', () => {\n   *   polling.stop();\n   * });\n   * ```\n   *\n   * @see {@link getChatEvents} for manual event fetching\n   */\n  pollForNewEvents(\n    intervalMs = 10000,\n    callback: (events: ChatEvent[]) => void | Promise<void>\n  ): { stop: () => void } {\n    let cursor: number | undefined;\n\n    const poll = async () => {\n      try {\n        const response = await this.getChatEvents(cursor);\n        const { events, next, totalEvents } = response.result;\n\n        // Update cursor for next iteration\n        cursor = next;\n\n        // Invoke callback with new events if any\n        if (totalEvents > 0 && events.length > 0) {\n          await callback(events);\n        }\n      } catch {\n        // Silently continue polling on errors (graceful degradation)\n        // Users can handle errors in their callback if needed\n      }\n    };\n\n    // Start polling immediately, then at intervals\n    void poll();\n    const intervalId = setInterval(() => {\n      void poll();\n    }, intervalMs);\n\n    return {\n      stop: () => {\n        clearInterval(intervalId);\n      },\n    };\n  }\n\n  // ============================================================================\n  // Product Q&A Methods\n  // ============================================================================\n\n  /**\n   * Get product questions with filtering\n   *\n   * Retrieves customer questions about products with support for filtering by\n   * answered status, product ID, date range, and pagination.\n   *\n   * **Pagination Limits**:\n   * - Maximum 10,000 questions per response\n   * - `take + skip` must not exceed 10,000\n   *\n   * **Question States**:\n   * - `suppliersPortalSynch` — New unanswered question\n   * - `wbRu` — Answered question visible to customers\n   * - `none` — Rejected question (not visible)\n   *\n   * **Rate Limit**: 3 requests per second (burst: 6)\n   *\n   * @param filters - Filter criteria (isAnswered, take, skip required; nmId, order, dateFrom, dateTo optional)\n   * @returns Promise resolving to questions with counts and product details\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When required filters missing\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Get unanswered questions sorted by newest first\n   * const response = await sdk.communications.getQuestions({\n   *   isAnswered: false,\n   *   take: 20,\n   *   skip: 0,\n   *   order: 'dateDesc'\n   * });\n   *\n   * console.log(`${response.data.countUnanswered} unanswered questions`);\n   * for (const q of response.data.questions) {\n   *   console.log(`Q: ${q.text}`);\n   *   console.log(`Product: ${q.productDetails.productName} (nmId: ${q.productDetails.nmId})`);\n   * }\n   *\n   * // Filter questions for specific product\n   * const productQuestions = await sdk.communications.getQuestions({\n   *   isAnswered: false,\n   *   nmId: 12345,\n   *   take: 10,\n   *   skip: 0\n   * });\n   * ```\n   */\n  async getQuestions(filters: QuestionFilters): Promise<QuestionsResponse> {\n    return this.client.get<QuestionsResponse>(\n      'https://feedbacks-api.wildberries.ru/api/v1/questions',\n      {\n        params: filters as Record<string, unknown>,\n        rateLimitKey: 'communications.getQuestions',\n      }\n    );\n  }\n\n  /**\n   * Answer or reject product question\n   *\n   * Provides an answer to a customer question or rejects it. Answered questions\n   * with state `wbRu` are visible to all customers on the product page.\n   *\n   * **Answer Editing**:\n   * - Can edit answer once within 60 days of original response\n   * - Check `question.answer.editable` field before attempting edit\n   * - Use same method to edit (just call with updated text)\n   *\n   * **Question States**:\n   * - `wbRu` — Answer visible to customers (use `reject: false` or omit)\n   * - `none` — Question rejected, not visible (use `reject: true`)\n   *\n   * **Rate Limit**: 3 requests per second (burst: 6)\n   *\n   * @param questionId - Question ID from getQuestions()\n   * @param answerText - Answer text to display to customer\n   * @param reject - Optional: true to reject question (state='none'), false/undefined to answer (state='wbRu')\n   * @returns Promise resolving to void (204 No Content)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {ValidationError} When questionId or answerText empty\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Answer a question\n   * await sdk.communications.answerQuestion(\n   *   'q123',\n   *   'This product is made of 100% cotton and machine washable.'\n   * );\n   *\n   * // Reject a question (not visible to customers)\n   * await sdk.communications.answerQuestion(\n   *   'q456',\n   *   'Internal note: inappropriate question',\n   *   true // reject = true sets state to 'none'\n   * );\n   *\n   * // Edit an existing answer (within 60 days)\n   * const questions = await sdk.communications.getQuestions({\n   *   isAnswered: true,\n   *   take: 10,\n   *   skip: 0\n   * });\n   * const editableQuestion = questions.data.questions.find(q => q.answer?.editable);\n   * if (editableQuestion) {\n   *   await sdk.communications.answerQuestion(\n   *     editableQuestion.id,\n   *     'Updated answer with more details.'\n   *   );\n   * }\n   * ```\n   */\n  async answerQuestion(\n    questionId: string,\n    answerText: string,\n    reject?: boolean\n  ): Promise<void> {\n    if (!questionId || questionId.trim() === '') {\n      throw new ValidationError('Question ID is required');\n    }\n    if (!answerText || answerText.trim() === '') {\n      throw new ValidationError('Answer text is required');\n    }\n\n    const payload: AnswerQuestionRequest = {\n      id: questionId,\n      answer: { text: answerText },\n      state: reject ? 'none' : 'wbRu',\n    };\n\n    await this.client.patch<unknown>(\n      'https://feedbacks-api.wildberries.ru/api/v1/questions',\n      payload,\n      { rateLimitKey: 'communications.answerQuestion' }\n    );\n  }\n\n  /**\n   * Mark question as viewed without answering\n   *\n   * Marks a question as viewed for tracking purposes without providing an answer.\n   * Useful for keeping track of which questions the seller has reviewed.\n   *\n   * **Rate Limit**: 3 requests per second (burst: 6)\n   *\n   * @param questionId - Question ID from getQuestions()\n   * @returns Promise resolving to void\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {ValidationError} When questionId is empty\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Batch mark questions as viewed\n   * const response = await sdk.communications.getQuestions({\n   *   isAnswered: false,\n   *   take: 20,\n   *   skip: 0\n   * });\n   *\n   * for (const question of response.data.questions) {\n   *   if (!question.wasViewed) {\n   *     await sdk.communications.markQuestionViewed(question.id);\n   *     console.log(`Marked question ${question.id} as viewed`);\n   *   }\n   * }\n   * ```\n   */\n  async markQuestionViewed(questionId: string): Promise<void> {\n    if (!questionId || questionId.trim() === '') {\n      throw new ValidationError('Question ID is required');\n    }\n\n    const payload: MarkQuestionViewedRequest = {\n      id: questionId,\n      wasViewed: true,\n    };\n\n    await this.client.patch<unknown>(\n      'https://feedbacks-api.wildberries.ru/api/v1/questions',\n      payload,\n      { rateLimitKey: 'communications.markQuestionViewed' }\n    );\n  }\n\n  // ============================================================================\n  // Customer Reviews Methods\n  // ============================================================================\n\n  /**\n   * Get product reviews with filtering\n   *\n   * Retrieves customer reviews with ratings, photos, videos, and product details.\n   * Supports filtering by answered status, product ID, date range, and pagination.\n   *\n   * **Pagination Limits**:\n   * - Maximum 5,000 reviews per response (`take` max: 5000)\n   * - Maximum skip offset: 199,990\n   *\n   * **Review Structure**:\n   * - Rating: 1-5 stars (`productValuation`)\n   * - Content: text, pros, cons\n   * - Media: photos (fullSize, miniSize URLs), video (HLS playlist)\n   * - Customer info: userName, matchingSize, bables (tags)\n   *\n   * **Rate Limit**: 3 requests per second (burst: 6)\n   *\n   * @param filters - Filter criteria (isAnswered, take, skip required; nmId, order, dateFrom, dateTo optional)\n   * @returns Promise resolving to reviews with photos, videos, and ratings\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When required filters missing\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Get unanswered reviews with newest first\n   * const response = await sdk.communications.getReviews({\n   *   isAnswered: false,\n   *   take: 20,\n   *   skip: 0,\n   *   order: 'dateDesc'\n   * });\n   *\n   * console.log(`${response.data.countUnanswered} unanswered reviews`);\n   * for (const review of response.data.feedbacks) {\n   *   console.log(`Rating: ${review.productValuation}/5 stars`);\n   *   console.log(`Review: ${review.text}`);\n   *   console.log(`Pros: ${review.pros}, Cons: ${review.cons}`);\n   *\n   *   // Check for photos\n   *   if (review.photoLinks && review.photoLinks.length > 0) {\n   *     console.log(`Photos: ${review.photoLinks.length}`);\n   *     review.photoLinks.forEach(photo => {\n   *       console.log(`  - ${photo.fullSize}`);\n   *     });\n   *   }\n   *\n   *   // Check for video\n   *   if (review.video) {\n   *     console.log(`Video: ${review.video.durationSec}s - ${review.video.link}`);\n   *   }\n   * }\n   *\n   * // Filter reviews for specific product\n   * const productReviews = await sdk.communications.getReviews({\n   *   isAnswered: false,\n   *   nmId: 12345,\n   *   take: 10,\n   *   skip: 0\n   * });\n   * ```\n   */\n  async getReviews(filters: ReviewFilters): Promise<ReviewsResponse> {\n    return this.client.get<ReviewsResponse>(\n      'https://feedbacks-api.wildberries.ru/api/v1/feedbacks',\n      {\n        params: filters as Record<string, unknown>,\n        rateLimitKey: 'communications.getReviews',\n      }\n    );\n  }\n\n  /**\n   * Respond to customer review\n   *\n   * Provides a professional response to a customer review. Responses are visible\n   * to all customers viewing the product page.\n   *\n   * **Response Constraints**:\n   * - Minimum length: 2 characters\n   * - Maximum length: 5,000 characters\n   * - Professional tone recommended\n   *\n   * **Response Editing**:\n   * - Can edit response once within 60 days\n   * - Check `review.answer.editable` field before attempting edit\n   * - Use `editReviewResponse()` method to edit existing response\n   *\n   * **Note**: Review ID is not validated by API - invalid IDs won't throw errors\n   *\n   * **Rate Limit**: 3 requests per second (burst: 6)\n   *\n   * @param reviewId - Review ID from getReviews()\n   * @param responseText - Response text (min 2, max 5000 characters)\n   * @returns Promise resolving to void (204 No Content)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {ValidationError} When reviewId empty or responseText length invalid\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Professional response to positive review\n   * await sdk.communications.respondToReview(\n   *   'rev123',\n   *   'Thank you for your wonderful feedback! We're delighted that you enjoyed our product. We appreciate your business and hope to serve you again soon.'\n   * );\n   *\n   * // Constructive response to negative review\n   * await sdk.communications.respondToReview(\n   *   'rev456',\n   *   'We sincerely apologize for your experience. Customer satisfaction is our priority. Please contact us directly at support@example.com so we can make this right.'\n   * );\n   *\n   * // Response to review with specific feedback\n   * const reviews = await sdk.communications.getReviews({\n   *   isAnswered: false,\n   *   take: 10,\n   *   skip: 0\n   * });\n   * for (const review of reviews.data.feedbacks) {\n   *   if (review.productValuation === 5) {\n   *     await sdk.communications.respondToReview(\n   *       review.id,\n   *       `Thank you ${review.userName}! We're thrilled you love the ${review.productDetails.productName}!`\n   *     );\n   *   }\n   * }\n   * ```\n   */\n  async respondToReview(reviewId: string, responseText: string): Promise<void> {\n    if (!reviewId || reviewId.trim() === '') {\n      throw new ValidationError('Review ID is required');\n    }\n    if (!responseText || responseText.trim() === '') {\n      throw new ValidationError('Response text is required');\n    }\n    if (responseText.length < 2) {\n      throw new ValidationError(\n        'Response text must be at least 2 characters long'\n      );\n    }\n    if (responseText.length > 5000) {\n      throw new ValidationError(\n        'Response text must not exceed 5000 characters'\n      );\n    }\n\n    const payload: RespondToReviewRequest = {\n      id: reviewId,\n      text: responseText,\n    };\n\n    await this.client.post<unknown>(\n      'https://feedbacks-api.wildberries.ru/api/v1/feedbacks/answer',\n      payload,\n      { rateLimitKey: 'communications.respondToReview' }\n    );\n  }\n\n  /**\n   * Edit existing response to review\n   *\n   * Edits a previously submitted response to a customer review.\n   *\n   * **Edit Limitations**:\n   * - Can only edit once within 60 days of original response\n   * - Check `review.answer.editable` field before attempting\n   * - Same validation as respondToReview (2-5000 characters)\n   *\n   * **Note**: Review ID is not validated by API - invalid IDs won't throw errors\n   *\n   * **Rate Limit**: 3 requests per second (burst: 6)\n   *\n   * @param reviewId - Review ID from getReviews()\n   * @param newResponseText - New response text (min 2, max 5000 characters)\n   * @returns Promise resolving to void (204 No Content)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {ValidationError} When reviewId empty or newResponseText length invalid\n   * @throws {NetworkError} When network request fails\n   *\n   * @example\n   * ```typescript\n   * // Check if response is editable before editing\n   * const reviews = await sdk.communications.getReviews({\n   *   isAnswered: true,\n   *   take: 10,\n   *   skip: 0\n   * });\n   *\n   * for (const review of reviews.data.feedbacks) {\n   *   if (review.answer && review.answer.editable) {\n   *     await sdk.communications.editReviewResponse(\n   *       review.id,\n   *       'Updated response with additional information and improved tone.'\n   *     );\n   *     console.log(`Edited response for review ${review.id}`);\n   *   }\n   * }\n   *\n   * // Edit specific review response\n   * await sdk.communications.editReviewResponse(\n   *   'rev789',\n   *   'Thank you for your feedback! We have updated our product based on your suggestions.'\n   * );\n   * ```\n   */\n  async editReviewResponse(\n    reviewId: string,\n    newResponseText: string\n  ): Promise<void> {\n    if (!reviewId || reviewId.trim() === '') {\n      throw new ValidationError('Review ID is required');\n    }\n    if (!newResponseText || newResponseText.trim() === '') {\n      throw new ValidationError('Response text is required');\n    }\n    if (newResponseText.length < 2) {\n      throw new ValidationError(\n        'Response text must be at least 2 characters long'\n      );\n    }\n    if (newResponseText.length > 5000) {\n      throw new ValidationError(\n        'Response text must not exceed 5000 characters'\n      );\n    }\n\n    const payload: RespondToReviewRequest = {\n      id: reviewId,\n      text: newResponseText,\n    };\n\n    await this.client.patch<unknown>(\n      'https://feedbacks-api.wildberries.ru/api/v1/feedbacks/answer',\n      payload,\n      { rateLimitKey: 'communications.editReviewResponse' }\n    );\n  }\n\n  // ============================================================================\n  // Chat Helper Methods\n  // ============================================================================\n\n  /**\n   * Extract replySign from Chat object\n   *\n   * Helper method to get the replySign needed for sending messages.\n   *\n   * @param chat - Chat object from getChats()\n   * @returns Reply signature string\n   *\n   * @example\n   * ```typescript\n   * const chats = (await sdk.communications.getChats()).result;\n   * const replySign = sdk.communications.getReplySignFromChat(chats[0]);\n   * await sdk.communications.sendMessage(replySign, 'Hello!');\n   * ```\n   */\n  getReplySignFromChat(chat: Chat): string {\n    return chat.replySign;\n  }\n\n  /**\n   * Extract replySign from ChatEvent (only for new chats)\n   *\n   * Helper method to get the replySign from an event when it's a new chat.\n   * Returns null if the event is not a new chat.\n   *\n   * @param event - ChatEvent from getChatEvents()\n   * @returns Reply signature string or null if not a new chat\n   *\n   * @example\n   * ```typescript\n   * const events = (await sdk.communications.getChatEvents()).result.events;\n   * for (const event of events) {\n   *   const replySign = sdk.communications.getReplySignFromEvent(event);\n   *   if (replySign) {\n   *     console.log('New chat detected, replySign:', replySign);\n   *   }\n   * }\n   * ```\n   */\n  getReplySignFromEvent(event: ChatEvent): string | null {\n    return event.isNewChat ? event.replySign ?? null : null;\n  }\n\n  /**\n   * Filter events by specific chat ID\n   *\n   * Helper method to filter events for a specific chat conversation.\n   *\n   * @param events - Array of chat events\n   * @param chatID - Chat ID to filter by\n   * @returns Filtered array of events for the specified chat\n   *\n   * @example\n   * ```typescript\n   * const allEvents = (await sdk.communications.getChatEvents()).result.events;\n   * const chatEvents = sdk.communications.filterEventsByChatID(\n   *   allEvents,\n   *   '1:4019cd7d-cca8-4e90-8b11-f78afbea42e3'\n   * );\n   * console.log(`Chat has ${chatEvents.length} events`);\n   * ```\n   */\n  filterEventsByChatID(events: ChatEvent[], chatID: string): ChatEvent[] {\n    return events.filter((e) => e.chatID === chatID);\n  }\n\n  /**\n   * Filter events to get only client messages\n   *\n   * Helper method to filter events to show only messages from customers.\n   *\n   * @param events - Array of chat events\n   * @returns Filtered array containing only client messages\n   *\n   * @example\n   * ```typescript\n   * const allEvents = (await sdk.communications.getChatEvents()).result.events;\n   * const customerMessages = sdk.communications.getClientMessages(allEvents);\n   *\n   * // Process only customer messages\n   * for (const message of customerMessages) {\n   *   console.log(`Customer ${message.clientName}: ${message.message?.text}`);\n   * }\n   * ```\n   */\n  getClientMessages(events: ChatEvent[]): ChatEvent[] {\n    return events.filter((e) => e.sender === 'client');\n  }\n}\n","/**\n * Reports Module - Business reports generation and retrieval\n *\n * @module modules/reports\n */\n\nimport type { BaseClient } from '../../client/base-client';\nimport type {\n  IncomesItem,\n  StocksItem,\n  OrdersItem,\n  SalesItem,\n  ExciseReportRequest,\n  ExciseReportResponse,\n  WarehouseRemainsParams,\n  ReportTaskResponse,\n  ReportStatus,\n  ReportType,\n} from '../../types/reports.types';\n\n/**\n * ReportsModule - Generate and retrieve various business reports\n *\n * - Basic reports: incomes, stocks, orders, sales (with pagination)\n * - Excise reports: compliance tracking for mandatory labeling\n * - Async reports: warehouse remains with configurable grouping/filtering\n *\n * @example\n * ```typescript\n * const sdk = new WildberriesSDK({ apiKey: 'your-api-key' });\n *\n * // Get recent incomes with pagination\n * const incomes = await sdk.reports.getIncomes('2024-01-01');\n *\n * // Create async warehouse remains report\n * const task = await sdk.reports.createWarehouseRemainsReport({\n *   locale: 'ru',\n *   groupByBrand: true\n * });\n * ```\n */\nexport class ReportsModule {\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Get inbound shipment data from warehouses\n   *\n   * Supports pagination for large datasets (up to 100,000 rows per request).\n   *\n   * **Pagination Strategy**:\n   * 1. Make initial request with desired dateFrom\n   * 2. Check if response length equals 100,000 (indicates more data)\n   * 3. Use lastChangeDate from last row as dateFrom in next request\n   * 4. Continue until response is empty array []\n   *\n   * **Date Format**: RFC3339 in Moscow timezone (UTC+3)\n   * - Date only: `2019-06-20`\n   * - Date with time: `2019-06-20T23:59:59`\n   * - With milliseconds: `2019-06-20T00:00:00.12345`\n   *\n   * @param dateFrom - RFC3339 date/datetime for last change (Moscow UTC+3)\n   * @param flag - Optional filter mode:\n   *   - 0 or undefined: All changes since dateFrom (default)\n   *   - 1: Only new records\n   *\n   * @returns Promise resolving to array of IncomesItem (max 100,000 rows)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {ValidationError} When dateFrom format is invalid\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * // Fetch all incomes with pagination\n   * let allIncomes: IncomesItem[] = [];\n   * let dateFrom = '2024-01-01';\n   *\n   * while (true) {\n   *   const incomes = await sdk.reports.getIncomes(dateFrom);\n   *   if (incomes.length === 0) break;\n   *\n   *   allIncomes = allIncomes.concat(incomes);\n   *   console.log(`Fetched ${incomes.length} incomes, total: ${allIncomes.length}`);\n   *\n   *   // Use lastChangeDate from last row for next request\n   *   dateFrom = incomes[incomes.length - 1].lastChangeDate;\n   *\n   *   // Check if we hit the 100K limit\n   *   if (incomes.length < 100000) break;\n   * }\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyoty-statistiki/paths/~1api~1v1~1supplier~1incomes/get}\n   */\n  async getIncomes(dateFrom: string, flag?: number): Promise<IncomesItem[]> {\n    const params: Record<string, string | number> = { dateFrom };\n    if (flag !== undefined) {\n      params.flag = flag;\n    }\n\n    return this.client.get<IncomesItem[]>(\n      'https://statistics-api.wildberries.ru/api/v1/supplier/incomes',\n      { params, rateLimitKey: 'reports.getIncomes' }\n    );\n  }\n\n  /**\n   * Get current stock levels across WB warehouses\n   *\n   * Data is updated every 30 minutes. Maximum 60,000 rows per response.\n   *\n   * **Stock Quantity Fields**:\n   * - `quantity`: Available stock in warehouse (can be added to cart)\n   * - `inWayToClient`: In transit to customer\n   * - `inWayFromClient`: In transit from customer (returns)\n   * - `quantityFull`: Total quantity (quantity + inWayToClient + inWayFromClient)\n   *\n   * **For Full Stock Snapshot**: Use early date like `2019-06-20` to get all current stock\n   *\n   * **Pagination Strategy**: Same as getIncomes(), use lastChangeDate from last row\n   *\n   * @param dateFrom - RFC3339 date/datetime (use early date like 2019-06-20 for full snapshot)\n   *\n   * @returns Promise resolving to array of StocksItem with quantity breakdown (max 60,000 rows)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {ValidationError} When dateFrom format is invalid\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * // Get current stock snapshot\n   * const stocks = await sdk.reports.getStocks('2019-01-01');\n   *\n   * // Analyze stock levels\n   * let totalAvailable = 0;\n   * let totalInTransit = 0;\n   *\n   * stocks.forEach(stock => {\n   *   totalAvailable += stock.quantity;\n   *   totalInTransit += stock.inWayToClient + stock.inWayFromClient;\n   * });\n   *\n   * console.log(`Available: ${totalAvailable}`);\n   * console.log(`In Transit: ${totalInTransit}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyoty-statistiki/paths/~1api~1v1~1supplier~1stocks/get}\n   */\n  async getStocks(dateFrom: string): Promise<StocksItem[]> {\n    return this.client.get<StocksItem[]>(\n      'https://statistics-api.wildberries.ru/api/v1/supplier/stocks',\n      { params: { dateFrom }, rateLimitKey: 'reports.getStocks' }\n    );\n  }\n\n  /**\n   * Get order information for all customer orders\n   *\n   * Maximum 80,000 rows per response.\n   *\n   * **Important Notes**:\n   * - 1 row = 1 order = 1 assembly task = 1 product unit\n   * - Use `srid` field for unique order identification\n   * - `isCancel` field indicates canceled orders (with cancelDate)\n   * - Data retention: 90 days from order creation\n   *\n   * **Pagination Strategy**: Use lastChangeDate from last row, 80,000 row limit\n   *\n   * @param dateFrom - RFC3339 date/datetime for last change\n   * @param flag - Optional filter mode:\n   *   - 0 or undefined: All changes since dateFrom (default)\n   *   - 1: Only new records\n   *\n   * @returns Promise resolving to array of OrdersItem (max 80,000 rows)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {ValidationError} When dateFrom format is invalid\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * // Get recent orders and track cancellations\n   * const orders = await sdk.reports.getOrders('2024-01-01', 1);\n   *\n   * const canceledOrders = orders.filter(o => o.isCancel);\n   * console.log(`Canceled: ${canceledOrders.length} / ${orders.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyoty-statistiki/paths/~1api~1v1~1supplier~1orders/get}\n   */\n  async getOrders(dateFrom: string, flag?: number): Promise<OrdersItem[]> {\n    const params: Record<string, string | number> = { dateFrom };\n    if (flag !== undefined) {\n      params.flag = flag;\n    }\n\n    return this.client.get<OrdersItem[]>(\n      'https://statistics-api.wildberries.ru/api/v1/supplier/orders',\n      { params, rateLimitKey: 'reports.getOrders' }\n    );\n  }\n\n  /**\n   * Get sales and returns data\n   *\n   * Data is updated every 30 minutes with 90-day retention.\n   * Maximum 80,000 rows per response.\n   *\n   * **Payment Fields**:\n   * - `paymentSaleAmount`: Payment from sale (negative for returns)\n   * - `forPay`: Amount to be paid to seller\n   * - `saleID`: Unique sale identifier (S********** = sale, R********** = return)\n   *\n   * **Returns Detection**: Negative `paymentSaleAmount` indicates return\n   *\n   * @param dateFrom - RFC3339 date/datetime for last change\n   * @param flag - Optional filter mode:\n   *   - 0 or undefined: All changes since dateFrom (default)\n   *   - 1: Only new records\n   *\n   * @returns Promise resolving to array of SalesItem with payment info (max 80,000 rows)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {ValidationError} When dateFrom format is invalid\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * // Calculate revenue and returns\n   * const sales = await sdk.reports.getSales('2024-01-01');\n   *\n   * let totalRevenue = 0;\n   * let totalReturns = 0;\n   *\n   * sales.forEach(sale => {\n   *   if (sale.paymentSaleAmount > 0) {\n   *     totalRevenue += sale.forPay;\n   *   } else {\n   *     totalReturns += Math.abs(sale.forPay);\n   *   }\n   * });\n   *\n   * console.log(`Revenue: ${totalRevenue}`);\n   * console.log(`Returns: ${totalReturns}`);\n   * console.log(`Net: ${totalRevenue - totalReturns}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyoty-statistiki/paths/~1api~1v1~1supplier~1sales/get}\n   */\n  async getSales(dateFrom: string, flag?: number): Promise<SalesItem[]> {\n    const params: Record<string, string | number> = { dateFrom };\n    if (flag !== undefined) {\n      params.flag = flag;\n    }\n\n    return this.client.get<SalesItem[]>(\n      'https://statistics-api.wildberries.ru/api/v1/supplier/sales',\n      { params, rateLimitKey: 'reports.getSales' }\n    );\n  }\n\n  /**\n   * Get report on goods with mandatory labeling (excise goods)\n   *\n   * Used for tracking labeling operations and regulatory compliance.\n   *\n   * **Country Codes** (ISO 3166-2):\n   * - AM: Armenia\n   * - BY: Belarus\n   * - KG: Kyrgyzstan\n   * - KZ: Kazakhstan\n   * - RU: Russia\n   * - UZ: Uzbekistan\n   *\n   * **Operation Types**:\n   * - 1: Withdrawal from circulation\n   * - 2: Return to circulation\n   *\n   * @param dateFrom - RFC3339 date for report start\n   * @param dateTo - RFC3339 date for report end\n   * @param body - Optional filters: countries, brands, inns\n   *\n   * @returns Promise resolving to ExciseReportResponse with labeling operations\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (10 req/5hrs)\n   * @throws {ValidationError} When date format or parameters invalid\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * // Get excise report for Russia\n   * const report = await sdk.reports.getExciseReport(\n   *   '2024-01-01',\n   *   '2024-01-31',\n   *   { countries: ['RU'] }\n   * );\n   *\n   * console.log(`Operations tracked: ${report.response.data.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyot-po-markirovke-tovarov/paths/~1api~1v1~1analytics~1excise-report/post}\n   */\n  async getExciseReport(\n    dateFrom: string,\n    dateTo: string,\n    body?: ExciseReportRequest\n  ): Promise<ExciseReportResponse> {\n    return this.client.post<ExciseReportResponse>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/excise-report',\n      body ?? {},\n      {\n        params: { dateFrom, dateTo },\n        rateLimitKey: 'reports.getExciseReport',\n      }\n    );\n  }\n\n  /**\n   * Create async task to generate warehouse remains report\n   *\n   * Returns taskId for status checking and download.\n   *\n   * **Async Workflow**:\n   * 1. Create task with this method (get taskId)\n   * 2. Poll status with checkReportStatus() every 5-10 seconds\n   * 3. Download with downloadReport() when status is 'done'\n   *\n   * **Locale Options**:\n   * - ru: Russian (default)\n   * - en: English\n   * - zh: Chinese (warehouseName in English)\n   *\n   * **GroupBy Options**: groupByBrand, groupBySubject, groupBySa, groupBySize, groupByNm, groupByBarcode\n   *\n   * **Filter Options**: filterPics (-1/0/1), filterVolume (-1/0/3)\n   *\n   * @param params - Report configuration with locale, groupBy options, and filters\n   *\n   * @returns Promise resolving to ReportTaskResponse with taskId\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min, burst 5)\n   * @throws {ValidationError} When parameters are invalid\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * // Create report with brand and subject grouping\n   * const task = await sdk.reports.createWarehouseRemainsReport({\n   *   locale: 'ru',\n   *   groupByBrand: true,\n   *   groupBySubject: true\n   * });\n   *\n   * console.log(`Task created: ${task.data.taskId}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyot-ob-ostatkah-na-skladah/paths/~1api~1v1~1warehouse_remains/get}\n   */\n  async createWarehouseRemainsReport(\n    params: WarehouseRemainsParams\n  ): Promise<ReportTaskResponse> {\n    return this.client.get<ReportTaskResponse>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/warehouse_remains',\n      { params, rateLimitKey: 'reports.createWarehouseRemainsReport' }\n    );\n  }\n\n  /**\n   * Check async report generation status\n   *\n   * Poll every 5-10 seconds until status is 'done' or 'error'.\n   *\n   * **Status Values**:\n   * - new: Queued\n   * - processing: Generating report\n   * - done: Ready for download\n   * - error: Generation failed (check error field)\n   * - purged: Report deleted\n   * - canceled: Task canceled\n   *\n   * **Polling Strategy**: Check every 5-10 seconds until 'done' or 'error'\n   *\n   * @param taskId - Task ID from createWarehouseRemainsReport()\n   * @param reportType - Type of report being generated\n   *\n   * @returns Promise resolving to ReportStatus with current status\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/5s, burst 5)\n   * @throws {NetworkError} When network error occurs\n   *\n   * @example\n   * ```typescript\n   * // Poll status until done\n   * let status: ReportStatus;\n   * do {\n   *   await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5s\n   *\n   *   status = await sdk.reports.checkReportStatus(\n   *     taskId,\n   *     'warehouse_remains'\n   *   );\n   *\n   *   console.log(`Status: ${status.data.status}`);\n   * } while (status.data.status === 'new' || status.data.status === 'processing');\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyot-ob-ostatkah-na-skladah/paths/~1api~1v1~1warehouse_remains~1tasks~1%7Btask_id%7D~1status/get}\n   */\n  async checkReportStatus(\n    taskId: string,\n    reportType: ReportType\n  ): Promise<ReportStatus> {\n    const endpoints: Record<ReportType, string> = {\n      warehouse_remains: 'warehouse_remains',\n      acceptance: 'acceptance_report',\n      paid_storage: 'paid_storage',\n    };\n\n    const endpoint = endpoints[reportType];\n\n    return this.client.get<ReportStatus>(\n      `https://seller-analytics-api.wildberries.ru/api/v1/${endpoint}/tasks/${taskId}/status`,\n      { rateLimitKey: `reports.checkReportStatus.${reportType}` }\n    );\n  }\n\n  /**\n   * Download completed async report\n   *\n   * Report format is Excel (.xlsx) file with tabular data.\n   *\n   * **Prerequisites**: Task status must be 'done' before downloading\n   *\n   * **Report Format**: Excel (.xlsx) file\n   *\n   * @param taskId - Task ID from createWarehouseRemainsReport()\n   * @param reportType - Type of report to download\n   *\n   * @returns Promise resolving to Blob (report file data)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network error occurs\n   *\n   * @example\n   * ```typescript\n   * // Download and save report\n   * const reportBlob = await sdk.reports.downloadReport(\n   *   taskId,\n   *   'warehouse_remains'\n   * );\n   *\n   * // Save to file (Node.js)\n   * const fs = require('fs');\n   * const buffer = await reportBlob.arrayBuffer();\n   * fs.writeFileSync('warehouse_remains.xlsx', Buffer.from(buffer));\n   *\n   * console.log('Report downloaded: warehouse_remains.xlsx');\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyot-ob-ostatkah-na-skladah/paths/~1api~1v1~1warehouse_remains~1tasks~1%7Btask_id%7D~1download/get}\n   */\n  async downloadReport(\n    taskId: string,\n    reportType: ReportType\n  ): Promise<Blob> {\n    const endpoints: Record<ReportType, string> = {\n      warehouse_remains: 'warehouse_remains',\n      acceptance: 'acceptance_report',\n      paid_storage: 'paid_storage',\n    };\n\n    const endpoint = endpoints[reportType];\n\n    return this.client.get<Blob>(\n      `https://seller-analytics-api.wildberries.ru/api/v1/${endpoint}/tasks/${taskId}/download`,\n      {\n        rateLimitKey: `reports.downloadReport.${reportType}`,\n        responseType: 'blob',\n      }\n    );\n  }\n\n  // ==================== Compliance Reports ====================\n\n  /**\n   * Get report on goods with mandatory labeling requirements\n   *\n   * Used for tracking compliance with Russian marking system (Честный ЗНАК).\n   *\n   * @param params - Optional query parameters for filtering\n   *\n   * @returns Promise resolving to array of labeling items\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const labelingReport = await sdk.reports.getGoodsLabelingReport();\n   * console.log(`Products requiring labeling: ${labelingReport.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyot-o-tovarah-c-obyazatelnoj-markirovkoj}\n   */\n  async getGoodsLabelingReport(params?: Record<string, unknown>): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/goods-labeling',\n      { params, rateLimitKey: 'reports.getGoodsLabelingReport' }\n    );\n  }\n\n  /**\n   * Get report on product characteristics changes\n   *\n   * Used for tracking product data modifications and compliance.\n   *\n   * @param params - Optional query parameters for filtering\n   *\n   * @returns Promise resolving to array of characteristic change records\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const changes = await sdk.reports.getCharacteristicsChangeReport();\n   * console.log(`Characteristics changes: ${changes.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyoty-ob-uderzhaniyah}\n   */\n  async getCharacteristicsChangeReport(params?: Record<string, unknown>): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/characteristics-change',\n      { params, rateLimitKey: 'reports.getCharacteristicsChangeReport' }\n    );\n  }\n\n  /**\n   * Get antifraud system details report\n   *\n   * Used for tracking fraud prevention measures and blocked operations.\n   *\n   * @param params - Optional query parameters for filtering\n   *\n   * @returns Promise resolving to antifraud details\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const antifraud = await sdk.reports.getAntifraudDetailsReport();\n   * console.log(`Antifraud records: ${antifraud.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyoty-ob-uderzhaniyah}\n   */\n  async getAntifraudDetailsReport(params?: Record<string, unknown>): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/antifraud-details',\n      { params, rateLimitKey: 'reports.getAntifraudDetailsReport' }\n    );\n  }\n\n  /**\n   * Get report on incorrect product attachments\n   *\n   * Used for identifying and fixing product data quality issues.\n   *\n   * @param params - Optional query parameters for filtering\n   *\n   * @returns Promise resolving to array of incorrect attachment records\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const incorrect = await sdk.reports.getIncorrectAttachmentsReport();\n   * console.log(`Products with incorrect attachments: ${incorrect.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyoty-ob-uderzhaniyah}\n   */\n  async getIncorrectAttachmentsReport(params?: Record<string, unknown>): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/incorrect-attachments',\n      { params, rateLimitKey: 'reports.getIncorrectAttachmentsReport' }\n    );\n  }\n\n  // ==================== Warehouse Operations ====================\n\n  /**\n   * Get warehouse measurements report\n   *\n   * Used for tracking dimensional weight and storage calculations.\n   *\n   * @param params - Optional query parameters for filtering\n   *\n   * @returns Promise resolving to warehouse measurements data\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const measurements = await sdk.reports.getWarehouseMeasurementsReport();\n   * console.log(`Measurement records: ${measurements.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyoty-ob-uderzhaniyah}\n   */\n  async getWarehouseMeasurementsReport(params?: Record<string, unknown>): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/warehouse-measurements',\n      { params, rateLimitKey: 'reports.getWarehouseMeasurementsReport' }\n    );\n  }\n\n  // ==================== Acceptance Report (Async Task) ====================\n\n  /**\n   * Create async task to generate acceptance report\n   *\n   * Returns taskId for status checking and download.\n   *\n   * **Async Workflow**:\n   * 1. Create task with this method (get taskId)\n   * 2. Poll status with getAcceptanceReportStatus() every 5-10 seconds\n   * 3. Download with downloadAcceptanceReport() when status is 'done'\n   *\n   * @param params - Report parameters (date range, filters)\n   *\n   * @returns Promise resolving to ReportTaskResponse with taskId\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {ValidationError} When parameters are invalid\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const task = await sdk.reports.requestAcceptanceReport({});\n   * console.log(`Task created: ${task.data.taskId}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Platnaya-priyomka}\n   */\n  async requestAcceptanceReport(params?: Record<string, unknown>): Promise<ReportTaskResponse> {\n    return this.client.get<ReportTaskResponse>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/acceptance_report',\n      { params, rateLimitKey: 'reports.requestAcceptanceReport' }\n    );\n  }\n\n  /**\n   * Check acceptance report generation status\n   *\n   * Poll every 5-10 seconds until status is 'done' or 'error'.\n   *\n   * **Status Values**: new, processing, done, error, purged, canceled\n   *\n   * @param taskId - Task ID from requestAcceptanceReport()\n   *\n   * @returns Promise resolving to ReportStatus with current status\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/5s)\n   * @throws {NetworkError} When network error occurs\n   *\n   * @example\n   * ```typescript\n   * const status = await sdk.reports.getAcceptanceReportStatus(taskId);\n   * console.log(`Status: ${status.data.status}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Platnaya-priyomka}\n   */\n  async getAcceptanceReportStatus(taskId: string): Promise<ReportStatus> {\n    return this.checkReportStatus(taskId, 'acceptance');\n  }\n\n  /**\n   * Download completed acceptance report\n   *\n   * Report format is Excel (.xlsx) file with acceptance fee details.\n   *\n   * **Prerequisites**: Task status must be 'done' before downloading\n   *\n   * @param taskId - Task ID from requestAcceptanceReport()\n   *\n   * @returns Promise resolving to Blob (report file data)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network error occurs\n   *\n   * @example\n   * ```typescript\n   * const reportBlob = await sdk.reports.downloadAcceptanceReport(taskId);\n   * // Save to file...\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Platnaya-priyomka}\n   */\n  async downloadAcceptanceReport(taskId: string): Promise<Blob> {\n    return this.downloadReport(taskId, 'acceptance');\n  }\n\n  // ==================== Paid Storage Report (Async Task) ====================\n\n  /**\n   * Create async task to generate paid storage report\n   *\n   * Returns taskId for status checking and download.\n   *\n   * **Async Workflow**:\n   * 1. Create task with this method (get taskId)\n   * 2. Poll status with getPaidStorageReportStatus() every 5-10 seconds\n   * 3. Download with downloadPaidStorageReport() when status is 'done'\n   *\n   * @param params - Report parameters (date range, filters)\n   *\n   * @returns Promise resolving to ReportTaskResponse with taskId\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {ValidationError} When parameters are invalid\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const task = await sdk.reports.requestPaidStorageReport({});\n   * console.log(`Task created: ${task.data.taskId}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Platnoe-hranenie}\n   */\n  async requestPaidStorageReport(params?: Record<string, unknown>): Promise<ReportTaskResponse> {\n    return this.client.get<ReportTaskResponse>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/paid_storage',\n      { params, rateLimitKey: 'reports.requestPaidStorageReport' }\n    );\n  }\n\n  /**\n   * Check paid storage report generation status\n   *\n   * Poll every 5-10 seconds until status is 'done' or 'error'.\n   *\n   * **Status Values**: new, processing, done, error, purged, canceled\n   *\n   * @param taskId - Task ID from requestPaidStorageReport()\n   *\n   * @returns Promise resolving to ReportStatus with current status\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/5s)\n   * @throws {NetworkError} When network error occurs\n   *\n   * @example\n   * ```typescript\n   * const status = await sdk.reports.getPaidStorageReportStatus(taskId);\n   * console.log(`Status: ${status.data.status}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Platnoe-hranenie}\n   */\n  async getPaidStorageReportStatus(taskId: string): Promise<ReportStatus> {\n    return this.checkReportStatus(taskId, 'paid_storage');\n  }\n\n  /**\n   * Download completed paid storage report\n   *\n   * Report format is Excel (.xlsx) file with storage cost details.\n   *\n   * **Prerequisites**: Task status must be 'done' before downloading\n   *\n   * @param taskId - Task ID from requestPaidStorageReport()\n   *\n   * @returns Promise resolving to Blob (report file data)\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network error occurs\n   *\n   * @example\n   * ```typescript\n   * const reportBlob = await sdk.reports.downloadPaidStorageReport(taskId);\n   * // Save to file...\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Platnoe-hranenie}\n   */\n  async downloadPaidStorageReport(taskId: string): Promise<Blob> {\n    return this.downloadReport(taskId, 'paid_storage');\n  }\n\n  // ==================== Analytics Reports ====================\n\n  /**\n   * Get sales by region report\n   *\n   * Used for geographic sales analysis and regional performance tracking.\n   *\n   * @param params - Optional query parameters (date range, filters)\n   *\n   * @returns Promise resolving to array of regional sales data\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const regionalSales = await sdk.reports.getRegionalSalesReport();\n   * regionalSales.forEach(region => {\n   *   console.log(`${region.regionName}: ${region.sales} sales`);\n   * });\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Prodazhi-po-regionam}\n   */\n  async getRegionalSalesReport(params?: Record<string, unknown>): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/region-sale',\n      { params, rateLimitKey: 'reports.getRegionalSalesReport' }\n    );\n  }\n\n  /**\n   * Get list of brands for brand share analysis\n   *\n   * Used as prerequisite for getBrandShareReport().\n   *\n   * @returns Promise resolving to array of brand information\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const brands = await sdk.reports.getBrandsForBrandShare();\n   * console.log(`Available brands: ${brands.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Dolya-brenda-v-prodazhah}\n   */\n  async getBrandsForBrandShare(): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/brand-share/brands',\n      { rateLimitKey: 'reports.getBrandsForBrandShare' }\n    );\n  }\n\n  /**\n   * Get list of parent subjects (categories) for brand share analysis\n   *\n   * Used as prerequisite for getBrandShareReport().\n   *\n   * @returns Promise resolving to array of category information\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const categories = await sdk.reports.getParentSubjectsForBrandShare();\n   * console.log(`Available categories: ${categories.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Dolya-brenda-v-prodazhah}\n   */\n  async getParentSubjectsForBrandShare(): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/brand-share/parent-subjects',\n      { rateLimitKey: 'reports.getParentSubjectsForBrandShare' }\n    );\n  }\n\n  /**\n   * Get brand market share report\n   *\n   * Shows brand performance relative to category market.\n   *\n   * @param params - Query parameters (brand ID, category ID, date range)\n   *\n   * @returns Promise resolving to brand share data\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {ValidationError} When required parameters missing\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const shareReport = await sdk.reports.getBrandShareReport({\n   *   brandId: 123,\n   *   categoryId: 456\n   * });\n   * console.log(`Market share: ${shareReport.sharePercent}%`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Dolya-brenda-v-prodazhah}\n   */\n  async getBrandShareReport(params: Record<string, unknown>): Promise<unknown> {\n    return this.client.get<unknown>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/brand-share',\n      { params, rateLimitKey: 'reports.getBrandShareReport' }\n    );\n  }\n\n  /**\n   * Get blocked products report\n   *\n   * Used for identifying and resolving product listing issues.\n   *\n   * @param params - Optional query parameters for filtering\n   *\n   * @returns Promise resolving to array of blocked products\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const blocked = await sdk.reports.getBlockedProductsReport();\n   * console.log(`Blocked products: ${blocked.length}`);\n   * blocked.forEach(product => {\n   *   console.log(`Product ${product.nmId}: ${product.blockReason}`);\n   * });\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Skrytye-tovary}\n   */\n  async getBlockedProductsReport(params?: Record<string, unknown>): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/banned-products/blocked',\n      { params, rateLimitKey: 'reports.getBlockedProductsReport' }\n    );\n  }\n\n  /**\n   * Get shadowed (hidden) products report\n   *\n   * Used for identifying products with visibility issues.\n   *\n   * @param params - Optional query parameters for filtering\n   *\n   * @returns Promise resolving to array of hidden products\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const shadowed = await sdk.reports.getShadowedProductsReport();\n   * console.log(`Hidden products: ${shadowed.length}`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Skrytye-tovary}\n   */\n  async getShadowedProductsReport(params?: Record<string, unknown>): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/banned-products/shadowed',\n      { params, rateLimitKey: 'reports.getShadowedProductsReport' }\n    );\n  }\n\n  /**\n   * Get goods return and movement report\n   *\n   * Used for tracking return rates, reasons, and product flow.\n   *\n   * @param params - Optional query parameters (date range, filters)\n   *\n   * @returns Promise resolving to array of return/movement records\n   *\n   * @throws {AuthenticationError} When API key is invalid\n   * @throws {RateLimitError} When rate limit exceeded (1 req/min)\n   * @throws {NetworkError} When network or server error occurs\n   *\n   * @example\n   * ```typescript\n   * const returns = await sdk.reports.getGoodsReturnReport();\n   * console.log(`Return records: ${returns.length}`);\n   * const returnRate = (returns.length / totalSales) * 100;\n   * console.log(`Return rate: ${returnRate.toFixed(2)}%`);\n   * ```\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/reports#tag/Otchyot-o-vozvratah-i-peremeshenii-tovarov}\n   */\n  async getGoodsReturnReport(params?: Record<string, unknown>): Promise<unknown[]> {\n    return this.client.get<unknown[]>(\n      'https://seller-analytics-api.wildberries.ru/api/v1/analytics/goods-return',\n      { params, rateLimitKey: 'reports.getGoodsReturnReport' }\n    );\n  }\n}\n","/**\n * Auto-generated module\n * Generated from: wildberries_api_doc/08-promotion.yaml\n * DO NOT EDIT MANUALLY - Changes will be overwritten on next generation\n */\n\nimport { BaseClient } from '../../client/base-client';\nimport type { GetAuctionAdverts, PlacementType, RequestWithCampaignID, RequestWithDate, RequestWithInterval, ResponseFullStats, ResponseInfoAdvert, ResponseInfoAdvertType8, ResponseInfoAdvertType9, ResponseWithDate, ResponseWithInterval, ResponseWithReturn, Stat, StatDate, StatInterval, V0AdvertMultibid, V0GetConfigCategoriesResponse, V0KeywordsStatisticsResponse } from '../../types/promotion.types';\n\nexport class PromotionModule {\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Списки кампаний\n   *\n   * Метод возвращает списки всех [рекламных кампаний](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post) продавца с их ID. Кампании сгруппированы по типу и статусу, у каждой указана дата последнего изменения. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getPromotionCount();\n  console.log(result);\n   */\n  async getPromotionCount(): Promise<{ adverts?: { type?: number; status?: number; count?: number; advert_list?: { advertId?: number; changeTime?: string }[] }[]; all?: number }> {\n    return this.client.get<{ adverts?: { type?: number; status?: number; count?: number; advert_list?: { advertId?: number; changeTime?: string }[] }[]; all?: number }>('https://advert-api.wildberries.ru/adv/v1/promotion/count');\n  }\n\n  /**\n   * Информация о кампаниях\n   *\n   * Метод возвращает информацию о рекламных кампаниях с устаревшими типами (4-8) по их статусам, типам и ID. <br><br> Для получения информации о кампаниях с типом 9 используйте [отдельный метод](/openapi/promotion#tag/Kampanii/paths/~1adv~1v0~1auction~1adverts/get). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createPromotionAdverts({}, {});\n  console.log(result);\n   */\n  async createPromotionAdverts(data: number[], options?: { status?: -1 | 4 | 7 | 8 | 9 | 11; type?: 4 | 5 | 6 | 7 | 8; order?: 'create' | 'change' | 'id'; direction?: 'desc' | 'asc' }): Promise<ResponseInfoAdvertType8 | ResponseInfoAdvert | ResponseInfoAdvertType9[]> {\n    return this.client.post<ResponseInfoAdvertType8 | ResponseInfoAdvert | ResponseInfoAdvertType9[]>('https://advert-api.wildberries.ru/adv/v1/promotion/adverts', data, { params: options });\n  }\n\n  /**\n   * Информация о кампаниях с ручной ставкой\n   *\n   * Метод возвращает информацию о рекламных кампаниях с ручной ставкой по их статусам, типам оплаты и ID. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAuctionAdverts({});\n  console.log(result);\n   */\n  async getAuctionAdverts(options?: { ids?: string; statuses?: '-1' | '4' | '7' | '8' | '9' | '11'; payment_type?: 'cpm' | 'cpc' }): Promise<GetAuctionAdverts> {\n    return this.client.get<GetAuctionAdverts>('https://advert-api.wildberries.ru/adv/v0/auction/adverts', { params: options });\n  }\n\n  /**\n   * Конфигурационные значения Продвижения\n   *\n   * Метод возвращает допустимые значения основных параметров конфигурации [кампаний](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post): например, минимальные ставки, доступные категории и максимальное количество товаров, которые можно добавить в кампанию. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 1 запрос | 1 минута | 1 запрос | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvConfig();\n  console.log(result);\n   */\n  async getAdvConfig(): Promise<{ categories?: V0GetConfigCategoriesResponse[]; config?: { description?: string; name?: string; value?: string }[] }> {\n    return this.client.get<{ categories?: V0GetConfigCategoriesResponse[]; config?: { description?: string; name?: string; value?: string }[] }>('https://advert-api.wildberries.ru/adv/v0/config');\n  }\n\n  /**\n   * Минимальные ставки для карточек товаров\n   *\n   * Метод возвращает минимальные ставки для карточек товаров по типу оплаты и местам размещения. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 20 запросов | 3 секунды | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createBidsMin({});\n  console.log(result);\n   */\n  async createBidsMin(data: { advert_id: number; nm_ids: number[]; payment_type: 'cpm' | 'cpc'; placement_types: 'combined' | 'search' | 'recommendation'[] }): Promise<{ bids: { bids: { type: PlacementType; value: number }[]; nm_id: number }[] }> {\n    return this.client.post<{ bids: { bids: { type: PlacementType; value: number }[]; nm_id: number }[] }>('https://advert-api.wildberries.ru/adv/v0/bids/min', data);\n  }\n\n  /**\n   * Создать кампанию с единой ставкой\n   *\n   * Метод создаёт кампанию [с единой ставкой](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post) для продвижения товаров в: - каталоге - поиске - карточках товаров - рекомендациях на главной странице WB <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 20 секунд | 1 запрос | 20 секунд | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createAdvSaveAd({});\n  console.log(result);\n   */\n  async createAdvSaveAd(data: { type?: number; name?: string; subjectId?: number; sum?: number; btype?: number; on_pause?: boolean; nms?: number[]; cpm?: number }): Promise<string> {\n    return this.client.post<string>('https://advert-api.wildberries.ru/adv/v1/save-ad', data);\n  }\n\n  /**\n   * Создать кампанию\n   *\n   * Метод создаёт кампанию: - с ручной ставкой для продвижения товаров в поиске и/или рекомендациях - с единой ставкой для продвижения товаров одновременно в поиске и рекомендациях Тип всех созданных этим методом кампаний — `9`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 5 запросов | 12 секунд | 5 запросов | </div>\n   *\n   * @param [data] - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createSeacatSaveAd({});\n  console.log(result);\n   */\n  async createSeacatSaveAd(data?: { name?: string; nms?: number[]; bid_type?: 'manual' | 'unified'; placement_types?: 'search' | 'recommendations'[] }): Promise<number> {\n    return this.client.post<number>('https://advert-api.wildberries.ru/adv/v2/seacat/save-ad', data);\n  }\n\n  /**\n   * Предметы для кампаний\n   *\n   * Метод возвращает список [предметов](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1all/get), которые можно добавить в рекламную [кампанию](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 12 секунд | 1 запрос | 12 секунд | 5 запросов | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getSupplierSubjects();\n  console.log(result);\n   */\n  async getSupplierSubjects(): Promise<{ id?: number; name?: string; count?: number }[]> {\n    return this.client.get<{ id?: number; name?: string; count?: number }[]>('https://advert-api.wildberries.ru/adv/v1/supplier/subjects');\n  }\n\n  /**\n   * Карточки товаров для кампаний\n   *\n   * Метод возвращает список [карточек товаров](/openapi/work-with-products#tag/Kartochki-tovarov/paths/~1content~1v2~1get~1cards~1list/post), которые можно добавить в рекламную [кампанию](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post). Для получения карточек необходимы ID [предметов](/openapi/promotion#tag/Sozdanie-kampanij/paths/~1adv~1v1~1supplier~1subjects/get), также доступных для добавления в кампанию. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 5 запросов | 12 секунд | 5 запросов | </div>\n   *\n   * @param [data] - ID предметов, для которых нужно получить карточки товаров\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createSupplierNms({});\n  console.log(result);\n   */\n  async createSupplierNms(data?: number[]): Promise<{ title?: string; nm?: number; subjectId?: number }[]> {\n    return this.client.post<{ title?: string; nm?: number; subjectId?: number }[]>('https://advert-api.wildberries.ru/adv/v2/supplier/nms', data);\n  }\n\n  /**\n   * Удаление кампании\n   *\n   * Метод удаляет [кампании](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post) в статусе `4` — готова к запуску.<br><br> После удаления кампания некоторое время будет находиться в статусе `-1` — кампания в процессе удаления. Полное удаление кампании занимает от 3 до 10 минут. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvDelete({});\n  console.log(result);\n   */\n  async getAdvDelete(options?: { id: number }): Promise<unknown> {\n    return this.client.get<unknown>('https://advert-api.wildberries.ru/adv/v0/delete', { params: options });\n  }\n\n  /**\n   * Переименование кампании\n   *\n   * Метод меняет название [кампании](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post). Это можно сделать в любой момент существования кампании. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @param [data] - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createAdvRename({});\n  console.log(result);\n   */\n  async createAdvRename(data?: { advertId: number; name: string }): Promise<unknown> {\n    return this.client.post<unknown>('https://advert-api.wildberries.ru/adv/v0/rename', data);\n  }\n\n  /**\n   * Запуск кампании\n   *\n   * Метод запускает [кампании](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post) в статусах `4` — готово к запуску — или `11` — пауза. Чтобы запустить кампанию со статусом `4`, необходимо выполнить два условия: 1. После создания кампании в кабинете **WB. Продвижение** нажать кнопку **Применить изменения**. 2. Установить бюджет — максимальную сумму затрат на кампанию. Чтобы запустить кампанию со статусом `11`, проверьте ее бюджет. Если бюджета недостаточно, [пополните его](/openapi/promotion#tag/Finansy/paths/~1adv~1v1~1budget~1deposit/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvStart({});\n  console.log(result);\n   */\n  async getAdvStart(options?: { id: number }): Promise<unknown> {\n    return this.client.get<unknown>('https://advert-api.wildberries.ru/adv/v0/start', { params: options });\n  }\n\n  /**\n   * Пауза кампании\n   *\n   * Метод ставит [кампании](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post) в статусе `9` — активна — на паузу. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvPause({});\n  console.log(result);\n   */\n  async getAdvPause(options?: { id: number }): Promise<unknown> {\n    return this.client.get<unknown>('https://advert-api.wildberries.ru/adv/v0/pause', { params: options });\n  }\n\n  /**\n   * Завершение кампании\n   *\n   * Метод завершает [кампании](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post) в статусах: - `4` — готово к запуску - `9` — активна - `11` — пауза <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvStop({});\n  console.log(result);\n   */\n  async getAdvStop(options?: { id: number }): Promise<unknown> {\n    return this.client.get<unknown>('https://advert-api.wildberries.ru/adv/v0/stop', { params: options });\n  }\n\n  /**\n   * Изменение ставок\n   *\n   * Метод меняет ставки карточек товаров по артикулам WB в кампаниях с единой ставкой. <br><br> Для кампаний в статусах `4`, `9` и `11`. <br><br> Для изменения ставок в кампаниях с ручной ставкой используйте [отдельный метод](/openapi/promotion#tag/Upravlenie-kampaniyami/paths/~1adv~1v0~1auction~1bids/patch). <br><br> Минимально допустимые ставки вы можете получить в ответе метода [получения минимальных ставок для карточек товаров](/openapi/promotion#tag/Sozdanie-kampanij/paths/~1adv~1v0~1bids~1min/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.updateAdvBids({});\n   */\n  async updateAdvBids(data: { bids: V0AdvertMultibid[] }): Promise<void> {\n    return this.client.patch('https://advert-api.wildberries.ru/adv/v0/bids', data);\n  }\n\n  /**\n   * Изменение мест размещения в кампаниях с ручной ставкой\n   *\n   * Метод меняет места размещения в кампаниях с ручной ставкой. <br><br> Для кампаний в статусах `4`, `9` и `11`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 1 запрос | 1 секунда | 1 запрос | </div>\n   *\n   * @param data - Request body data\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.updateAuctionPlacements({});\n   */\n  async updateAuctionPlacements(data: { placements: { advert_id: number; placements: { search: boolean; recommendations: boolean } }[] }): Promise<void> {\n    return this.client.put('https://advert-api.wildberries.ru/adv/v0/auction/placements', data);\n  }\n\n  /**\n   * Изменение ставок в кампаниях\n   *\n   * Метод меняет ставки карточек товаров по артикулам WB в кампаниях типа `9` с единой или ручной ставкой. <br><br> Для кампаний в статусах `4`, `9` и `11`. <br><br> В запросе укажите место размещения в параметре `placement`: - `combined` — в поиске и рекомендациях для кампаний с единой ставкой - `search `или `recommendations` — в поиске или рекомендациях для кампаний с ручной ставкой <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 5 запросов | 200 миллисекунд | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.updateAuctionBids({});\n  console.log(result);\n   */\n  async updateAuctionBids(data: { bids: { advert_id: number; nm_bids: { nm_id: number; bid: number; placement: 'search' | 'recommendations' | 'combined' }[] }[] }): Promise<{ bids: { advert_id: number; nm_bids: { nm_id: number; bid: number; placement: string }[] }[] }> {\n    return this.client.patch<{ bids: { advert_id: number; nm_bids: { nm_id: number; bid: number; placement: string }[] }[] }>('https://advert-api.wildberries.ru/adv/v0/auction/bids', data);\n  }\n\n  /**\n   * Баланс\n   *\n   * Метод возвращает информацию о: - счёте кабинета Продвижения WB. Его пополняет продавец. - балансе — максимальной сумме для оплаты камапнии по взаиморасчету: удержании средств из будущих продаж. Баланс пополнить нельзя, он рассчитывается автоматически на основе отчётов по продвижению. - бонусных начислениях WB. Информацию о бюджете кампаний можно получить в [отдельном методе](/openapi/promotion#tag/Finansy/paths/~1adv~1v1~1budget/get). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 1 запрос | 1 секунда | 5 запросов | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvBalance();\n  console.log(result);\n   */\n  async getAdvBalance(): Promise<{ balance?: number; net?: number; bonus?: number; cashbacks?: { sum?: number; percent?: number; expiration_date?: string }[] }> {\n    return this.client.get<{ balance?: number; net?: number; bonus?: number; cashbacks?: { sum?: number; percent?: number; expiration_date?: string }[] }>('https://advert-api.wildberries.ru/adv/v1/balance');\n  }\n\n  /**\n   * Бюджет кампании\n   *\n   * Метод возвращает информацию о бюджете [кампании](/openapi/promotion#tag/Kampanii/paths/~1adv~1v1~1promotion~1adverts/post) — максимальной сумме затрат на кампанию. Бюджет кампании можно [пополнить](/openapi/promotion#tag/Finansy/paths/~1adv~1v1~1budget~1deposit/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 4 запроса | 250 миллисекунд | 4 запроса | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvBudget({});\n  console.log(result);\n   */\n  async getAdvBudget(options?: { id: number }): Promise<{ cash?: number; netting?: number; total?: number }> {\n    return this.client.get<{ cash?: number; netting?: number; total?: number }>('https://advert-api.wildberries.ru/adv/v1/budget', { params: options });\n  }\n\n  /**\n   * Пополнение бюджета кампании\n   *\n   * Метод пополняет [бюджет](/openapi/promotion#tag/Finansy/paths/~1adv~1v1~1budget/get) кампании в статусе `11` — на паузе. <br> Чтобы запустить кампанию после пополнения бюджета, используйте метод [Запуск кампании](/openapi/promotion#tag/Upravlenie-kampaniyami/paths/~1adv~1v0~1start/get). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 1 запрос | 1 секунда | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createBudgetDeposit({}, {});\n  console.log(result);\n   */\n  async createBudgetDeposit(data: { sum?: number; cashback_sum?: number; cashback_percent?: number; type?: number; return?: boolean }, options?: { id: number }): Promise<ResponseWithReturn> {\n    return this.client.post<ResponseWithReturn>('https://advert-api.wildberries.ru/adv/v1/budget/deposit', data, { params: options });\n  }\n\n  /**\n   * Получение истории затрат\n   *\n   * Метод формирует список фактических затрат на рекламные кампании за заданный период. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 1 запрос | 1 секунда | 5 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvUpd({});\n  console.log(result);\n   */\n  async getAdvUpd(options?: { from: string; to: string }): Promise<{ updNum?: number; updTime?: string; updSum?: number; advertId?: number; campName?: string; advertType?: number; paymentType?: string; advertStatus?: number }[]> {\n    return this.client.get<{ updNum?: number; updTime?: string; updSum?: number; advertId?: number; campName?: string; advertType?: number; paymentType?: string; advertStatus?: number }[]>('https://advert-api.wildberries.ru/adv/v1/upd', { params: options });\n  }\n\n  /**\n   * Получение истории пополнений счёта\n   *\n   * Метод возвращает историю пополнений счёта **WB Продвижение** за заданный период. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 1 запрос | 1 секунда | 5 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvPayments({});\n  console.log(result);\n   */\n  async getAdvPayments(options?: { from?: string; to?: string }): Promise<{ id?: number; date?: string; sum?: number; type?: number; statusId?: number; cardStatus?: string }[]> {\n    return this.client.get<{ id?: number; date?: string; sum?: number; type?: number; statusId?: number; cardStatus?: string }[]>('https://advert-api.wildberries.ru/adv/v1/payments', { params: options });\n  }\n\n  /**\n   * Управление активностью фиксированных фраз\n   *\n   * Метод делает активными или неактивными фиксированные фразы в кампаниях [с ручной ставкой](/openapi/promotion#tag/Sozdanie-kampanij/paths/~1adv~1v2~1seacat~1save-ad/post). Фиксированные фразы нужны, чтобы товар отображался в поиске только по определенным поисковым запросам.<br><br> Установить или удалить фиксированные фразы можно через [отдельный метод](/openapi/promotion#tag/Parametry-kampanij/paths/~1adv~1v1~1search~1set-plus/post). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 500 миллисекунд | 1 запрос | 500 миллисекунд | 5 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getSearchSetPlus({});\n  console.log(result);\n   */\n  async getSearchSetPlus(options?: { id: number; fixed?: boolean }): Promise<unknown> {\n    return this.client.get<unknown>('https://advert-api.wildberries.ru/adv/v1/search/set-plus', { params: options });\n  }\n\n  /**\n   * Установка/удаление фиксированных фраз\n   *\n   * Метод устанавливает и удаляет фиксированные фразы в кампаниях [с ручной ставкой](/openapi/promotion#tag/Sozdanie-kampanij/paths/~1adv~1v2~1seacat~1save-ad/post). Фиксированные фразы можно выбрать в списке ключевых фраз кампании, который формируется после запуска.<br><br> Отправка пустого массива в методе удаляет все фиксированные фразы и отключает [активность](/openapi/promotion#tag/Parametry-kampanij/paths/~1adv~1v1~1search~1set-plus/get) всех фиксированных фраз кампании. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 500 миллисекунд | 1 запрос | 500 миллисекунд | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createSearchSetPlus({}, {});\n  console.log(result);\n   */\n  async createSearchSetPlus(data: { pluse?: string[] }, options?: { id: number }): Promise<string[]> {\n    return this.client.post<string[]>('https://advert-api.wildberries.ru/adv/v1/search/set-plus', data, { params: options });\n  }\n\n  /**\n   * Установка/удаление минус-фраз в поиске\n   *\n   * Метод устанавливает и удаляет минус-фразы в поиске, в кампаниях [с ручной ставкой](/openapi/promotion#tag/Sozdanie-kampanij/paths/~1adv~1v2~1seacat~1save-ad/post).<br><br> Данные фразы можно выбрать из списка запросов, по которым покупатели находили ваш товар. Список запросов можно получить в [статистике ключевых фраз](/openapi/analytics#tag/Statistika-po-prodvizheniyu/paths/~1adv~1v0~1stats~1keywords/get).<br>Максимально допустимое количество минус-фраз в кампании — 1000.<br> Отправка пустого массива удаляет все минус-фразы из поиска из кампании. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 2 запроса | 500 миллисекунд | 2 запроса | </div>\n   *\n   * @param data - Request body data\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createSearchSetExcluded({}, {});\n  console.log(result);\n   */\n  async createSearchSetExcluded(data: { excluded?: string[] }, options?: { id: number }): Promise<unknown> {\n    return this.client.post<unknown>('https://advert-api.wildberries.ru/adv/v1/search/set-excluded', data, { params: options });\n  }\n\n  /**\n   * Установка/удаление минус-фраз для кампании с единой ставкой\n   *\n   * Метод устанавливает и удаляет минус-фразы для кампании [с единой ставкой](/openapi/promotion#tag/Sozdanie-kampanij/paths/~1adv~1v1~1save-ad/post).<br><br> Данные фразы можно выбрать из списка запросов, по которым покупатели находили ваш товар. Список запросов можно получить в [статистике ключевых фраз](/openapi/analytics#tag/Statistika-po-prodvizheniyu/paths/~1adv~1v0~1stats~1keywords/get).<br> Отправка пустого массива удаляет все минус-фразы из кампании. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 1 запрос | 6 секунд | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createAutoSetExcluded({}, {});\n  console.log(result);\n   */\n  async createAutoSetExcluded(data: { excluded?: string[] }, options?: { id: number }): Promise<unknown> {\n    return this.client.post<unknown>('https://advert-api.wildberries.ru/adv/v1/auto/set-excluded', data, { params: options });\n  }\n\n  /**\n   * Список карточек товаров для кампании с единой ставкой\n   *\n   * Метод формирует [список карточек товаров](/openapi/promotion#tag/Sozdanie-kampanij/paths/~1adv~1v2~1supplier~1nms/post), которые можно добавить в кампанию с единой ставкой.<br><br> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 1 запрос | 1 секунда | 5 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAutoGetnmtoadd({});\n  console.log(result);\n   */\n  async getAutoGetnmtoadd(options?: { id: number }): Promise<number[]> {\n    return this.client.get<number[]>('https://advert-api.wildberries.ru/adv/v1/auto/getnmtoadd', { params: options });\n  }\n\n  /**\n   * Изменение списка карточек товаров в кампании с единой ставкой\n   *\n   * Метод добавляет и удаляет карточки товаров в кампании с единой ставкой.<br><br> <div class=\"description_important\"> Добавить можно только те карточки товаров, которые вернутся в <a href=\"/openapi/promotion#tag/Parametry-avtomaticheskih-kampanij/paths/~1adv~1v1~1auto~1getnmtoadd/get\">списке карточек товаров для кампании с единой ставкой</a>.<br>Удалить единственную карточку товара из кампании нельзя. </div> Проверки по параметру `delete` не предусмотрено. Если пришел ответ со статус-кодом `200`, а изменений не произошло, проверьте, чтобы запрос соответствовал документации. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 60 запросов | 1 секунда | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createAutoUpdatenm({}, {});\n  console.log(result);\n   */\n  async createAutoUpdatenm(data: { add?: number[]; delete?: number[] }, options?: { id: number }): Promise<unknown> {\n    return this.client.post<unknown>('https://advert-api.wildberries.ru/adv/v1/auto/updatenm', data, { params: options });\n  }\n\n  /**\n   * Изменение списка карточек товаров в кампаниях\n   *\n   * Метод добавляет и удаляет карточки товаров в кампаниях. <br><br> Для кампаний в статусах `4`, `9` и `11`. <br><br> Для добавляемых товаров устанавливается текущая минимальная ставка. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 1 запрос | 1 секунда | 1 запрос | </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.updateAuctionNms({});\n  console.log(result);\n   */\n  async updateAuctionNms(data: { nms: { advert_id: number; nms: { add?: unknown; delete?: number[] } }[] }): Promise<{ nms: { advert_id: number; nms: { added: number[]; deleted: number[] } }[] }> {\n    return this.client.patch<{ nms: { advert_id: number; nms: { added: number[]; deleted: number[] } }[] }>('https://advert-api.wildberries.ru/adv/v0/auction/nms', data);\n  }\n\n  /**\n   * Количество медиакампаний\n   *\n   * Метод возвращает количество [медиакампаний](/openapi/promotion#tag/Media/paths/~1adv~1v1~1advert/get) продавца с группировкой по статусам. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 10 запросов | 100 миллисекунд | 10 запросов | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvCount();\n  console.log(result);\n   */\n  async getAdvCount(): Promise<{ all?: number; adverts?: { type?: number; status?: number; count?: number } }> {\n    return this.client.get<{ all?: number; adverts?: { type?: number; status?: number; count?: number } }>('https://advert-media-api.wildberries.ru/adv/v1/count');\n  }\n\n  /**\n   * Список медиакампаний\n   *\n   * Метод возвращает список всех [медиакампаний](/openapi/promotion#tag/Media/paths/~1adv~1v1~1advert/get) продавца по их типам и статусам. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 10 запросов | 100 миллисекунд | 10 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvAdverts({});\n  console.log(result);\n   */\n  async getAdvAdverts(options?: { status?: number; type?: number; limit?: number; offset?: number; order?: string; direction?: string }): Promise<{ advertId?: number; name?: string; brand?: string; type?: number; status?: number; createTime?: string; endTime?: string }[]> {\n    return this.client.get<{ advertId?: number; name?: string; brand?: string; type?: number; status?: number; createTime?: string; endTime?: string }[]>('https://advert-media-api.wildberries.ru/adv/v1/adverts', { params: options });\n  }\n\n  /**\n   * Информация о медиакампании\n   *\n   * Метод возвращает информацию о кампании [WB Медиа](https://cmp.wildberries.ru/cmpf/list). Вместо карточек товаров в медиакампаниях продвигаются рекламные баннеры продавца на сайте и в приложении WB. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 10 запросов | 100 миллисекунд | 10 запросов | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvAdvert({});\n  console.log(result);\n   */\n  async getAdvAdvert(options?: { id: number }): Promise<{ advertId?: number; name?: string; brand?: string; type?: number; status?: number; createTime?: string; extended?: { reason?: string; expenses?: number; from?: string; to?: string; updated_at?: string; price?: number; budget?: number; operation?: number; contract_id?: number }; items?: { id?: number; name?: string; status?: number; place?: number; budget?: number; daily_limit?: number; category_name?: string; cpm?: number; url?: string; advert_type?: number; created_at?: string; updated_at?: string; date_from?: string; date_to?: string; nms?: number[]; bottomText1?: string; bottomText2?: string; message?: string; additionalSettings?: number; receiversCount?: number; subject_id?: number; subject_name?: string; action_name?: string; show_hours?: { From?: number; To?: number }[]; Erid?: string }[] }> {\n    return this.client.get<{ advertId?: number; name?: string; brand?: string; type?: number; status?: number; createTime?: string; extended?: { reason?: string; expenses?: number; from?: string; to?: string; updated_at?: string; price?: number; budget?: number; operation?: number; contract_id?: number }; items?: { id?: number; name?: string; status?: number; place?: number; budget?: number; daily_limit?: number; category_name?: string; cpm?: number; url?: string; advert_type?: number; created_at?: string; updated_at?: string; date_from?: string; date_to?: string; nms?: number[]; bottomText1?: string; bottomText2?: string; message?: string; additionalSettings?: number; receiversCount?: number; subject_id?: number; subject_name?: string; action_name?: string; show_hours?: { From?: number; To?: number }[]; Erid?: string }[] }>('https://advert-media-api.wildberries.ru/adv/v1/advert', { params: options });\n  }\n\n  /**\n   * Статистика кампаний\n   *\n   * Метод будет отключён 30 сентября. Используйте [актуальный метод](/openapi/promotion#tag/Statistika/paths/~1adv~1v3~1fullstats/get). <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 1 запрос | 1 минута | 5 запросов | </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createAdvFullstats({});\n  console.log(result);\n   */\n  async createAdvFullstats(data: RequestWithDate | RequestWithInterval | RequestWithCampaignID[]): Promise<ResponseWithDate | ResponseWithInterval> {\n    return this.client.post<ResponseWithDate | ResponseWithInterval>('https://advert-api.wildberries.ru/adv/v2/fullstats', data);\n  }\n\n  /**\n   * Статистика кампаний\n   *\n   * Метод формирует статистику для кампаний независимо от типа. <br><br> Максимальный период в запросе — 31 день. <br><br> Для кампаний в статусах `7`, `9` и `11`. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 3 запроса | 20 секунд | 1 запрос | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAdvFullstats({});\n  console.log(result);\n   */\n  async getAdvFullstats(options?: { ids: string; beginDate: string; endDate: string }): Promise<ResponseFullStats> {\n    return this.client.get<ResponseFullStats>('https://advert-api.wildberries.ru/adv/v3/fullstats', { params: options });\n  }\n\n  /**\n   * Статистика кампании с единой ставкой по кластерам фраз\n   *\n   * Метод формирует кластеры ключевых — то есть, наборы похожих — фраз из поисковой строки, если по ним хотя бы один раз были показаны товары из кампании. В ответе метода также указано количество показов этих товаров. <br><br> Информация обновляется каждые 15 минут. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 4 запроса | 250 миллисекунд | 4 запроса | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getAutoStatWords({});\n  console.log(result);\n   */\n  async getAutoStatWords(options?: { id: number }): Promise<{ excluded?: string[]; clusters?: { cluster?: string; count?: number; keywords?: string[] }[] }> {\n    return this.client.get<{ excluded?: string[]; clusters?: { cluster?: string; count?: number; keywords?: string[] }[] }>('https://advert-api.wildberries.ru/adv/v2/auto/stat-words', { params: options });\n  }\n\n  /**\n   * Статистика кампании c ручной ставкой по ключевым фразам\n   *\n   * Метод формирует статистику кампании c ручной ставкой по ключевым фразам из поисковой строки: количество просмотров товара и затраты по одной ключевой фразе. <br><br> Информация обновляется каждые 30 минут. <div class=\"description_important\"> Тип рекламных кампаний <strong>Поиск</strong> устарел. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 4 запроса | 250 миллисекунд | 4 запроса | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getStatWords({});\n  console.log(result);\n   */\n  async getStatWords(options?: { id: number }): Promise<{ words?: { phrase?: string[]; strong?: string[]; excluded?: string[]; pluse?: string[]; keywords?: { keyword?: string; count?: number }[]; fixed?: boolean }; stat?: { advertId?: number; keyword?: string; advertName?: string; campaignName?: string; begin?: string; end?: string; views?: number; clicks?: number; frq?: number; ctr?: number; cpc?: number; duration?: number; sum?: number }[] }> {\n    return this.client.get<{ words?: { phrase?: string[]; strong?: string[]; excluded?: string[]; pluse?: string[]; keywords?: { keyword?: string; count?: number }[]; fixed?: boolean }; stat?: { advertId?: number; keyword?: string; advertName?: string; campaignName?: string; begin?: string; end?: string; views?: number; clicks?: number; frq?: number; ctr?: number; cpc?: number; duration?: number; sum?: number }[] }>('https://advert-api.wildberries.ru/adv/v1/stat/words', { params: options });\n  }\n\n  /**\n   * Статистика по ключевым фразам\n   *\n   * Метод формирует статистику по ключевым фразам из поисковой строки: количество просмотров товара и затраты по одной ключевой фразе. Подходит для кампаний c единой и ручной ставкой. <br><br> Статистика формируется за каждый день, когда кампания была активна. В одном запросе можно получить данные максимум за 7 дней. <br> Данные обновляются каждый час. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 4 запроса | 250 миллисекунд | 4 запроса | </div>\n   *\n   * @param [options] - Query parameters\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getStatsKeywords({});\n  console.log(result);\n   */\n  async getStatsKeywords(options?: { advert_id: number; from: string; to: string }): Promise<V0KeywordsStatisticsResponse> {\n    return this.client.get<V0KeywordsStatisticsResponse>('https://api.wildberries.ru/adv/v0/stats/keywords', { params: options });\n  }\n\n  /**\n   * Статистика медиакампаний\n   *\n   * Метод формирует статистику кампаний сервиса [WB Медиа](https://cmp.wildberries.ru/cmpf/statistics). Статистику можно группировать по датам и/или интервалам. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 секунда | 10 запросов | 100 миллисекунд | 10 запросов | </div>\n   *\n   * @param data - Request body data\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createAdvStats({});\n  console.log(result);\n   */\n  async createAdvStats(data: RequestWithDate | RequestWithInterval | RequestWithCampaignID[]): Promise<StatInterval | StatDate | Stat[]> {\n    return this.client.post<StatInterval | StatDate | Stat[]>('https://advert-media-api.wildberries.ru/adv/v1/stats', data);\n  }\n\n  /**\n   * Список акций\n   *\n   * Метод возвращает список [акций](/openapi/promotion#tag/Kalendar-akcij/paths/~1api~1v1~1calendar~1promotions~1details/get) в WB с датами и временем проведения. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Календарь акций</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getCalendarPromotions();\n  console.log(result);\n   */\n  async getCalendarPromotions(): Promise<unknown> {\n    return this.client.get<unknown>('https://dp-calendar-api.wildberries.ru/api/v1/calendar/promotions');\n  }\n\n  /**\n   * Детальная информация об акциях\n   *\n   * Метод возвращает подробную информацию об [акции](/openapi/promotion#tag/Kalendar-akcij/paths/~1api~1v1~1calendar~1promotions~1details/get) по ID. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Календарь акций</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getPromotionsDetails();\n  console.log(result);\n   */\n  async getPromotionsDetails(): Promise<unknown> {\n    return this.client.get<unknown>('https://dp-calendar-api.wildberries.ru/api/v1/calendar/promotions/details');\n  }\n\n  /**\n   * Список товаров для участия в акции\n   *\n   * Метод формирует список товаров, подходящих для участия в [акции](/openapi/promotion#tag/Kalendar-akcij/paths/~1api~1v1~1calendar~1promotions~1details/get). Эти товары можно добавить в акцию с помощью [отдельного метода](/openapi/promotion#tag/Kalendar-akcij/paths/~1api~1v1~1calendar~1promotions~1upload/post). <div class=\"description_important\"> Данный метод неприменим для автоакций. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Календарь акций</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.getPromotionsNomenclatures();\n  console.log(result);\n   */\n  async getPromotionsNomenclatures(): Promise<unknown> {\n    return this.client.get<unknown>('https://dp-calendar-api.wildberries.ru/api/v1/calendar/promotions/nomenclatures');\n  }\n\n  /**\n   * Добавить товар в акцию\n   *\n   * Метод создаёт задание на загрузку товара в [акцию](/openapi/promotion#tag/Kalendar-akcij/paths/~1api~1v1~1calendar~1promotions~1details/get).<br> Состояние загрузки можно проверить с помощью [отдельных методов](/openapi/work-with-products#tag/Ceny-i-skidki/paths/~1api~1v2~1history~1tasks/get). <div class=\"description_important\"> Данный метод неприменим для автоакций. </div> <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца для всех методов категории <strong>Календарь акций</strong>: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 6 секунд | 10 запросов | 600 миллисекунд | 5 запросов | </div>\n   *\n   * @returns Response data\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.promotion.createPromotionsUpload();\n  console.log(result);\n   */\n  async createPromotionsUpload(): Promise<unknown> {\n    return this.client.post<unknown>('https://dp-calendar-api.wildberries.ru/api/v1/calendar/promotions/upload', undefined);\n  }\n\n}","/**\n * Auto-generated module\n * Generated from: wildberries_api_doc/10-tariffs.yaml\n * DO NOT EDIT MANUALLY - Changes will be overwritten on next generation\n */\n\nimport { BaseClient } from '../../client/base-client';\nimport type { Commission, CommissionChina, CommissionTurkey, CommissionUAE, CommissionUzbekistan, ReturnTariffsResponse, TariffsBoxResponse, TariffsPalletResponse } from '../../types/tariffs.types';\n\nexport class TariffsModule {\n  constructor(private client: BaseClient) {}\n\n  /**\n   * Комиссия по категориям товаров\n   *\n   * Метод возвращает данные о [комиссии](https://seller.wildberries.ru/dynamic-product-categories/commission) WB по [родительским категориям товаров](/openapi/work-with-products#tag/Kategorii-predmety-i-harakteristiki/paths/~1content~1v2~1object~1parent~1all/get) согласно модели продаж. <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 1 запрос | 1 минута | 2 запроса | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.tariffs.getTariffsCommission();\n  console.log(result);\n   */\n  async getTariffsCommission(): Promise<Commission | CommissionChina | CommissionTurkey | CommissionUzbekistan | CommissionUAE> {\n    return this.client.get<Commission | CommissionChina | CommissionTurkey | CommissionUzbekistan | CommissionUAE>('https://common-api.wildberries.ru/api/v1/tariffs/commission');\n  }\n\n  /**\n   * Тарифы для коробов\n   *\n   * Для товаров, которые поставляются на склад в коробах, метод возвращает [тарифы на остаток](https://seller.wildberries.ru/dynamic-product-categories): - доставка со склада или пункта приёма до покупателя - доставка от покупателя до пункта приёма - хранение на складе WB <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 60 запросов | 1 секунда | 5 запросов | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.tariffs.getTariffsBox();\n  console.log(result);\n   */\n  async getTariffsBox(): Promise<TariffsBoxResponse> {\n    return this.client.get<TariffsBoxResponse>('https://common-api.wildberries.ru/api/v1/tariffs/box');\n  }\n\n  /**\n   * Тарифы для монопаллет\n   *\n   * Для товаров, которые поставляются на склад WB на монопаллетах, метод возвращает [стоимость](https://seller.wildberries.ru/dynamic-product-categories): - доставки со склада до покупателя - доставки от покупателя до склада - хранения на складе WB <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 60 запросов | 1 секунда | 5 запросов | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.tariffs.getTariffsPallet();\n  console.log(result);\n   */\n  async getTariffsPallet(): Promise<TariffsPalletResponse> {\n    return this.client.get<TariffsPalletResponse>('https://common-api.wildberries.ru/api/v1/tariffs/pallet');\n  }\n\n  /**\n   * Тарифы на возврат\n   *\n   * Метод возвращает [тарифы](https://seller.wildberries.ru/dynamic-product-categories/return-cost): - на перевозку товаров со склада WB или из пункта приёма до продавца - на обратную перевозку возвратов, которые не забрал продавец <div class=\"description_limit\"> <a href=\"/openapi/api-information#tag/Vvedenie/Limity-zaprosov\">Лимит запросов</a> на один аккаунт продавца: | Период | Лимит | Интервал | Всплеск | | --- | --- | --- | --- | | 1 минута | 60 запросов | 1 секунда | 5 запросов | </div>\n   *\n   * @returns Успешно\n   * @throws {AuthenticationError} When API key is invalid (401/403)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   * @throws {ValidationError} When request data is invalid (400/422)\n   * @throws {NetworkError} When network request fails or times out\n   * @example\n  const result = await sdk.tariffs.getTariffsReturn();\n  console.log(result);\n   */\n  async getTariffsReturn(): Promise<ReturnTariffsResponse> {\n    return this.client.get<ReturnTariffsResponse>('https://common-api.wildberries.ru/api/v1/tariffs/return');\n  }\n\n}","/**\n * In-Store Pickup (Click & Collect) Module\n *\n * Manage click & collect orders where customers purchase online and pick up\n * at seller's physical location. Handles order assembly lifecycle, customer\n * verification, and product metadata management for regulated products.\n *\n * **Context7 References**:\n * - Axios interceptors and error handling: /axios/axios-docs\n * - TypeScript utility types: /microsoft/typescript\n * - Vitest testing patterns: /vitest-dev/vitest\n *\n * @module modules/in-store-pickup\n */\n\nimport type { BaseClient } from '../../client/base-client';\nimport type {\n  NewOrdersResponse,\n  OrdersResponse,\n  OrderStatusesResponse,\n  OrderStatusRequest,\n  OrderClientInfoResponse,\n  CheckIdentityRequest,\n  CheckedIdentity,\n  OrderMetadata,\n  SGTINRequest,\n  UINRequest,\n  IMEIRequest,\n  GTINRequest,\n  GetOrdersParams,\n} from '../../types/in-store-pickup.types';\n\n/**\n * In-Store Pickup (Click & Collect) module\n *\n * Provides comprehensive methods for managing in-store pickup operations:\n * - **Order Assembly Management**: Process orders through lifecycle (new → confirm → prepare → receive/reject)\n * - **Order Queries**: List orders with filtering and get order statuses\n * - **Customer Interaction**: Search customer orders and verify customer identity at pickup\n * - **Metadata Management**: Manage product identification codes (SGTIN, UIN, IMEI, GTIN)\n *\n * **Order Lifecycle States**:\n * - `new` → `confirm` (via confirmOrder) - Start assembly\n * - `confirm` → `prepare` (via prepareOrder) - Mark ready for pickup\n * - `prepare` → `receive` (via receiveOrder) - Complete handover to customer\n * - `prepare` → `reject` (via rejectOrder) - Customer rejected/didn't pick up\n * - Any → `cancel` (via cancelOrder) - Seller cancellation\n *\n * **Rate Limit Note**: 409 responses count as 5 requests toward rate limits!\n *\n * @example Basic pickup workflow\n * ```typescript\n * const sdk = new WildberriesSDK({ apiKey: 'your-api-key' });\n *\n * // 1. Get new pickup orders\n * const newOrders = await sdk.inStorePickup.getNewOrders();\n * const order = newOrders.orders[0];\n *\n * // 2. Confirm order and start assembly\n * await sdk.inStorePickup.confirmOrder(order.id);\n *\n * // 3. Complete assembly\n * await sdk.inStorePickup.prepareOrder(order.id);\n *\n * // 4. Customer arrives - verify identity\n * const verification = await sdk.inStorePickup.verifyCustomerIdentity({\n *   orderCode: order.orderCode,\n *   passcode: '1234' // From customer's app\n * });\n *\n * // 5. Complete handover\n * await sdk.inStorePickup.receiveOrder(order.id);\n * ```\n *\n * @example Metadata management for regulated products\n * ```typescript\n * // Set SGTIN code (Честный знак marking)\n * await sdk.inStorePickup.setSGTINCode(orderId, ['1234567890123456']);\n *\n * // Set IMEI for electronics\n * await sdk.inStorePickup.setIMEICode(orderId, '123456789012345');\n *\n * // Get all metadata\n * const metadata = await sdk.inStorePickup.getOrderMetadata(orderId);\n * ```\n */\nexport class InStorePickupModule {\n  constructor(private client: BaseClient) {}\n\n  // ============================================================\n  // ORDER ASSEMBLY MANAGEMENT\n  // ============================================================\n\n  /**\n   * Get all new pickup orders awaiting processing\n   *\n   * Returns all new assembly tasks for click & collect orders that need to be\n   * processed. Orders should be confirmed and assembled by the seller before\n   * customer pickup.\n   *\n   * **Rate limit**: 300 requests per minute, 200ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @returns Promise resolving to array of new pickup orders\n   * @throws {RateLimitError} When rate limit exceeded\n   * @throws {NetworkError} On network failures\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1new/get}\n   *\n   * @example\n   * ```typescript\n   * const response = await sdk.inStorePickup.getNewOrders();\n   * console.log(`Found ${response.orders.length} new pickup orders`);\n   *\n   * response.orders.forEach(order => {\n   *   console.log(`Order ${order.id}: ${order.article}`);\n   *   console.log(`Customer code: ${order.orderCode}`);\n   *   console.log(`Required metadata: ${order.requiredMeta?.join(', ') || 'None'}`);\n   * });\n   * ```\n   */\n  async getNewOrders(): Promise<NewOrdersResponse> {\n    return this.client.get<NewOrdersResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/new',\n      { rateLimitKey: 'inStorePickup.getNewOrders' }\n    );\n  }\n\n  /**\n   * Confirm order and start assembly process\n   *\n   * Transitions order from `new` to `confirm` status, indicating that assembly\n   * has started. This is required before the order can be prepared.\n   *\n   * **Rate limit**: 100 requests per minute, 600ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the assembly task to confirm\n   * @returns Promise resolving when confirmation succeeds (204 No Content)\n   * @throws {ValidationError} On invalid order ID (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {InvalidOrderStateError} When order state transition is invalid (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1%7BorderId%7D~1confirm/patch}\n   *\n   * @example\n   * ```typescript\n   * try {\n   *   await sdk.inStorePickup.confirmOrder(12345);\n   *   console.log('Order confirmed, assembly started');\n   * } catch (error) {\n   *   if (error.name === 'InvalidOrderStateError') {\n   *     console.error('Order is not in correct state for confirmation');\n   *   }\n   * }\n   * ```\n   */\n  async confirmOrder(orderId: number): Promise<void> {\n    await this.client.patch<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/confirm`,\n      {},\n      { rateLimitKey: 'inStorePickup.confirmOrder' }\n    );\n  }\n\n  /**\n   * Mark order as prepared and ready for customer pickup\n   *\n   * Transitions order from `confirm` to `prepare` status. Order is now assembled\n   * and waiting for customer to arrive for pickup.\n   *\n   * **Rate limit**: 100 requests per minute, 600ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the assembly task to mark as prepared\n   * @returns Promise resolving when preparation succeeds (204 No Content)\n   * @throws {ValidationError} On invalid order ID (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {InvalidOrderStateError} When order state transition is invalid (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1%7BorderId%7D~1prepare/patch}\n   *\n   * @example\n   * ```typescript\n   * try {\n   *   await sdk.inStorePickup.prepareOrder(12345);\n   *   console.log('Order prepared and ready for customer pickup');\n   * } catch (error) {\n   *   if (error.name === 'InvalidOrderStateError') {\n   *     console.error('Order must be confirmed before preparation');\n   *   }\n   * }\n   * ```\n   */\n  async prepareOrder(orderId: number): Promise<void> {\n    await this.client.patch<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/prepare`,\n      {},\n      { rateLimitKey: 'inStorePickup.prepareOrder' }\n    );\n  }\n\n  /**\n   * Complete order handover to customer\n   *\n   * Transitions order from `prepare` to `receive` status. This is the terminal\n   * state indicating successful order completion.\n   *\n   * **Rate limit**: 100 requests per minute, 600ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the assembly task to mark as received\n   * @returns Promise resolving when handover succeeds (204 No Content)\n   * @throws {ValidationError} On invalid order ID (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {InvalidOrderStateError} When order state transition is invalid (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1%7BorderId%7D~1receive/patch}\n   *\n   * @example\n   * ```typescript\n   * // After customer identity verification succeeds\n   * await sdk.inStorePickup.receiveOrder(12345);\n   * console.log('Order successfully handed over to customer');\n   * ```\n   */\n  async receiveOrder(orderId: number): Promise<void> {\n    await this.client.patch<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/receive`,\n      {},\n      { rateLimitKey: 'inStorePickup.receiveOrder' }\n    );\n  }\n\n  /**\n   * Mark order as rejected by customer\n   *\n   * Transitions order from `prepare` to `reject` status when customer refuses\n   * to pick up the order. This is a terminal state.\n   *\n   * **Rate limit**: 100 requests per minute, 600ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the assembly task to mark as rejected\n   * @returns Promise resolving when rejection succeeds (204 No Content)\n   * @throws {ValidationError} On invalid order ID (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {InvalidOrderStateError} When order state transition is invalid (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1%7BorderId%7D~1reject/patch}\n   *\n   * @example\n   * ```typescript\n   * // Customer doesn't show up or refuses order\n   * await sdk.inStorePickup.rejectOrder(12345);\n   * console.log('Order marked as rejected by customer');\n   * ```\n   */\n  async rejectOrder(orderId: number): Promise<void> {\n    await this.client.patch<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/reject`,\n      {},\n      { rateLimitKey: 'inStorePickup.rejectOrder' }\n    );\n  }\n\n  /**\n   * Cancel order (seller cancellation)\n   *\n   * Transitions order to `cancel` status. Can be done from any state. This is\n   * a terminal state.\n   *\n   * **Rate limit**: 100 requests per minute, 600ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the assembly task to cancel\n   * @returns Promise resolving when cancellation succeeds (204 No Content)\n   * @throws {ValidationError} On invalid order ID (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {InvalidOrderStateError} When order state transition is invalid (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1%7BorderId%7D~1cancel/patch}\n   *\n   * @example\n   * ```typescript\n   * // Seller cancels order due to stock issues\n   * await sdk.inStorePickup.cancelOrder(12345);\n   * console.log('Order cancelled by seller');\n   * ```\n   */\n  async cancelOrder(orderId: number): Promise<void> {\n    await this.client.patch<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/cancel`,\n      {},\n      { rateLimitKey: 'inStorePickup.cancelOrder' }\n    );\n  }\n\n  // ============================================================\n  // ORDER QUERIES\n  // ============================================================\n\n  /**\n   * Get completed orders with pagination\n   *\n   * Returns completed pickup orders (after sale or cancellation) for a specified\n   * time period. Maximum 30 calendar days per request.\n   *\n   * **Rate limit**: 300 requests per minute, 200ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param params - Query parameters for filtering\n   * @param params.limit - Maximum number of items to return (1-1000)\n   * @param params.next - Pagination offset (0 for first request)\n   * @param params.dateFrom - Period start date (Unix timestamp)\n   * @param params.dateTo - Period end date (Unix timestamp, max 30 days from dateFrom)\n   * @returns Promise resolving to paginated orders response\n   * @throws {ValidationError} On invalid parameters (400)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders/get}\n   *\n   * @example Get last 7 days of completed orders\n   * ```typescript\n   * const sevenDaysAgo = Math.floor(Date.now() / 1000) - (7 * 24 * 60 * 60);\n   * const now = Math.floor(Date.now() / 1000);\n   *\n   * let allOrders: Order[] = [];\n   * let next = 0;\n   *\n   * do {\n   *   const response = await sdk.inStorePickup.getOrders({\n   *     limit: 1000,\n   *     next,\n   *     dateFrom: sevenDaysAgo,\n   *     dateTo: now\n   *   });\n   *\n   *   allOrders = allOrders.concat(response.orders);\n   *   next = response.next;\n   * } while (next !== 0);\n   *\n   * console.log(`Found ${allOrders.length} completed orders`);\n   * ```\n   */\n  async getOrders(params: GetOrdersParams): Promise<OrdersResponse> {\n    const queryParams: Record<string, number> = {\n      limit: params.limit,\n      next: params.next,\n      dateFrom: params.dateFrom,\n      dateTo: params.dateTo,\n    };\n\n    return this.client.get<OrdersResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/click-collect/orders',\n      {\n        params: queryParams,\n        rateLimitKey: 'inStorePickup.getOrders',\n      }\n    );\n  }\n\n  /**\n   * Get current statuses for multiple orders\n   *\n   * Returns both supplier status (seller-controlled) and WB status (system-controlled)\n   * for specified order IDs.\n   *\n   * **Supplier Statuses**: new, confirm, prepare, receive, reject, cancel, cancel_shelf_life\n   * **WB Statuses**: waiting, sold, canceled, canceled_by_client, declined_by_client, defect, ready_for_pickup\n   *\n   * **Rate limit**: 300 requests per minute, 200ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderIds - Array of order IDs to check\n   * @returns Promise resolving to order statuses\n   * @throws {ValidationError} On invalid request body (400)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1status/post}\n   *\n   * @example\n   * ```typescript\n   * const orderIds = [12345, 12346, 12347];\n   * const statuses = await sdk.inStorePickup.getOrderStatuses(orderIds);\n   *\n   * statuses.orders.forEach(status => {\n   *   console.log(`Order ${status.id}:`);\n   *   console.log(`  Supplier: ${status.supplierStatus}`);\n   *   console.log(`  WB System: ${status.wbStatus}`);\n   * });\n   * ```\n   */\n  async getOrderStatuses(orderIds: number[]): Promise<OrderStatusesResponse> {\n    const request: OrderStatusRequest = { orders: orderIds };\n\n    return this.client.post<OrderStatusesResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/status',\n      request,\n      { rateLimitKey: 'inStorePickup.getOrderStatuses' }\n    );\n  }\n\n  // ============================================================\n  // CUSTOMER INTERACTION\n  // ============================================================\n\n  /**\n   * Get customer information for orders\n   *\n   * Returns customer contact information for specified orders. Only available\n   * for orders in `confirm` (on assembly) or `prepare` (ready for pickup) status.\n   *\n   * **Note**: Phone number is NOT direct customer number - requires extension code\n   *\n   * **Rate limit**: 300 requests per minute, 200ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderIds - Array of order IDs to get customer info for\n   * @returns Promise resolving to customer information\n   * @throws {ValidationError} On invalid request body (400)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1client/post}\n   *\n   * @example\n   * ```typescript\n   * const customerInfo = await sdk.inStorePickup.getCustomerInfo([12345]);\n   *\n   * customerInfo.orders.forEach(info => {\n   *   console.log(`Order ${info.orderID}: ${info.firstName}`);\n   *   console.log(`Contact: ${info.phone}, extension ${info.phoneCode}`);\n   * });\n   * ```\n   */\n  async getCustomerInfo(orderIds: number[]): Promise<OrderClientInfoResponse> {\n    const request: OrderStatusRequest = { orders: orderIds };\n\n    return this.client.post<OrderClientInfoResponse>(\n      'https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/client',\n      request,\n      { rateLimitKey: 'inStorePickup.getCustomerInfo' }\n    );\n  }\n\n  /**\n   * Verify customer identity at pickup\n   *\n   * Verifies that the order belongs to the customer by validating their passcode.\n   * Only available when at least one assembly task from the order is in `prepare` status.\n   *\n   * **Rate limit**: 30 requests per minute, 2s interval, 20 burst (MOST RESTRICTIVE!)\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param request - Identity verification request\n   * @param request.orderCode - Customer's unique order code\n   * @param request.passcode - Verification passcode from customer's app\n   * @returns Promise resolving to verification result (always { ok: true } on success)\n   * @throws {ValidationError} On invalid request body (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {CustomerVerificationError} When passcode is incorrect (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Sborochnye-zadaniya-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1client~1identity/post}\n   *\n   * @example\n   * ```typescript\n   * try {\n   *   const result = await sdk.inStorePickup.verifyCustomerIdentity({\n   *     orderCode: '21117866-0006',\n   *     passcode: '1234'\n   *   });\n   *\n   *   if (result.ok) {\n   *     console.log('Customer verified! Proceed with handover');\n   *     // Now call receiveOrder()\n   *   }\n   * } catch (error) {\n   *   if (error.name === 'CustomerVerificationError') {\n   *     console.error('Invalid passcode - ask customer to check their app');\n   *   }\n   * }\n   * ```\n   */\n  async verifyCustomerIdentity(request: CheckIdentityRequest): Promise<CheckedIdentity> {\n    return this.client.post<CheckedIdentity>(\n      'https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/client/identity',\n      request,\n      { rateLimitKey: 'inStorePickup.verifyCustomerIdentity' }\n    );\n  }\n\n  // ============================================================\n  // METADATA MANAGEMENT\n  // ============================================================\n\n  /**\n   * Get product metadata for order\n   *\n   * Returns identification codes (SGTIN, UIN, IMEI, GTIN) associated with the order.\n   * Available metadata types are listed in the `requiredMeta` field of new orders.\n   *\n   * **Rate limit**: 300 requests per minute, 200ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the order to get metadata for\n   * @returns Promise resolving to order metadata\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Metadannye-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1{orderId}~1meta/get}\n   *\n   * @example\n   * ```typescript\n   * const metadata = await sdk.inStorePickup.getOrderMetadata(12345);\n   *\n   * console.log('Order metadata:');\n   * if (metadata.meta.sgtin?.value) {\n   *   console.log(`SGTIN: ${metadata.meta.sgtin.value.join(', ')}`);\n   * }\n   * if (metadata.meta.imei?.value) {\n   *   console.log(`IMEI: ${metadata.meta.imei.value}`);\n   * }\n   * ```\n   */\n  async getOrderMetadata(orderId: number): Promise<OrderMetadata> {\n    return this.client.get<OrderMetadata>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/meta`,\n      { rateLimitKey: 'inStorePickup.getOrderMetadata' }\n    );\n  }\n\n  /**\n   * Delete metadata for order\n   *\n   * Removes metadata value for specified key. Valid keys: imei, uin, gtin, sgtin.\n   * Only one key can be deleted per request.\n   *\n   * **Rate limit**: 300 requests per minute, 200ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the order to delete metadata from\n   * @param key - Metadata key to delete (imei, uin, gtin, sgtin)\n   * @returns Promise resolving when deletion succeeds (204 No Content)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Metadannye-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1{orderId}~1meta/delete}\n   *\n   * @example\n   * ```typescript\n   * // Remove IMEI code\n   * await sdk.inStorePickup.deleteOrderMetadata(12345, 'imei');\n   * console.log('IMEI metadata deleted');\n   * ```\n   */\n  async deleteOrderMetadata(orderId: number, key: 'imei' | 'uin' | 'gtin' | 'sgtin'): Promise<void> {\n    await this.client.delete<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/meta`,\n      undefined,\n      {\n        params: { key },\n        rateLimitKey: 'inStorePickup.deleteOrderMetadata',\n      }\n    );\n  }\n\n  /**\n   * Set SGTIN codes (Честный знак marking)\n   *\n   * Assigns SGTIN codes for Честный знак product marking system. Only available\n   * when order is in `confirm` status and `sgtin` is in order's `requiredMeta`.\n   *\n   * **Rate limit**: 1000 requests per minute, 60ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the order to set SGTIN for\n   * @param sgtins - Array of SGTIN codes (16-135 characters each)\n   * @returns Promise resolving when codes are set (204 No Content)\n   * @throws {ValidationError} On invalid codes (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {MetadataValidationError} When metadata cannot be updated (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Metadannye-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1{orderId}~1meta~1sgtin/put}\n   *\n   * @example\n   * ```typescript\n   * // Scan SGTIN codes from product marking\n   * await sdk.inStorePickup.setSGTINCode(12345, [\n   *   '01047264500236891521AbCdEf1234567890',\n   *   '01047264500236892521GhIjKl0987654321'\n   * ]);\n   * console.log('SGTIN codes assigned');\n   * ```\n   */\n  async setSGTINCode(orderId: number, sgtins: string[]): Promise<void> {\n    const request: SGTINRequest = { sgtins };\n\n    await this.client.put<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/meta/sgtin`,\n      request,\n      { rateLimitKey: 'inStorePickup.setSGTINCode' }\n    );\n  }\n\n  /**\n   * Set UIN code (Unique Identification Number)\n   *\n   * Assigns UIN for the order. Only available when order is in `confirm` status\n   * and `uin` is in order's `requiredMeta`.\n   *\n   * **Rate limit**: 1000 requests per minute, 60ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the order to set UIN for\n   * @param uin - UIN code\n   * @returns Promise resolving when code is set (204 No Content)\n   * @throws {ValidationError} On invalid code (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {MetadataValidationError} When metadata cannot be updated (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Metadannye-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1{orderId}~1meta~1uin/put}\n   *\n   * @example\n   * ```typescript\n   * await sdk.inStorePickup.setUINCode(12345, '1234567890123456');\n   * console.log('UIN code assigned');\n   * ```\n   */\n  async setUINCode(orderId: number, uin: string): Promise<void> {\n    const request: UINRequest = { uin };\n\n    await this.client.put<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/meta/uin`,\n      request,\n      { rateLimitKey: 'inStorePickup.setUINCode' }\n    );\n  }\n\n  /**\n   * Set IMEI code (for electronics)\n   *\n   * Assigns IMEI code for electronic devices. Only available when order is in\n   * `confirm` status and `imei` is in order's `requiredMeta`.\n   *\n   * **Rate limit**: 1000 requests per minute, 60ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the order to set IMEI for\n   * @param imei - IMEI code (15 digits)\n   * @returns Promise resolving when code is set (204 No Content)\n   * @throws {ValidationError} On invalid code (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {MetadataValidationError} When metadata cannot be updated (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Metadannye-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1{orderId}~1meta~1imei/put}\n   *\n   * @example\n   * ```typescript\n   * // Scan IMEI from device\n   * await sdk.inStorePickup.setIMEICode(12345, '123456789012345');\n   * console.log('IMEI code assigned');\n   * ```\n   */\n  async setIMEICode(orderId: number, imei: string): Promise<void> {\n    const request: IMEIRequest = { imei };\n\n    await this.client.put<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/meta/imei`,\n      request,\n      { rateLimitKey: 'inStorePickup.setIMEICode' }\n    );\n  }\n\n  /**\n   * Set GTIN code (Belarus product ID)\n   *\n   * Assigns GTIN code (unique product ID in Belarus). Only available when order\n   * is in `confirm` status and `gtin` is in order's `requiredMeta`.\n   *\n   * **Rate limit**: 1000 requests per minute, 60ms interval, 20 burst\n   * **Note**: 409 responses count as 5 requests\n   *\n   * @param orderId - ID of the order to set GTIN for\n   * @param gtin - GTIN code\n   * @returns Promise resolving when code is set (204 No Content)\n   * @throws {ValidationError} On invalid code (400)\n   * @throws {NotFoundError} When order doesn't exist (404)\n   * @throws {MetadataValidationError} When metadata cannot be updated (409)\n   * @throws {RateLimitError} When rate limit exceeded (429)\n   *\n   * @see {@link https://dev.wildberries.ru/openapi/in-store-pickup#tag/Metadannye-Samovyvoz/paths/~1api~1v3~1click-collect~1orders~1{orderId}~1meta~1gtin/put}\n   *\n   * @example\n   * ```typescript\n   * await sdk.inStorePickup.setGTINCode(12345, '1234567890123456');\n   * console.log('GTIN code assigned');\n   * ```\n   */\n  async setGTINCode(orderId: number, gtin: string): Promise<void> {\n    const request: GTINRequest = { gtin };\n\n    await this.client.put<unknown>(\n      `https://marketplace-api.wildberries.ru/api/v3/click-collect/orders/${orderId}/meta/gtin`,\n      request,\n      { rateLimitKey: 'inStorePickup.setGTINCode' }\n    );\n  }\n}\n","/**\n * Auto-generated rate limit configuration for promotion module\n * Generated from: wildberries_api_doc/08-promotion.yaml\n * DO NOT EDIT MANUALLY - Changes will be overwritten on regeneration\n *\n * This file contains rate limit configurations extracted from OpenAPI operation descriptions.\n * Rate limits are enforced by the RateLimiter (Story 1.4) using the token bucket algorithm.\n *\n * @see {@link ../../src/client/rate-limiter!RateLimiter RateLimiter Documentation}\n * @module config/promotion-rate-limits\n * @generated\n */\n\nimport type { RateLimitConfig } from '../client/rate-limiter';\n\nexport const promotionRateLimits: Record<string, RateLimitConfig> = {\n  'promotion.advPromotionCount': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.postAdvPromotionAdverts': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.advAuctionAdverts': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.advConfig': {\n    requestsPerMinute: 1,\n    intervalSeconds: 60,\n    burstLimit: 1\n  },\n  'promotion.postAdvBidsMin': {\n    requestsPerMinute: 20,\n    intervalSeconds: 3,\n    burstLimit: 5\n  },\n  'promotion.postAdvSaveAd': {\n    requestsPerMinute: 3,\n    intervalSeconds: 20,\n    burstLimit: 5\n  },\n  'promotion.postAdvSeacatSaveAd': {\n    requestsPerMinute: 5,\n    intervalSeconds: 12,\n    burstLimit: 5\n  },\n  'promotion.advSupplierSubjects': {\n    requestsPerMinute: 5,\n    intervalSeconds: 12,\n    burstLimit: 5\n  },\n  'promotion.postAdvSupplierNms': {\n    requestsPerMinute: 5,\n    intervalSeconds: 12,\n    burstLimit: 5\n  },\n  'promotion.advDelete': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.postAdvRename': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.advStart': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.advPause': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.advStop': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.patchAdvBids': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.putAdvAuctionPlacements': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 1\n  },\n  'promotion.patchAdvAuctionBids': {\n    requestsPerMinute: 300,\n    intervalSeconds: 0.2,\n    burstLimit: 5\n  },\n  'promotion.advBalance': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 5\n  },\n  'promotion.advBudget': {\n    requestsPerMinute: 240,\n    intervalSeconds: 0.25,\n    burstLimit: 4\n  },\n  'promotion.postAdvBudgetDeposit': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 5\n  },\n  'promotion.advUpd': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 5\n  },\n  'promotion.advPayments': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 5\n  },\n  'promotion.advSearchSetPlus': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'promotion.postAdvSearchSetPlus': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'promotion.postAdvSearchSetExcluded': {\n    requestsPerMinute: 120,\n    intervalSeconds: 0.5,\n    burstLimit: 2\n  },\n  'promotion.postAdvAutoSetExcluded': {\n    requestsPerMinute: 10,\n    intervalSeconds: 6,\n    burstLimit: 5\n  },\n  'promotion.advAutoGetnmtoadd': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 5\n  },\n  'promotion.postAdvAutoUpdatenm': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 5\n  },\n  'promotion.patchAdvAuctionNms': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 1\n  },\n  'promotion.advCount': {\n    requestsPerMinute: 600,\n    intervalSeconds: 0.1,\n    burstLimit: 10\n  },\n  'promotion.advAdverts': {\n    requestsPerMinute: 600,\n    intervalSeconds: 0.1,\n    burstLimit: 10\n  },\n  'promotion.advAdvert': {\n    requestsPerMinute: 600,\n    intervalSeconds: 0.1,\n    burstLimit: 10\n  },\n  'promotion.postAdvFullstats': {\n    requestsPerMinute: 1,\n    intervalSeconds: 60,\n    burstLimit: 5\n  },\n  'promotion.advFullstats': {\n    requestsPerMinute: 3,\n    intervalSeconds: 20,\n    burstLimit: 1\n  },\n  'promotion.advAutoStatWords': {\n    requestsPerMinute: 240,\n    intervalSeconds: 0.25,\n    burstLimit: 4\n  },\n  'promotion.advStatWords': {\n    requestsPerMinute: 240,\n    intervalSeconds: 0.25,\n    burstLimit: 4\n  },\n  'promotion.advStatsKeywords': {\n    requestsPerMinute: 240,\n    intervalSeconds: 0.25,\n    burstLimit: 4\n  },\n  'promotion.postAdvStats': {\n    requestsPerMinute: 600,\n    intervalSeconds: 0.1,\n    burstLimit: 10\n  },\n  'promotion.calendarPromotions': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'promotion.calendarPromotionsDetails': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'promotion.calendarPromotionsNomenclatures': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  },\n  'promotion.postCalendarPromotionsUpload': {\n    requestsPerMinute: 100,\n    intervalSeconds: 0.6,\n    burstLimit: 5\n  }\n};\n","/**\n * Auto-generated rate limit configuration for tariffs module\n * Generated from: wildberries_api_doc/10-tariffs.yaml\n * DO NOT EDIT MANUALLY - Changes will be overwritten on regeneration\n *\n * This file contains rate limit configurations extracted from OpenAPI operation descriptions.\n * Rate limits are enforced by the RateLimiter (Story 1.4) using the token bucket algorithm.\n *\n * @see {@link ../../src/client/rate-limiter!RateLimiter RateLimiter Documentation}\n * @module config/tariffs-rate-limits\n * @generated\n */\n\nimport type { RateLimitConfig } from '../client/rate-limiter';\n\nexport const tariffsRateLimits: Record<string, RateLimitConfig> = {\n  'tariffs.tariffsCommission': {\n    requestsPerMinute: 1,\n    intervalSeconds: 60,\n    burstLimit: 2\n  },\n  'tariffs.tariffsBox': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 5\n  },\n  'tariffs.tariffsPallet': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 5\n  },\n  'tariffs.tariffsReturn': {\n    requestsPerMinute: 60,\n    intervalSeconds: 1,\n    burstLimit: 5\n  }\n};\n","/**\n * Communications Module Types\n * Generated from wildberries_api_doc/09-communications.yaml\n *\n * This module provides types for:\n * 1. Chat with Customers - Real-time messaging with buyers\n * 2. Product Q&A - Managing customer questions about products\n * 3. Customer Reviews - Responding to product reviews with photos/videos\n *\n * @module communications.types\n */\n\n/**\n * Order information attached to a chat message\n */\nexport interface GoodCard {\n  /**\n   * Order date\n   */\n  date: string;\n\n  /**\n   * @deprecated This field will be removed. Use separate method for customer return requests.\n   * Whether return is requested:\n   * - `false` — not requested\n   * - `true` — requested\n   */\n  needRefund?: boolean;\n\n  /**\n   * Wildberries product ID (nmID)\n   */\n  nmID: number;\n\n  /**\n   * Actual price with all discounts applied (charged to customer)\n   */\n  price: number;\n\n  /**\n   * Currency code (e.g., 'RUB')\n   */\n  priceCurrency: string;\n\n  /**\n   * Unique order ID\n   * Note: `rid` is equivalent to `srid` in Orders/Sales API responses\n   */\n  rid: string;\n\n  /**\n   * Product size (corresponds to `wbSize` in product card)\n   */\n  size: string;\n\n  /**\n   * Product order status:\n   * - `0` — Active\n   * - `1` — Created\n   * - `2` — Being collected\n   * - `3` — In transit\n   * - `4` — Waiting at pickup point\n   * - `5` — With courier\n   * - `10` — Archived\n   * - `11` — Purchased\n   * - `12` — Cancelled\n   * - `13` — Return requested\n   * - `14` — Cancelled (out of stock)\n   */\n  statusID: number;\n}\n\n/**\n * Chat conversation object\n */\nexport interface Chat {\n  /**\n   * Chat ID\n   * @example \"1:4019cd7d-cca8-4e90-8b11-f78afbea42e3\"\n   */\n  chatID: string;\n\n  /**\n   * Chat signature required for sending messages\n   * Use this value as the `replySign` parameter when calling sendMessage()\n   * @example \"1:4019cd7d-cca8-4e90-8b11-f78afbea42e3:54828159:bc3a4c04079f5956cff170b25e73523aa1208b5c0bd7aea1e520a64ae3e212b1ebae6712661f3afd27520fa785fa3042254e8a3100ce00644322054ae7cfcd0e\"\n   */\n  replySign: string;\n\n  /**\n   * Customer ID\n   * @example \"123456\"\n   */\n  clientID: string;\n\n  /**\n   * Customer name\n   * @example \"Иван\"\n   */\n  clientName: string;\n\n  /**\n   * Order information associated with the chat\n   */\n  goodCard?: GoodCard;\n}\n\n/**\n * Response from getChats() method\n */\nexport interface ChatsResponse {\n  /**\n   * Array of chat conversations\n   */\n  result: Chat[];\n\n  /**\n   * Error messages, if any\n   */\n  errors: string[] | null;\n}\n\n/**\n * Event type enum\n */\nexport enum EventType {\n  /**\n   * Message event\n   */\n  MESSAGE = 'message',\n}\n\n/**\n * Message sender enum\n */\nexport enum Sender {\n  /**\n   * Message sent by customer\n   */\n  CLIENT = 'client',\n\n  /**\n   * Message sent by seller\n   */\n  SELLER = 'seller',\n\n  /**\n   * Message sent by Wildberries system\n   */\n  WB = 'wb',\n}\n\n/**\n * File attachment in chat event\n */\nexport interface EventFile {\n  /**\n   * MIME type of the file\n   * @example \"application/pdf\"\n   */\n  contentType: string;\n\n  /**\n   * Upload date\n   */\n  date: string;\n\n  /**\n   * File download ID (use with download endpoint)\n   */\n  downloadID: string;\n\n  /**\n   * Original file name\n   * @example \"Чек.pdf\"\n   */\n  name: string;\n\n  /**\n   * Direct URL for file download\n   */\n  url: string;\n\n  /**\n   * File size in bytes\n   */\n  size: number;\n}\n\n/**\n * Image attachment in chat event\n */\nexport interface EventImage {\n  /**\n   * Upload date\n   */\n  date: string;\n\n  /**\n   * Image download ID (use with download endpoint)\n   */\n  downloadID: string;\n\n  /**\n   * Direct URL for image download\n   */\n  url: string;\n}\n\n/**\n * Attachments in chat event message\n */\nexport interface EventAttachments {\n  /**\n   * Order information\n   */\n  goodCard?: GoodCard;\n\n  /**\n   * File attachments (PDF, etc.)\n   */\n  files?: EventFile[];\n\n  /**\n   * Image attachments (JPEG, PNG)\n   */\n  images?: EventImage[];\n}\n\n/**\n * Message content in chat event\n */\nexport interface EventMessage {\n  /**\n   * Message text content\n   */\n  text?: string;\n\n  /**\n   * Attachments included in the message\n   */\n  attachments?: EventAttachments;\n}\n\n/**\n * Chat event object\n * Represents a message or activity in the chat conversation\n */\nexport interface ChatEvent {\n  /**\n   * Chat ID this event belongs to\n   */\n  chatID: string;\n\n  /**\n   * Unique event ID\n   */\n  eventID: string;\n\n  /**\n   * Event type (currently only 'message')\n   */\n  eventType: EventType | string;\n\n  /**\n   * Indicates if this is a new chat\n   * - `false` — existing chat\n   * - `true` — new chat (replySign will be available)\n   */\n  isNewChat: boolean;\n\n  /**\n   * Message content and attachments\n   */\n  message?: EventMessage;\n\n  /**\n   * Message source platform:\n   * - `seller-portal` — seller portal\n   * - `seller-public-api` — Chat API\n   * - `rusite` — customer portal\n   * - `global` — global.wildberries.ru\n   * - `ios` — iOS mobile app\n   * - `android` — Android mobile app\n   */\n  source: string;\n\n  /**\n   * Event timestamp (Unix timestamp with milliseconds)\n   * @example 1698037340000\n   */\n  addTimestamp: number;\n\n  /**\n   * Event timestamp in UTC (RFC 3339 format)\n   * @example \"2023-10-23T05:02:20Z\"\n   */\n  addTime: string;\n\n  /**\n   * Chat signature for sending replies\n   * Only available when `isNewChat: true`\n   * Use this value as the `replySign` parameter when calling sendMessage()\n   */\n  replySign?: string;\n\n  /**\n   * Message sender\n   */\n  sender: Sender | string;\n\n  /**\n   * Customer ID\n   */\n  clientID: string;\n\n  /**\n   * Customer name\n   */\n  clientName: string;\n}\n\n/**\n * Result object containing events and pagination data\n */\nexport interface EventsResult {\n  /**\n   * Cursor for next page (Unix timestamp with milliseconds)\n   * Use this value in the next getChatEvents() call to fetch subsequent events\n   */\n  next: number;\n\n  /**\n   * Timestamp of newest event in response (RFC 3339 format)\n   */\n  newestEventTime: string | null;\n\n  /**\n   * Timestamp of oldest event in response (RFC 3339 format)\n   */\n  oldestEventTime: string | null;\n\n  /**\n   * Number of events in this response\n   * When `totalEvents` is 0, there are no more events to fetch\n   */\n  totalEvents: number;\n\n  /**\n   * Array of chat events\n   */\n  events: ChatEvent[];\n}\n\n/**\n * Response from getChatEvents() method\n */\nexport interface EventsResponse {\n  /**\n   * Events result with pagination\n   */\n  result: EventsResult;\n\n  /**\n   * Error messages, if any\n   */\n  errors: string[] | null;\n}\n\n/**\n * Response from sendMessage() method\n */\nexport interface MessageResponse {\n  /**\n   * Message send result\n   */\n  result: {\n    /**\n     * Message upload timestamp (Unix timestamp with milliseconds)\n     */\n    addTime: number;\n\n    /**\n     * Chat ID where message was sent\n     */\n    chatID: string;\n  };\n\n  /**\n   * File upload errors, if any\n   */\n  errors: string[];\n}\n\n/**\n * Request parameters for sendMessage() method\n * Note: This is sent as multipart/form-data, not JSON\n */\nexport interface SendMessageRequest {\n  /**\n   * Chat signature (required)\n   * Obtain from Chat.replySign or Event.replySign (when isNewChat=true)\n   */\n  replySign: string;\n\n  /**\n   * Message text (optional, max 1000 characters)\n   * At least one of message or file must be provided\n   */\n  message?: string;\n\n  /**\n   * File attachments (optional)\n   * Formats: JPEG, PDF, PNG\n   * Max size: 5MB per file, 30MB total\n   */\n  files?: File[] | Blob[];\n}\n\n// ============================================================================\n// Product Q&A Types\n// ============================================================================\n\n/**\n * Filter criteria for retrieving product questions\n */\nexport interface QuestionFilters {\n  /**\n   * Whether question has been answered (required)\n   * - `true` — answered questions\n   * - `false` — unanswered questions\n   */\n  isAnswered: boolean;\n\n  /**\n   * Wildberries product ID to filter by (optional)\n   * Filter questions for a specific product\n   */\n  nmId?: number;\n\n  /**\n   * Number of questions to retrieve (required)\n   * Maximum allowed: 10,000\n   * Note: take + skip must not exceed 10,000\n   */\n  take: number;\n\n  /**\n   * Number of questions to skip for pagination (required)\n   * Maximum allowed: 10,000\n   * Note: take + skip must not exceed 10,000\n   */\n  skip: number;\n\n  /**\n   * Sort order by date (optional)\n   * - `dateAsc` — oldest first\n   * - `dateDesc` — newest first (default)\n   */\n  order?: 'dateAsc' | 'dateDesc';\n\n  /**\n   * Filter start date (Unix timestamp) (optional)\n   */\n  dateFrom?: number;\n\n  /**\n   * Filter end date (Unix timestamp) (optional)\n   */\n  dateTo?: number;\n\n  /**\n   * Index signature for compatibility with HTTP client params\n   */\n  [key: string]: unknown;\n}\n\n/**\n * Question state enum\n */\nexport enum QuestionState {\n  /**\n   * Question rejected by seller (not visible to customers)\n   */\n  NONE = 'none',\n\n  /**\n   * Answer provided and visible on customer portal\n   */\n  WB_RU = 'wbRu',\n\n  /**\n   * New question from customer awaiting response\n   */\n  SUPPLIERS_PORTAL_SYNCH = 'suppliersPortalSynch',\n}\n\n/**\n * Answer to a customer question\n */\nexport interface QuestionAnswer {\n  /**\n   * Answer text content\n   */\n  text: string;\n\n  /**\n   * Whether answer can be edited\n   * - `false` — cannot edit (60 days passed or not editable)\n   * - `true` — can edit (within 60 days, edit once allowed)\n   */\n  editable: boolean;\n\n  /**\n   * Answer creation timestamp (ISO 8601)\n   * @example \"2024-01-16T10:00:00Z\"\n   */\n  createDate: string;\n}\n\n/**\n * Product information in question\n */\nexport interface QuestionProductDetails {\n  /**\n   * Wildberries product ID (nmId)\n   */\n  nmId: number;\n\n  /**\n   * Product card ID\n   */\n  imtId: number;\n\n  /**\n   * Product name\n   */\n  productName: string;\n\n  /**\n   * Seller's article/SKU\n   */\n  supplierArticle: string;\n\n  /**\n   * Seller name\n   */\n  supplierName: string;\n\n  /**\n   * Brand name\n   */\n  brandName: string;\n\n  /**\n   * Product size\n   * @deprecated This field will be deprecated\n   */\n  size: string;\n}\n\n/**\n * Customer question object\n */\nexport interface Question {\n  /**\n   * Question ID\n   */\n  id: string;\n\n  /**\n   * Question text from customer\n   */\n  text: string;\n\n  /**\n   * Question creation timestamp (ISO 8601)\n   * @example \"2022-02-01T11:18:08.769513469Z\"\n   */\n  createdDate: string;\n\n  /**\n   * Question state/status\n   */\n  state: QuestionState | string;\n\n  /**\n   * Answer to question (null if not answered)\n   */\n  answer: QuestionAnswer | null;\n\n  /**\n   * Product information\n   */\n  productDetails: QuestionProductDetails;\n\n  /**\n   * Whether seller has viewed the question\n   */\n  wasViewed: boolean;\n\n  /**\n   * Whether question is suspicious\n   * If `true`, question is published but marked with warning banner\n   */\n  isWarned: boolean;\n}\n\n/**\n * Response from getQuestions() method\n */\nexport interface QuestionsResponse {\n  /**\n   * Questions data\n   */\n  data: {\n    /**\n     * Count of unanswered questions\n     */\n    countUnanswered: number;\n\n    /**\n     * Count of answered/archived questions\n     */\n    countArchive: number;\n\n    /**\n     * Array of questions\n     */\n    questions: Question[];\n  };\n\n  /**\n   * Whether there was an error\n   */\n  error: boolean;\n\n  /**\n   * Error description text\n   */\n  errorText: string;\n\n  /**\n   * Additional errors array\n   */\n  additionalErrors: string[] | null;\n}\n\n/**\n * Request payload for answering a question\n * Used internally by answerQuestion() method\n */\nexport interface AnswerQuestionRequest {\n  /**\n   * Question ID\n   */\n  id: string;\n\n  /**\n   * Answer object\n   */\n  answer: {\n    /**\n     * Answer text\n     */\n    text: string;\n  };\n\n  /**\n   * Question state after answer\n   * - `none` — reject question (not visible to customers)\n   * - `wbRu` — answer visible to customers\n   */\n  state: 'none' | 'wbRu';\n}\n\n/**\n * Request payload for marking question as viewed\n * Used internally by markQuestionViewed() method\n */\nexport interface MarkQuestionViewedRequest {\n  /**\n   * Question ID\n   */\n  id: string;\n\n  /**\n   * Mark as viewed\n   */\n  wasViewed: boolean;\n}\n\n// ============================================================================\n// Customer Reviews Types\n// ============================================================================\n\n/**\n * Filter criteria for retrieving customer reviews\n */\nexport interface ReviewFilters {\n  /**\n   * Whether review has been answered (required)\n   * - `true` — answered/processed reviews\n   * - `false` — unanswered/unprocessed reviews\n   */\n  isAnswered: boolean;\n\n  /**\n   * Wildberries product ID to filter by (optional)\n   * Filter reviews for a specific product\n   */\n  nmId?: number;\n\n  /**\n   * Number of reviews to retrieve (required)\n   * Maximum allowed: 5,000\n   */\n  take: number;\n\n  /**\n   * Number of reviews to skip for pagination (required)\n   * Maximum allowed: 199,990\n   */\n  skip: number;\n\n  /**\n   * Sort order by date (optional)\n   * - `dateAsc` — oldest first\n   * - `dateDesc` — newest first (default)\n   */\n  order?: 'dateAsc' | 'dateDesc';\n\n  /**\n   * Filter start date (Unix timestamp) (optional)\n   */\n  dateFrom?: number;\n\n  /**\n   * Filter end date (Unix timestamp) (optional)\n   */\n  dateTo?: number;\n\n  /**\n   * Index signature for compatibility with HTTP client params\n   */\n  [key: string]: unknown;\n}\n\n/**\n * Review state enum\n */\nexport enum ReviewState {\n  /**\n   * New/unprocessed review\n   */\n  NONE = 'none',\n\n  /**\n   * Processed review (visible on site)\n   */\n  WB_RU = 'wbRu',\n}\n\n/**\n * Review answer state enum\n */\nexport enum ReviewAnswerState {\n  /**\n   * New response\n   */\n  NONE = 'none',\n\n  /**\n   * Response visible on customer portal\n   */\n  WB_RU = 'wbRu',\n\n  /**\n   * Response under review\n   */\n  REVIEW_REQUIRED = 'reviewRequired',\n\n  /**\n   * Response rejected\n   */\n  REJECTED = 'rejected',\n}\n\n/**\n * Seller's response to a review\n */\nexport interface ReviewAnswer {\n  /**\n   * Response text\n   */\n  text: string;\n\n  /**\n   * Response state/status\n   */\n  state: ReviewAnswerState | string;\n\n  /**\n   * Whether response can be edited\n   * - `false` — cannot edit (60 days passed or already edited)\n   * - `true` — can edit (within 60 days, edit once allowed)\n   */\n  editable: boolean;\n}\n\n/**\n * Product information in review\n */\nexport interface ReviewProductDetails {\n  /**\n   * Wildberries product ID (nmId)\n   */\n  nmId: number;\n\n  /**\n   * Product card ID\n   */\n  imtId: number;\n\n  /**\n   * Product name\n   */\n  productName: string;\n\n  /**\n   * Seller's article/SKU\n   */\n  supplierArticle: string | null;\n\n  /**\n   * Seller name\n   */\n  supplierName: string | null;\n\n  /**\n   * Brand name\n   */\n  brandName: string | null;\n\n  /**\n   * Product size (techSize in product card)\n   */\n  size: string;\n}\n\n/**\n * Photo link in review\n */\nexport interface ReviewPhoto {\n  /**\n   * Full-size photo URL\n   * @example \"https://feedback04.wbbasket.ru/vol1333/part133337/123456789/photos/fs.jpg\"\n   */\n  fullSize: string;\n\n  /**\n   * Thumbnail photo URL\n   * @example \"https://feedback04.wbbasket.ru/vol1333/part133337/123456789/photos/ms.jpg\"\n   */\n  miniSize: string;\n}\n\n/**\n * Video in review\n */\nexport interface ReviewVideo {\n  /**\n   * Video preview image URL\n   * @example \"https://videofeedback01.wbbasket.ru/8defc853-7f62-4d6d-b236-8a16cfb63128/preview.webp\"\n   */\n  previewImage: string;\n\n  /**\n   * HLS playlist URL (index.m3u8)\n   * @example \"https://videofeedback01.wbbasket.ru/8defc853-7f62-4d6d-b236-8a16cfb63128/index.m3u8\"\n   */\n  link: string;\n\n  /**\n   * Video duration in seconds\n   */\n  durationSec: number;\n}\n\n/**\n * Customer review object\n */\nexport interface Review {\n  /**\n   * Review ID\n   */\n  id: string;\n\n  /**\n   * Review text content\n   */\n  text: string;\n\n  /**\n   * Product pros/advantages\n   */\n  pros: string;\n\n  /**\n   * Product cons/disadvantages\n   */\n  cons: string;\n\n  /**\n   * Product rating (1-5 stars)\n   */\n  productValuation: number;\n\n  /**\n   * Review creation timestamp (ISO 8601)\n   * @example \"2024-09-26T10:20:48+03:00\"\n   */\n  createdDate: string;\n\n  /**\n   * Seller's response to review (null if not answered)\n   */\n  answer: ReviewAnswer | null;\n\n  /**\n   * Review state/status\n   */\n  state: ReviewState | string;\n\n  /**\n   * Product information\n   */\n  productDetails: ReviewProductDetails;\n\n  /**\n   * Customer photos attached to review\n   */\n  photoLinks: ReviewPhoto[] | null;\n\n  /**\n   * Customer video attached to review (HLS format)\n   */\n  video: ReviewVideo | null;\n\n  /**\n   * Whether seller has viewed the review\n   */\n  wasViewed: boolean;\n\n  /**\n   * Customer name\n   * @example \"Николай\"\n   */\n  userName: string;\n\n  /**\n   * Product size fit feedback:\n   * - ` ` (empty) — for non-sized products\n   * - `ok` — fits as expected\n   * - `smaller` — runs small\n   * - `bigger` — runs large\n   */\n  matchingSize: string;\n\n  /**\n   * Whether seller can file complaint about review\n   */\n  isAbleSupplierFeedbackValuation: boolean;\n\n  /**\n   * Complaint reason key (if filed)\n   * See supplier-valuations endpoint for reason mapping\n   */\n  supplierFeedbackValuation: number;\n\n  /**\n   * Whether seller can report product issue\n   */\n  isAbleSupplierProductValuation: boolean;\n\n  /**\n   * Product issue key (if reported)\n   * See supplier-valuations endpoint for issue mapping\n   */\n  supplierProductValuation: number;\n\n  /**\n   * Whether product return is available\n   */\n  isAbleReturnProductOrders: boolean;\n\n  /**\n   * Product return request timestamp (ISO 8601)\n   */\n  returnProductOrdersDate: string | null;\n\n  /**\n   * Customer tags/labels\n   * @example [\"price\", \"quality\"]\n   */\n  bables: string[] | null;\n\n  /**\n   * Product barcode (shkId)\n   */\n  lastOrderShkId: number;\n\n  /**\n   * Purchase date (ISO 8601)\n   * @example \"2024-08-12T10:20:48+03:00\"\n   */\n  lastOrderCreatedAt: string;\n\n  /**\n   * Product color\n   * @example \"blue\", \"colorless\"\n   */\n  color: string;\n\n  /**\n   * Product category ID\n   */\n  subjectId: number;\n\n  /**\n   * Product category name\n   * @example \"Футболки-поло\"\n   */\n  subjectName: string;\n\n  /**\n   * Parent review ID (null if this is the initial review)\n   */\n  parentFeedbackId: string | null;\n\n  /**\n   * Child review ID (null if this is the updated review)\n   */\n  childFeedbackId: string | null;\n}\n\n/**\n * Response from getReviews() method\n */\nexport interface ReviewsResponse {\n  /**\n   * Reviews data\n   */\n  data: {\n    /**\n     * Count of unanswered/unprocessed reviews\n     */\n    countUnanswered: number;\n\n    /**\n     * Count of answered/processed reviews\n     */\n    countArchive: number;\n\n    /**\n     * Array of customer reviews\n     */\n    feedbacks: Review[];\n  };\n\n  /**\n   * Whether there was an error\n   */\n  error: boolean;\n\n  /**\n   * Error description text\n   */\n  errorText: string;\n\n  /**\n   * Additional errors array\n   */\n  additionalErrors: string[] | null;\n}\n\n/**\n * Request payload for responding to a review\n * Used by both respondToReview() and editReviewResponse() methods\n */\nexport interface RespondToReviewRequest {\n  /**\n   * Review ID\n   */\n  id: string;\n\n  /**\n   * Response text (min 2, max 5000 characters)\n   */\n  text: string;\n}\n","/**\n * Wildberries API TypeScript SDK\n * Main entry point\n *\n * @packageDocumentation\n */\n\nimport { BaseClient } from './client/base-client';\nimport { GeneralModule } from './modules/general';\nimport { ProductsModule } from './modules/products';\nimport { OrdersFBSModule } from './modules/orders-fbs';\nimport { OrdersFBWModule } from './modules/orders-fbw';\nimport { FinancesModule } from './modules/finances';\nimport { AnalyticsModule } from './modules/analytics';\nimport { CommunicationsModule } from './modules/communications';\nimport { ReportsModule } from './modules/reports';\nimport { PromotionModule } from './modules/promotion';\nimport { TariffsModule } from './modules/tariffs';\nimport { InStorePickupModule } from './modules/in-store-pickup';\nimport { AuthenticationError } from './errors/auth-error';\nimport type { SDKConfig } from './config/sdk-config';\n\n/**\n * Main SDK class providing access to all Wildberries API modules.\n *\n * This class serves as the primary entry point for interacting with the Wildberries API.\n * It manages authentication, configuration, and provides access to all API modules through\n * a single unified interface.\n *\n * @example Basic usage\n * ```typescript\n * import { WildberriesSDK } from 'daytona-wildberries-typescript-sdk';\n *\n * const sdk = new WildberriesSDK({\n *   apiKey: process.env.WB_API_KEY!\n * });\n *\n * // Test connectivity\n * const response = await sdk.general.ping();\n * console.log('Status:', response.Status); // 'OK'\n * ```\n *\n * @example Advanced configuration\n * ```typescript\n * const sdk = new WildberriesSDK({\n *   apiKey: process.env.WB_API_KEY!,\n *   timeout: 60000, // 60 seconds for long operations\n *   retryConfig: {\n *     maxRetries: 5,\n *     retryDelay: 2000,\n *     exponentialBackoff: true\n *   },\n *   logLevel: 'debug'\n * });\n * ```\n *\n * @example Error handling\n * ```typescript\n * import { WildberriesSDK, AuthenticationError, RateLimitError } from 'daytona-wildberries-typescript-sdk';\n *\n * try {\n *   const sdk = new WildberriesSDK({ apiKey: '' });\n * } catch (error) {\n *   if (error instanceof AuthenticationError) {\n *     console.error('Invalid API key:', error.message);\n *   }\n * }\n * ```\n */\nexport class WildberriesSDK {\n  /**\n   * Internal HTTP client shared across all modules\n   * @private\n   */\n  private readonly client: BaseClient;\n\n  /**\n   * General API module\n   *\n   * Provides access to general utility endpoints:\n   * - Ping (connectivity testing)\n   * - Server timestamps\n   *\n   * @see {@link GeneralModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * const response = await sdk.general.ping();\n   * console.log('Server time:', response.TS);\n   * ```\n   */\n  public readonly general: GeneralModule;\n\n  /**\n   * Products API module\n   *\n   * Provides access to product management endpoints:\n   * - Product card creation and editing\n   * - Category and characteristic management\n   * - Media (images, videos) upload\n   * - Pricing and stock management\n   *\n   * @see {@link ProductsModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * // Get parent categories\n   * const parents = await sdk.products.getParentAll();\n   *\n   * // Get categories by parent\n   * const categories = await sdk.products.getObjectAll({ parentID: 479 });\n   *\n   * // Get characteristics for a category\n   * const characteristics = await sdk.products.getObjectCharc(105);\n   * ```\n   */\n  public readonly products: ProductsModule;\n\n  /**\n   * Orders FBS (Fulfillment by Seller) API module\n   *\n   * Provides access to FBS order management endpoints:\n   * - New order retrieval\n   * - Order listing with filters and pagination\n   * - Order status tracking (supplier and WB system status)\n   *\n   * @see {@link OrdersFBSModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * // Get new orders awaiting processing\n   * const newOrders = await sdk.ordersFBS.getNewOrders();\n   *\n   * // Get orders from last 7 days\n   * const sevenDaysAgo = Math.floor(Date.now() / 1000) - (7 * 24 * 60 * 60);\n   * const orders = await sdk.ordersFBS.getOrders({ dateFrom: sevenDaysAgo });\n   *\n   * // Check order statuses\n   * const orderIds = orders.orders.map(o => o.id);\n   * const statuses = await sdk.ordersFBS.getOrderStatuses(orderIds);\n   * ```\n   */\n  public readonly ordersFBS: OrdersFBSModule;\n\n  /**\n   * Orders FBW (Fulfillment by Wildberries) API module\n   *\n   * Provides access to FBW warehouse supply and acceptance endpoints:\n   * - Warehouse selection and availability\n   * - Acceptance coefficient checking\n   * - Supply planning and management\n   * - Transit tariff calculation\n   *\n   * @see {@link OrdersFBWModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * // Get available warehouses\n   * const warehouses = await sdk.ordersFBW.getWarehouses();\n   *\n   * // Check acceptance coefficients for next 14 days\n   * const coefficients = await sdk.ordersFBW.getAcceptanceCoefficients();\n   *\n   * // Get acceptance options for goods\n   * const goods = [{ barcode: '1234567891234', quantity: 10 }];\n   * const options = await sdk.ordersFBW.getAcceptanceOptions(goods);\n   *\n   * // Get supply details\n   * const details = await sdk.ordersFBW.getSupplyDetails(12345);\n   * ```\n   */\n  public readonly ordersFBW: OrdersFBWModule;\n\n  /**\n   * Finances API module\n   *\n   * Provides access to financial data endpoints:\n   * - Balance and transaction retrieval\n   * - Financial reports (sales reports by period)\n   * - Document management (categories, list, download)\n   *\n   * @see {@link FinancesModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * // Get current balance\n   * const balance = await sdk.finances.getBalance();\n   * console.log(`Available: ${balance.for_withdraw} ${balance.currency}`);\n   *\n   * // Get transaction history\n   * const transactions = await sdk.finances.getTransactions({\n   *   dateFrom: '2024-01-01',\n   *   dateTo: '2024-01-31',\n   *   period: 'weekly'\n   * });\n   *\n   * // Download documents\n   * const docs = await sdk.finances.getDocuments();\n   * ```\n   */\n  public readonly finances: FinancesModule;\n\n  /**\n   * Analytics API module\n   *\n   * Provides access to analytics and reporting endpoints:\n   * - Sales funnel conversion metrics\n   * - Product performance tracking\n   * - Search query analysis\n   * - Category-level analytics\n   * - CSV report generation\n   *\n   * @see {@link AnalyticsModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * // Get sales funnel metrics\n   * const funnel = await sdk.analytics.getSalesFunnel({\n   *   period: {\n   *     begin: '2024-01-01 00:00:00',\n   *     end: '2024-01-31 23:59:59'\n   *   }\n   * });\n   *\n   * // Track product performance\n   * const performance = await sdk.analytics.getProductPerformance(\n   *   [12345, 67890],\n   *   { from: '2024-01-01', to: '2024-01-31' }\n   * );\n   * ```\n   */\n  public readonly analytics: AnalyticsModule;\n\n  /**\n   * Communications API module\n   *\n   * Provides access to customer communication endpoints:\n   *\n   * **Chat Management:**\n   * - Get all chat conversations\n   * - Poll for new chat events\n   * - Send messages to customers (with file attachments)\n   * - Extract chat metadata (replySign, chatID)\n   *\n   * **Product Q&A Management:**\n   * - Get product questions (answered/unanswered, with filtering)\n   * - Answer or reject customer questions\n   * - Mark questions as viewed\n   *\n   * **Customer Reviews Management:**\n   * - Get customer reviews (answered/unanswered, with filtering)\n   * - View review details (text, photos, videos, ratings)\n   * - Respond to reviews\n   * - Edit review responses\n   *\n   * @see {@link CommunicationsModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * // Chat: Get all chats and send a message\n   * const chats = await sdk.communications.getChats();\n   * const replySign = chats.result[0].replySign;\n   * await sdk.communications.sendMessage(replySign, 'Thank you for your message!');\n   *\n   * // Q&A: Get and answer product questions\n   * const questions = await sdk.communications.getQuestions({\n   *   isAnswered: false,\n   *   take: 10,\n   *   skip: 0,\n   * });\n   * await sdk.communications.answerQuestion(questions.data.questions[0].id, 'This product is made of cotton.');\n   *\n   * // Reviews: Get and respond to customer reviews\n   * const reviews = await sdk.communications.getReviews({\n   *   isAnswered: false,\n   *   take: 10,\n   *   skip: 0,\n   * });\n   * await sdk.communications.respondToReview(reviews.data.feedbacks[0].id, 'Thank you for your feedback!');\n   * ```\n   */\n  public readonly communications: CommunicationsModule;\n\n  /**\n   * Reports API module\n   *\n   * Provides access to reporting and analytics data endpoints:\n   * - Inbound shipments (incomes) with pagination\n   * - Stock levels with quantity breakdown\n   * - Customer orders tracking\n   * - Sales and returns analysis\n   * - Excise/compliance reports\n   * - Async warehouse remains reports\n   *\n   * @see {@link ReportsModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * // Get inbound shipments\n   * const incomes = await sdk.reports.getIncomes('2024-01-01');\n   *\n   * // Get current stock levels\n   * const stocks = await sdk.reports.getStocks('2024-01-01');\n   *\n   * // Generate and download warehouse remains report\n   * const task = await sdk.reports.createWarehouseRemainsReport({ locale: 'ru' });\n   * const status = await sdk.reports.checkReportStatus(task.data.taskId, 'warehouse_remains');\n   * if (status.data.status === 'done') {\n   *   const blob = await sdk.reports.downloadReport(task.data.taskId, 'warehouse_remains');\n   * }\n   * ```\n   */\n  public readonly reports: ReportsModule;\n\n  /**\n   * Promotion API module\n   *\n   * Provides access to promotional campaign endpoints:\n   * - Campaign creation, management, and control\n   * - Campaign count and information retrieval\n   * - Auction (manual bid) campaign management\n   * - Configuration values and minimum bids\n   * - Budget deposits and management\n   * - Product and category selection for campaigns\n   * - Statistics and performance tracking\n   *\n   * @see {@link PromotionModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * // Get campaign count summary\n   * const summary = await sdk.promotion.getPromotionCount();\n   *\n   * // Create a new campaign\n   * const campaignId = await sdk.promotion.createSeacatSaveAd({\n   *   name: 'Winter Sale Campaign',\n   *   nms: [12345, 67890],\n   *   bid_type: 'manual',\n   *   placement_types: ['search', 'recommendations']\n   * });\n   *\n   * // Get minimum bids for products\n   * const minBids = await sdk.promotion.createBidsMin({\n   *   advert_id: campaignId,\n   *   nm_ids: [12345, 67890],\n   *   payment_type: 'cpm',\n   *   placement_types: ['search', 'recommendation']\n   * });\n   * ```\n   */\n  public readonly promotion: PromotionModule;\n\n  /**\n   * Tariffs API module\n   *\n   * Provides access to tariff and commission information:\n   * - Commission rates by category\n   * - Box storage tariffs\n   * - Pallet storage tariffs\n   * - Return handling tariffs\n   *\n   * @see {@link TariffsModule} for available methods\n   *\n   * @example\n   * ```typescript\n   * // Get commission rates for all categories\n   * const commissions = await sdk.tariffs.getTariffsCommission();\n   *\n   * // Get box storage tariffs\n   * const boxTariffs = await sdk.tariffs.getTariffsBox();\n   *\n   * // Get pallet storage tariffs\n   * const palletTariffs = await sdk.tariffs.getTariffsPallet();\n   *\n   * // Get return handling tariffs\n   * const returnTariffs = await sdk.tariffs.getTariffsReturn();\n   * ```\n   */\n  public readonly tariffs: TariffsModule;\n\n  /**\n   * In-Store Pickup API module (Click & Collect)\n   *\n   * Provides comprehensive methods for managing click & collect orders:\n   * - Order assembly lifecycle management (new → confirm → prepare → receive/reject)\n   * - Customer verification at pickup\n   * - Product metadata management (SGTIN, UIN, IMEI, GTIN)\n   * - Order queries and status tracking\n   *\n   * @see {@link InStorePickupModule} for available methods\n   *\n   * @example Order processing workflow\n   * ```typescript\n   * // 1. Get new pickup orders\n   * const newOrders = await sdk.inStorePickup.getNewOrders();\n   * const order = newOrders.orders[0];\n   *\n   * // 2. Confirm and start assembly\n   * await sdk.inStorePickup.confirmOrder(order.id);\n   *\n   * // 3. Complete assembly\n   * await sdk.inStorePickup.prepareOrder(order.id);\n   *\n   * // 4. Customer arrives - verify identity\n   * const verification = await sdk.inStorePickup.verifyCustomerIdentity({\n   *   orderCode: order.orderCode,\n   *   passcode: '1234' // From customer's app\n   * });\n   *\n   * // 5. Complete handover\n   * await sdk.inStorePickup.receiveOrder(order.id);\n   * ```\n   *\n   * @example Metadata management for regulated products\n   * ```typescript\n   * // Set SGTIN codes (Честный знак marking)\n   * await sdk.inStorePickup.setSGTINCode(orderId, ['1234567890123456']);\n   *\n   * // Set IMEI for electronics\n   * await sdk.inStorePickup.setIMEICode(orderId, '123456789012345');\n   *\n   * // Get all metadata\n   * const metadata = await sdk.inStorePickup.getOrderMetadata(orderId);\n   * ```\n   */\n  public readonly inStorePickup: InStorePickupModule;\n\n  /**\n   * Initialize the Wildberries SDK with configuration\n   *\n   * Creates a new SDK instance with the provided configuration.\n   * The SDK uses a single shared HTTP client for all API modules to ensure\n   * consistent authentication, rate limiting, and error handling.\n   *\n   * @param config - SDK configuration options\n   * @throws {AuthenticationError} If API key is missing or invalid\n   *\n   * @example\n   * ```typescript\n   * const sdk = new WildberriesSDK({\n   *   apiKey: process.env.WB_API_KEY!,\n   *   timeout: 30000,\n   *   logLevel: 'info'\n   * });\n   * ```\n   */\n  constructor(config: SDKConfig) {\n    // Validate API key\n    if (!config.apiKey || config.apiKey.trim() === '') {\n      throw new AuthenticationError(\n        'API key is required. Please provide a valid Wildberries API key in the configuration.',\n        401\n      );\n    }\n\n    // Create shared BaseClient instance\n    this.client = new BaseClient(config);\n\n    // Initialize General module (Story 1.9 - implemented)\n    this.general = new GeneralModule(this.client);\n\n    // Initialize Products module (Stories 2.1-2.4 - implemented)\n    this.products = new ProductsModule(this.client);\n\n    // Initialize Orders FBS module (Stories 2.5-2.6 - implemented)\n    this.ordersFBS = new OrdersFBSModule(this.client);\n\n    // Initialize Orders FBW module (Story 2.7 - implemented)\n    this.ordersFBW = new OrdersFBWModule(this.client);\n\n    // Initialize Finances module (Stories 3.1-3.2 - implemented)\n    this.finances = new FinancesModule(this.client);\n\n    // Initialize Analytics module (Stories 3.3-3.4 - implemented)\n    this.analytics = new AnalyticsModule(this.client);\n\n    // Initialize Communications module (Stories 3.5-3.6 - implemented)\n    this.communications = new CommunicationsModule(this.client);\n\n    // Initialize Reports module (Story 3.7 - implemented)\n    this.reports = new ReportsModule(this.client);\n\n    // Initialize Promotion module (Story 4.5 - implemented)\n    this.promotion = new PromotionModule(this.client);\n\n    // Initialize Tariffs module (Story 4.5 - implemented)\n    this.tariffs = new TariffsModule(this.client);\n\n    // Initialize In-Store Pickup module (Story 4.6 - implemented)\n    this.inStorePickup = new InStorePickupModule(this.client);\n  }\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n/**\n * SDK version\n */\nexport const version = '0.1.0';\n\n// Main SDK class\nexport { WildberriesSDK as default };\n\n// Configuration types\nexport type { SDKConfig, RequestOptions } from './config/sdk-config';\nexport {\n  ALL_RATE_LIMITS,\n  generalRateLimits,\n  ordersFBSRateLimits,\n  ordersFBWRateLimits,\n  promotionRateLimits,\n  tariffsRateLimits\n} from './config';\nexport type { RateLimitConfig, EndpointLimits } from './client/rate-limiter';\n\n// Core infrastructure\nexport { BaseClient } from './client/base-client';\n\n// API Modules\nexport { GeneralModule } from './modules/general';\nexport { ProductsModule } from './modules/products';\nexport { OrdersFBSModule } from './modules/orders-fbs';\nexport { OrdersFBWModule } from './modules/orders-fbw';\nexport { FinancesModule } from './modules/finances';\nexport { AnalyticsModule } from './modules/analytics';\nexport { CommunicationsModule } from './modules/communications';\nexport { ReportsModule } from './modules/reports';\nexport { PromotionModule } from './modules/promotion';\nexport { TariffsModule } from './modules/tariffs';\nexport { InStorePickupModule } from './modules/in-store-pickup';\n\n// Type definitions\nexport * from './types/products.types';\nexport * from './types/orders-fbs.types';\nexport * from './types/finances.types';\nexport * from './types/communications.types';\n\n// Reports types exported explicitly to avoid conflicts with finances types\nexport type {\n  IncomesItem,\n  StocksItem,\n  OrdersItem,\n  SalesItem,\n  ExciseReportRequest,\n  ExciseReportDataItem,\n  ExciseReportResponse,\n  WarehouseRemainsParams,\n  ReportTaskResponse,\n  ReportStatus as ReportsReportStatus, // Renamed to avoid conflict with finances\n  ReportType,\n  ResponseErrorStatistics,\n  ResponseErrorStatistics2,\n  ErrorResponse4xx,\n} from './types/reports.types';\n\n// Analytics types exported with explicit names to avoid conflicts\nexport type {\n  // Unique analytics types\n  ConversionMetrics,\n  PeriodStatistics,\n  PeriodComparisonDynamics,\n  ProductTag,\n  ProductObject,\n  CardStatistics,\n  ProductCardAnalytics,\n  ProductStatisticsRequest,\n  ProductStatisticsResponse,\n  TimeSeriesDataPoint,\n  DailyStatistics,\n  HistoricalStatisticsRequest,\n  ProductCardHistory,\n  HistoricalStatisticsResponse,\n  GroupedHistory,\n  GroupedHistoricalResponse,\n  SearchQueryMetrics,\n  SearchQueriesResponse,\n  CategoryPerformanceMetrics,\n  CategoryPerformanceResponse,\n  ProductPerformanceMetrics,\n  ProductPerformanceResponse,\n  // Stock history types (Story 3.4)\n  StockChangeReason,\n  StockHistoryEntry,\n  StockHistoryResponse,\n  // CSV export types (Story 3.4)\n  AnalyticsReportType,\n  CSVFormatOptions,\n  CSVExportRequest,\n  CSVExportResponse,\n  CSVReport,\n  CSVReportStatus,\n  // Shared types with analytics prefix for disambiguation\n  ReportType as AnalyticsReportTypeEnum,\n  Period as AnalyticsPeriod,\n} from './types/analytics.types';\n\n// FBW types exported with namespace to avoid conflicts with FBS\nexport type {\n  ModelsHandySupplyStatus as FBWSupplyStatus,\n  ModelsBox as FBWBox,\n  ModelsGoodInBox as FBWGoodInBox,\n  ModelsSuppliesFiltersRequest as FBWSupplyFilters,\n  ModelsGoodInSupply as FBWGoodInSupply,\n  ModelsDateFilterRequest as FBWDateFilter,\n  ModelsSupplyDetails as FBWSupplyDetails,\n  ModelsSupply as FBWSupply,\n  ModelsAcceptanceCoefficient as FBWAcceptanceCoefficient,\n  ModelsWarehousesResultItems as FBWWarehouse,\n  ModelsGood as FBWGood,\n  ModelsOptionsResultModel as FBWAcceptanceOptions,\n  ModelsTransitTariff as FBWTransitTariff,\n  ModelsVolumeTariff as FBWVolumeTariff,\n  ModelsErrorModel as FBWErrorModel\n} from './types/orders-fbw.types';\n\n// Promotion and Tariffs types\nexport * from './types/promotion.types';\nexport * from './types/tariffs.types';\n\n// In-Store Pickup types (Story 4.6) - Renamed to avoid conflicts with orders-fbs\nexport type {\n  NewOrder as PickupNewOrder,\n  NewOrdersResponse as PickupNewOrdersResponse,\n  Order as PickupOrder,\n  OrdersResponse as PickupOrdersResponse,\n  OrderStatus as PickupOrderStatus,\n  OrderStatusesResponse as PickupOrderStatusesResponse,\n  OrderStatusRequest as PickupOrderStatusRequest,\n  OrderClientInfo as PickupOrderClientInfo,\n  OrderClientInfoResponse as PickupOrderClientInfoResponse,\n  CheckIdentityRequest,\n  CheckedIdentity,\n  OrderMetadata,\n  SGTINRequest,\n  UINRequest,\n  IMEIRequest,\n  GTINRequest,\n  APIError as PickupAPIError,\n  GetOrdersParams as PickupGetOrdersParams,\n} from './types/in-store-pickup.types';\n\n// Error classes\nexport { WBAPIError } from './errors/base-error';\nexport { AuthenticationError } from './errors/auth-error';\nexport { RateLimitError } from './errors/rate-limit-error';\nexport { ValidationError } from './errors/validation-error';\nexport { NetworkError } from './errors/network-error';\nexport {\n  CampaignNotFoundError,\n  InvalidBidError,\n  BudgetExceededError,\n  InvalidCampaignStateError\n} from './errors/promotion-errors';\nexport {\n  PickupOrderNotFoundError,\n  InvalidOrderStateError,\n  CustomerVerificationError,\n  MetadataValidationError\n} from './errors/in-store-pickup-errors';\n"],"names":["bind","fn","thisArg","toString","getPrototypeOf","iterator","toStringTag","kindOf","cache","thing","str","kindOfTest","type","typeOfTest","isArray","isUndefined","isBuffer","val","isFunction","isArrayBuffer","isArrayBufferView","result","isString","isNumber","isObject","isBoolean","isPlainObject","prototype","isEmptyObject","isDate","isFile","isBlob","isFileList","isStream","isFormData","kind","isURLSearchParams","isReadableStream","isRequest","isResponse","isHeaders","trim","forEach","obj","allOwnKeys","i","l","keys","len","key","findKey","_key","_global","isContextDefined","context","merge","caseless","skipUndefined","assignValue","targetKey","extend","a","b","stripBOM","content","inherits","constructor","superConstructor","props","descriptors","toFlatObject","sourceObj","destObj","filter","propFilter","prop","merged","endsWith","searchString","position","lastIndex","toArray","arr","isTypedArray","TypedArray","forEachEntry","_iterator","pair","matchAll","regExp","matches","isHTMLForm","toCamelCase","m","p1","p2","hasOwnProperty","isRegExp","reduceDescriptors","reducer","reducedDescriptors","descriptor","name","ret","freezeMethods","value","toObjectSet","arrayOrString","delimiter","define","noop","toFiniteNumber","defaultValue","isSpecCompliantForm","toJSONObject","stack","visit","source","target","reducedValue","isAsyncFn","isThenable","_setImmediate","setImmediateSupported","postMessageSupported","token","callbacks","data","cb","asap","isIterable","utils$1","AxiosError","message","code","config","request","response","utils","error","customProps","axiosError","msg","errCode","httpAdapter","isVisitable","removeBrackets","renderKey","path","dots","isFlatArray","predicates","toFormData","formData","options","option","metaTokens","visitor","defaultVisitor","indexes","useBlob","convertValue","el","index","exposedHelpers","build","encode","charMap","match","AxiosURLSearchParams","params","encoder","_encode","buildURL","url","serializeFn","serializedParams","hashmarkIndex","InterceptorManager","fulfilled","rejected","id","h","transitionalDefaults","URLSearchParams$1","FormData$1","Blob$1","platform$1","URLSearchParams","FormData","Blob","hasBrowserEnv","_navigator","hasStandardBrowserEnv","hasStandardBrowserWebWorkerEnv","origin","platform","toURLEncodedForm","helpers","parsePropPath","arrayToObject","formDataToJSON","buildPath","isNumericKey","isLast","stringifySafely","rawValue","parser","e","defaults","headers","contentType","hasJSONContentType","isObjectPayload","_FormData","transitional","forcedJSONParsing","JSONRequested","strictJSONParsing","status","method","ignoreDuplicateOf","parseHeaders","rawHeaders","parsed","line","$internals","normalizeHeader","header","normalizeValue","parseTokens","tokens","tokensRE","isValidHeaderName","matchHeaderValue","isHeaderNameFilter","formatHeader","w","char","buildAccessors","accessorName","methodName","arg1","arg2","arg3","AxiosHeaders$1","valueOrRewrite","rewrite","self","setHeader","_value","_header","_rewrite","lHeader","setHeaders","dest","entry","matcher","deleted","deleteHeader","format","normalized","targets","asStrings","first","computed","accessors","defineAccessor","AxiosHeaders","mapped","headerValue","transformData","fns","isCancel","CanceledError","settle","resolve","reject","validateStatus","parseProtocol","speedometer","samplesCount","min","bytes","timestamps","head","tail","firstSampleTS","chunkLength","now","startedAt","bytesCount","passed","throttle","freq","timestamp","threshold","lastArgs","timer","invoke","args","progressEventReducer","listener","isDownloadStream","bytesNotified","_speedometer","loaded","total","progressBytes","rate","inRange","progressEventDecorator","throttled","lengthComputable","asyncDecorator","isURLSameOrigin","isMSIE","cookies","expires","domain","secure","cookie","isAbsoluteURL","combineURLs","baseURL","relativeURL","buildFullPath","requestedURL","allowAbsoluteUrls","isRelativeUrl","headersToObject","mergeConfig","config1","config2","getMergedValue","mergeDeepProperties","valueFromConfig2","defaultToConfig2","mergeDirectKeys","mergeMap","configValue","resolveConfig","newConfig","withXSRFToken","xsrfHeaderName","xsrfCookieName","auth","formHeaders","allowedHeaders","xsrfValue","isXHRAdapterSupported","xhrAdapter","_config","requestData","requestHeaders","responseType","onUploadProgress","onDownloadProgress","onCanceled","uploadThrottled","downloadThrottled","flushUpload","flushDownload","done","onloadend","responseHeaders","err","event","timeoutErrorMessage","cancel","protocol","composeSignals","signals","timeout","length","controller","aborted","onabort","reason","unsubscribe","signal","streamChunk","chunk","chunkSize","pos","end","readBytes","iterable","readStream","stream","reader","trackStream","onProgress","onFinish","_onFinish","loadedBytes","DEFAULT_CHUNK_SIZE","globalFetchAPI","Request","Response","ReadableStream","TextEncoder","test","factory","env","envFetch","isFetchSupported","isRequestSupported","isResponseSupported","isReadableStreamSupported","encodeText","supportsRequestStream","duplexAccessed","hasContentType","supportsResponseStream","resolvers","res","getBodyLength","body","resolveBodyLength","cancelToken","withCredentials","fetchOptions","_fetch","composedSignal","requestContentLength","_request","contentTypeHeader","flush","isCredentialsSupported","resolvedOptions","isStreamResponse","responseContentLength","responseData","seedCache","getFetch","fetch","seeds","seed","map","knownAdapters","fetchAdapter.getFetch","renderReason","isResolvedHandle","adapter","adapters","nameOrAdapter","rejectedReasons","reasons","state","s","throwIfCancellationRequested","dispatchRequest","VERSION","validators","deprecatedWarnings","validator","version","formatMessage","opt","desc","opts","correctSpelling","assertOptions","schema","allowUnknown","Axios$1","instanceConfig","configOrUrl","dummy","paramsSerializer","contextHeaders","requestInterceptorChain","synchronousRequestInterceptors","interceptor","responseInterceptorChain","promise","chain","onFulfilled","onRejected","fullPath","Axios","generateHTTPMethod","isForm","CancelToken$1","CancelToken","executor","resolvePromise","onfulfilled","_resolve","abort","c","spread","callback","isAxiosError","payload","HttpStatusCode","createInstance","defaultConfig","instance","axios","promises","all","Cancel","formToJSON","getAdapter","WBAPIError","statusCode","requestId","captureStackTrace","AuthenticationError","baseMessage","guidance","RateLimitError","retryAfter","ValidationError","fieldErrors","field","NetworkError","isTimeout","cause","CampaignNotFoundError","campaignId","InvalidBidError","bidInfo","info","BudgetExceededError","budgetInfo","InvalidCampaignStateError","currentState","attemptedAction","validStates","stateGuide","transitionGuide","PickupOrderNotFoundError","orderId","InvalidOrderStateError","stateInfo","CustomerVerificationError","orderCode","MetadataValidationError","codeType","_TokenBucket","tokensToAdd","timeToNextToken","RateLimiter","bucket","RetryHandler","operation","operationName","lastError","attempt","delay","jitter","ms","level","meta","logMethod","logData","generalRateLimits","productsRateLimits","ordersFBSRateLimits","ordersFBWRateLimits","ALL_RATE_LIMITS","BaseClient","_a","seconds","levels","currentLevel","sanitized","GeneralModule","client","ProductsModule","subjectId","filters","allCards","maxProducts","cursor","pageCount","baseRequest","cursorData","nmIDs","nmID","card","file","photoNumber","blob","mediaURLs","product","p","updates","nmIDOrIDs","uploadID","officeId","warehouseId","skus","update","OrdersFBSModule","orderIds","supplyId","OrdersFBWModule","warehouseIDs","goods","warehouseID","good","limit","offset","dateFilter","dateRegex","statusID","ID","isPreorderID","FinancesModule","transactionId","dateRange","transaction","t","locale","serviceName","extension","documents","requestBody","reportType","fromDate","toDate","reportId","report","payoutId","AnalyticsModule","productIds","categoryId","cards","totalRevenue","sum","totalUnitsSold","topProducts","productId","validTypes","returns","sales","CommunicationsModule","next","replySign","files","intervalMs","poll","events","totalEvents","intervalId","questionId","answerText","reviewId","responseText","newResponseText","chat","chatID","ReportsModule","dateFrom","flag","dateTo","taskId","endpoint","PromotionModule","TariffsModule","InStorePickupModule","queryParams","sgtins","uin","imei","gtin","promotionRateLimits","tariffsRateLimits","EventType","Sender","QuestionState","ReviewState","ReviewAnswerState","WildberriesSDK"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49]}