UNPKG

moysklad-ts

Version:

Полностью типизированный, современный и лёгкий клиент МойСклад JSON API

949 lines (917 loc) 34.4 kB
var StockMode = /* @__PURE__ */ ((StockMode2) => { StockMode2["All"] = "all"; StockMode2["PositiveOnly"] = "positiveOnly"; StockMode2["NegativeOnly"] = "negativeOnly"; StockMode2["Empty"] = "empty"; StockMode2["NonEmpty"] = "nonEmpty"; StockMode2["UnderMinimum"] = "underMinimum"; return StockMode2; })(StockMode || {}); var QuantityMode = /* @__PURE__ */ ((QuantityMode2) => { QuantityMode2["All"] = "all"; QuantityMode2["PositiveOnly"] = "positiveOnly"; QuantityMode2["NegativeOnly"] = "negativeOnly"; QuantityMode2["Empty"] = "empty"; QuantityMode2["NonEmpty"] = "nonEmpty"; QuantityMode2["UnderMinimum"] = "underMinimum"; return QuantityMode2; })(QuantityMode || {}); var AssortmentEntityType = /* @__PURE__ */ ((AssortmentEntityType2) => { AssortmentEntityType2["Product"] = "product"; AssortmentEntityType2["Service"] = "service"; AssortmentEntityType2["Bundle"] = "bundle"; AssortmentEntityType2["Variant"] = "variant"; AssortmentEntityType2["Consignment"] = "consignment"; return AssortmentEntityType2; })(AssortmentEntityType || {}); var WelcomeBonusMode = /* @__PURE__ */ ((WelcomeBonusMode2) => { WelcomeBonusMode2["Registration"] = "REGISTRATION"; WelcomeBonusMode2["FirstPurchase"] = "FIRST_PURCHASE"; return WelcomeBonusMode2; })(WelcomeBonusMode || {}); var BonusTransactionCategoryType = /* @__PURE__ */ ((BonusTransactionCategoryType2) => { BonusTransactionCategoryType2["Regular"] = "REGULAR"; BonusTransactionCategoryType2["Welcome"] = "WELCOME"; return BonusTransactionCategoryType2; })(BonusTransactionCategoryType || {}); var BonusTransactionStatus = /* @__PURE__ */ ((BonusTransactionStatus2) => { BonusTransactionStatus2["WaitProcessing"] = "WAIT_PROCESSING"; BonusTransactionStatus2["Completed"] = "COMPLETED"; BonusTransactionStatus2["Canceled"] = "CANCELED"; return BonusTransactionStatus2; })(BonusTransactionStatus || {}); var BonusTransactionType = /* @__PURE__ */ ((BonusTransactionType2) => { BonusTransactionType2["Earning"] = "EARNING"; BonusTransactionType2["Spending"] = "SPENDING"; return BonusTransactionType2; })(BonusTransactionType || {}); var BundlePaymentItemType = /* @__PURE__ */ ((BundlePaymentItemType2) => { BundlePaymentItemType2["Good"] = "GOOD"; BundlePaymentItemType2["ExcisableGood"] = "EXCISABLE_GOOD"; BundlePaymentItemType2["CompoundPaymentItem"] = "COMPOUND_PAYMENT_ITEM"; BundlePaymentItemType2["AnotherPaymentItem"] = "ANOTHER_PAYMENT_ITEM"; return BundlePaymentItemType2; })(BundlePaymentItemType || {}); var CounterpartyCompanyType = /* @__PURE__ */ ((CounterpartyCompanyType2) => { CounterpartyCompanyType2["Legal"] = "legal"; CounterpartyCompanyType2["Entrepreneur"] = "entrepreneur"; CounterpartyCompanyType2["Individual"] = "individual"; return CounterpartyCompanyType2; })(CounterpartyCompanyType || {}); var IndividualCounterpartySex = /* @__PURE__ */ ((IndividualCounterpartySex2) => { IndividualCounterpartySex2["Male"] = "male"; IndividualCounterpartySex2["Female"] = "female"; return IndividualCounterpartySex2; })(IndividualCounterpartySex || {}); var DemandOverheadDistribution = /* @__PURE__ */ ((DemandOverheadDistribution2) => { DemandOverheadDistribution2["Weight"] = "weight"; DemandOverheadDistribution2["Volume"] = "volume"; DemandOverheadDistribution2["Price"] = "price"; return DemandOverheadDistribution2; })(DemandOverheadDistribution || {}); var EnterOverheadDistribution = /* @__PURE__ */ ((EnterOverheadDistribution2) => { EnterOverheadDistribution2["Weight"] = "weight"; EnterOverheadDistribution2["Volume"] = "volume"; EnterOverheadDistribution2["Price"] = "price"; return EnterOverheadDistribution2; })(EnterOverheadDistribution || {}); var OrganizationCompanyType = /* @__PURE__ */ ((OrganizationCompanyType2) => { OrganizationCompanyType2["Legal"] = "legal"; OrganizationCompanyType2["Entrepreneur"] = "entrepreneur"; OrganizationCompanyType2["Individual"] = "individual"; return OrganizationCompanyType2; })(OrganizationCompanyType || {}); var ProcessingPlanCostDistributionType = /* @__PURE__ */ ((ProcessingPlanCostDistributionType2) => { ProcessingPlanCostDistributionType2["ByPrice"] = "BY_PRICE"; ProcessingPlanCostDistributionType2["ByProduction"] = "BY_PRODUCTION"; return ProcessingPlanCostDistributionType2; })(ProcessingPlanCostDistributionType || {}); var ProductPaymentItemType = /* @__PURE__ */ ((ProductPaymentItemType2) => { ProductPaymentItemType2["Good"] = "GOOD"; ProductPaymentItemType2["ExcisableGood"] = "EXCISABLE_GOOD"; ProductPaymentItemType2["CompoundPaymentItem"] = "COMPOUND_PAYMENT_ITEM"; ProductPaymentItemType2["AnotherPaymentItem"] = "ANOTHER_PAYMENT_ITEM"; return ProductPaymentItemType2; })(ProductPaymentItemType || {}); var StockAllCurrentStockType = /* @__PURE__ */ ((StockAllCurrentStockType2) => { StockAllCurrentStockType2["Stock"] = "stock"; StockAllCurrentStockType2["FreeStock"] = "freeStock"; StockAllCurrentStockType2["Quantity"] = "quantity"; StockAllCurrentStockType2["Reserve"] = "reserve"; StockAllCurrentStockType2["InTransit"] = "inTransit"; return StockAllCurrentStockType2; })(StockAllCurrentStockType || {}); var ServicePaymentItemType = /* @__PURE__ */ ((ServicePaymentItemType2) => { ServicePaymentItemType2["Service"] = "SERVICE"; ServicePaymentItemType2["Work"] = "WORK"; ServicePaymentItemType2["ProvidingRid"] = "PROVIDING_RID"; ServicePaymentItemType2["CompoundPaymentItem"] = "COMPOUND_PAYMENT_ITEM"; ServicePaymentItemType2["AnotherPaymentItem"] = "ANOTHER_PAYMENT_ITEM"; return ServicePaymentItemType2; })(ServicePaymentItemType || {}); var SupplyOverheadDistribution = /* @__PURE__ */ ((SupplyOverheadDistribution2) => { SupplyOverheadDistribution2["Weight"] = "weight"; SupplyOverheadDistribution2["Volume"] = "volume"; SupplyOverheadDistribution2["Price"] = "price"; return SupplyOverheadDistribution2; })(SupplyOverheadDistribution || {}); var AttributeType = /* @__PURE__ */ ((AttributeType2) => { AttributeType2["Time"] = "time"; AttributeType2["Link"] = "link"; AttributeType2["String"] = "string"; AttributeType2["Text"] = "text"; AttributeType2["File"] = "file"; AttributeType2["Boolean"] = "boolean"; AttributeType2["Double"] = "double"; AttributeType2["Long"] = "long"; AttributeType2["Contract"] = "contract"; AttributeType2["Counterparty"] = "counterparty"; AttributeType2["Project"] = "project"; AttributeType2["Store"] = "store"; AttributeType2["Employee"] = "employee"; AttributeType2["Product"] = "product"; AttributeType2["CustomEntity"] = "customentity"; return AttributeType2; })(AttributeType || {}); var AuditEventType = /* @__PURE__ */ ((AuditEventType2) => { AuditEventType2["Registration"] = "registration"; AuditEventType2["BulkOperation"] = "bulkoperation"; AuditEventType2["ClosePublication"] = "closepublication"; AuditEventType2["Create"] = "create"; AuditEventType2["Delete"] = "delete"; AuditEventType2["OpenPublication"] = "openpublication"; AuditEventType2["Print"] = "print"; AuditEventType2["PutToArchive"] = "puttoarchive"; AuditEventType2["PutToRecycleBin"] = "puttorecyclebin"; AuditEventType2["ReplaceToken"] = "replacetoken"; AuditEventType2["RestoreFromArchive"] = "restorefromarchive"; AuditEventType2["RestoreFromRecycleBin"] = "restorefromrecyclebin"; AuditEventType2["SendEmailFromEntity"] = "sendemailfromentity"; AuditEventType2["Update"] = "update"; return AuditEventType2; })(AuditEventType || {}); var AuditEventSource = /* @__PURE__ */ ((AuditEventSource2) => { AuditEventSource2["Registration"] = "registration"; AuditEventSource2["ClearRecycleBin"] = "clearrecyclebin"; AuditEventSource2["Combine"] = "combine"; AuditEventSource2["BulkCreate"] = "bulkcreate"; AuditEventSource2["Connectors"] = "connectors"; AuditEventSource2["Copy"] = "copy"; AuditEventSource2["EmailSend"] = "emailsend"; AuditEventSource2["Evotor"] = "evotor"; AuditEventSource2["Export"] = "export"; AuditEventSource2["ExportEdiClient1c"] = "exportediclient1c"; AuditEventSource2["Import"] = "import"; AuditEventSource2["ImportEdiClient1c"] = "importediclient1c"; AuditEventSource2["JsonApi"] = "jsonapi"; AuditEventSource2["LoginLogout"] = "loginlogout"; AuditEventSource2["Phone"] = "phone-1.0"; AuditEventSource2["PosApi"] = "posapi"; AuditEventSource2["RestApi"] = "restapi"; AuditEventSource2["Retail"] = "retail"; AuditEventSource2["Scriptor"] = "scriptor"; return AuditEventSource2; })(AuditEventSource || {}); var AuditObjectType = /* @__PURE__ */ ((AuditObjectType2) => { AuditObjectType2["EntitySettings"] = "ENTITY_SETTINGS"; AuditObjectType2["StateSettings"] = "STATE_SETTINGS"; AuditObjectType2["TemplateSettings"] = "TEMPLATE_SETTINGS"; return AuditObjectType2; })(AuditObjectType || {}); var Entity = /* @__PURE__ */ ((Entity2) => { Entity2["Assortment"] = "assortment"; Entity2["AuditEvent"] = "auditevent"; Entity2["Account"] = "account"; Entity2["Demand"] = "demand"; Entity2["DemandPosition"] = "demandposition"; Entity2["Contract"] = "contract"; Entity2["Project"] = "project"; Entity2["SalesChannel"] = "saleschannel"; Entity2["Country"] = "country"; Entity2["Region"] = "region"; Entity2["FactureOut"] = "factureout"; Entity2["PaymentOut"] = "paymentout"; Entity2["PaymentIn"] = "paymentin"; Entity2["InvoiceOut"] = "invoiceout"; Entity2["Counterparty"] = "counterparty"; Entity2["CustomerOrder"] = "customerorder"; Entity2["CustomerOrderState"] = "customerorderstate"; Entity2["CustomerOrderPosition"] = "customerorderposition"; Entity2["PurchaseReturn"] = "purchasereturn"; Entity2["CommissionReportIn"] = "commissionreportin"; Entity2["RetailShift"] = "retailshift"; Entity2["Product"] = "product"; Entity2["Service"] = "service"; Entity2["Bundle"] = "bundle"; Entity2["BundleComponent"] = "bundlecomponent"; Entity2["Variant"] = "variant"; Entity2["Consignment"] = "consignment"; Entity2["ProcessingPlan"] = "processingplan"; Entity2["ProcessingPlanResult"] = "processingplanresult"; Entity2["ProcessingPlanMaterial"] = "processingplanmaterial"; Entity2["ProcessingPlanFolder"] = "processingplanfolder"; Entity2["ProcessingOrder"] = "processingorder"; Entity2["ProcessingOrderPosition"] = "processingorderposition"; Entity2["NamedFilter"] = "namedfilter"; Entity2["Files"] = "files"; Entity2["ProductFolder"] = "productfolder"; Entity2["AttributeMetadata"] = "attributemetadata"; Entity2["CustomEntityMetadata"] = "customentitymetadata"; Entity2["CustomEntity"] = "customentity"; Entity2["Store"] = "store"; Entity2["Organization"] = "organization"; Entity2["PurchaseOrder"] = "purchaseorder"; Entity2["PurchaseOrderPosition"] = "purchaseorderposition"; Entity2["Supply"] = "supply"; Entity2["Processing"] = "processing"; Entity2["ProcessingPositionResult"] = "processingpositionresult"; Entity2["ProcessingPositionMaterial"] = "processingpositionmaterial"; Entity2["ProductionTaskMaterial"] = "productiontaskmaterial"; Entity2["ProcessingProcess"] = "processingprocess"; Entity2["ProcessingStage"] = "processingstage"; Entity2["ProcessingProcessPosition"] = "processingprocessposition"; Entity2["ProcessingPlanStages"] = "processingplanstages"; Entity2["ProductionTask"] = "productiontask"; Entity2["ProductionRow"] = "productionrow"; Entity2["ProductionTaskResult"] = "productiontaskresult"; Entity2["ProductionStageCompletion"] = "productionstagecompletion"; Entity2["ProductionStage"] = "productionstage"; Entity2["ProductionStageCompletionMaterial"] = "productionstagecompletionmaterial"; Entity2["ProductionStageCompletionResult"] = "productionstagecompletionresult"; Entity2["State"] = "state"; Entity2["PriceType"] = "pricetype"; Entity2["Uom"] = "uom"; Entity2["Currency"] = "currency"; Entity2["BonusTransaction"] = "bonustransaction"; Entity2["BonusProgram"] = "bonusprogram"; Entity2["Employee"] = "employee"; Entity2["Group"] = "group"; Entity2["Image"] = "image"; Entity2["Stock"] = "stock"; Entity2["Enter"] = "enter"; Entity2["SalesReturn"] = "salesreturn"; Entity2["RetailSalesReturn"] = "retailsalesreturn"; Entity2["SalesByVariant"] = "salesbyvariant"; Entity2["Slot"] = "slot"; Entity2["ExpenseItem"] = "expenseitem"; Entity2["InvoicePosition"] = "invoiceposition"; Entity2["EnterPosition"] = "enterposition"; Entity2["SupplyPosition"] = "supplyposition"; Entity2["Inventory"] = "inventory"; Entity2["InventoryPosition"] = "inventoryposition"; Entity2["Loss"] = "loss"; Entity2["MoneyPlotSeries"] = "moneyplotseries"; Entity2["MoneyReport"] = "moneyreport"; Entity2["TurnoverAll"] = "turnover"; Entity2["TurnoverByStore"] = "turnoverbystore"; Entity2["TurnoverByOperation"] = "turnoverbyoperation"; Entity2["StockByStore"] = "stockbystore"; return Entity2; })(Entity || {}); var MediaType = /* @__PURE__ */ ((MediaType2) => { MediaType2["Json"] = "application/json"; return MediaType2; })(MediaType || {}); var TaxSystem = /* @__PURE__ */ ((TaxSystem2) => { TaxSystem2["General"] = "GENERAL_TAX_SYSTEM"; TaxSystem2["SimplifiedIncome"] = "SIMPLIFIED_TAX_SYSTEM_INCOME"; TaxSystem2["SimplifiedIncomeOutcome"] = "SIMPLIFIED_TAX_SYSTEM_INCOME_OUTCOME"; TaxSystem2["UnifiedAgricultural"] = "UNIFIED_AGRICULTURAL_TAX"; TaxSystem2["Presumptive"] = "PRESUMPTIVE_TAX_SYSTEM"; TaxSystem2["PatentBased"] = "PATENT_BASED"; return TaxSystem2; })(TaxSystem || {}); var TrackingType = /* @__PURE__ */ ((TrackingType2) => { TrackingType2["BeerAlcohol"] = "BEER_ALCOHOL"; TrackingType2["Electronics"] = "ELECTRONICS"; TrackingType2["FoodSupplement"] = "FOOD_SUPPLEMENT"; TrackingType2["LpClothes"] = "LP_CLOTHES"; TrackingType2["LpLinens"] = "LP_LINENS"; TrackingType2["MedicalDevices"] = "MEDICAL_DEVICES"; TrackingType2["Milk"] = "MILK"; TrackingType2["Ncp"] = "NCP"; TrackingType2["NotTracked"] = "NOT_TRACKED"; TrackingType2["Otp"] = "OTP"; TrackingType2["Perfumery"] = "PERFUMERY"; TrackingType2["Sanitizer"] = "SANITIZER"; TrackingType2["Shoes"] = "SHOES"; TrackingType2["SoftDrinks"] = "SOFT_DRINKS"; TrackingType2["Tires"] = "TIRES"; TrackingType2["Tobacco"] = "TOBACCO"; TrackingType2["Water"] = "WATER"; return TrackingType2; })(TrackingType || {}); const EntitiesActions = { [Entity.SalesReturn]: "evaluate_cost" }; class MoyskladError extends Error { response; constructor(message, response) { super(message); this.response = response; this.name = this.constructor.name; } } class MoyskladApiError extends MoyskladError { code; moreInfo; constructor(message, response, code, moreInfo) { super(message, response); this.code = code; this.moreInfo = moreInfo; } } const version = "0.1.37"; async function* batchPromises(tasks, concurrencyLimit) { if (tasks.length === 0) { return []; } for (let index = 0; index < tasks.length; index += concurrencyLimit) { const batch = tasks.slice(index, index + concurrencyLimit); const result = await Promise.all(batch.map((task) => task())); yield result; } } const MOSCOW_TIMEZONE_MS = 3 * 60 * 60 * 1e3; function leftPad1(value) { return `0${value}`.slice(-2); } function leftPad2(value) { return `00${value}`.slice(-3); } function composeDateTime(date, shouldIncludeMs = false) { const moscowTime = new Date(+date + MOSCOW_TIMEZONE_MS); return [ moscowTime.getUTCFullYear(), "-", leftPad1(moscowTime.getUTCMonth() + 1), "-", leftPad1(moscowTime.getUTCDate()), " ", leftPad1(moscowTime.getUTCHours()), ":", leftPad1(moscowTime.getUTCMinutes()), ":", leftPad1(moscowTime.getUTCSeconds()), shouldIncludeMs ? `.${leftPad2(moscowTime.getUTCMilliseconds())}` : "" ].join(""); } function extractIdFromMetaHref(href) { return href?.split("/").at(-1)?.split("?")[0]; } function isAssortmentOfType(assortment, entity) { return assortment.meta.type === entity; } const MOYSKLAD_DATE_TIME_REGEX = /^(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?$/; function rightPad2(value) { return `${value}00`.slice(0, 3); } function parseDateTime(dateTime) { const m = MOYSKLAD_DATE_TIME_REGEX.exec(dateTime); if (!m || m.length < 7 || m.length > 8) { throw new Error(`Incorrect DateTime format "${dateTime}"`); } const dateTimeExpression = `${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}${m[7] && Number.parseInt(m[7], 10) !== 0 ? `.${rightPad2(m[7])}` : ""}+03:00`; return new Date(dateTimeExpression); } function isErrorObject(data) { return Boolean( typeof data === "object" && data && "error" in data && typeof data.error === "string" ); } function isErrorsObject(data) { return Boolean( typeof data === "object" && data && "errors" in data && Array.isArray(data.errors) && data.errors.some((error) => isErrorObject(error)) ); } function processErrorsObject({ errors: [error] }, response) { throw new MoyskladApiError(error.error, response, error.code, error.moreInfo); } async function handleError(response) { if (!response.headers.has("Content-Type")) { throw new MoyskladError("Response has no Content-Type header", response); } const contentType = response.headers.get("Content-Type"); const text = await response.clone().text(); if (!contentType?.includes("application/json")) { throw new MoyskladError( `Response Content-Type is not application/json, got ${contentType}. Body: ${text}`, response ); } if (!text || text.length === 0) { throw new MoyskladError("Response body is empty", response); } const data = JSON.parse(text); if (Array.isArray(data) && data.length > 0) { const errorsObject = data.find((error) => isErrorsObject(error)); if (!errorsObject) { throw new MoyskladError( `HTTP ${response.status} ${response.statusText} (${JSON.stringify(data)})`, response ); } processErrorsObject(errorsObject, response); } else if (isErrorsObject(data)) { processErrorsObject(data, response); } throw new MoyskladError( `HTTP ${response.status} ${response.statusText}`, response ); } class ApiClient { baseUrl; userAgent; auth; batchGetOptions; constructor(options) { this.baseUrl = options.baseUrl ?? "https://api.moysklad.ru/api/remap/1.2"; this.userAgent = options.userAgent ?? `moysklad-ts/${version} (+https://github.com/MonsterDeveloper/moysklad-ts)`; this.auth = options.auth; this.batchGetOptions = { limit: 1e3, expandLimit: 100, concurrencyLimit: 3, ...options.batchGetOptions }; } /** * Сделать запрос к API МойСклад. * * @param endpoint - относительный путь до ресурса * @param options - опции запроса * * @example * ```ts * const response = await apiClient.request("/entity/counterparty", { method: "POST", body: { name: "ООО Ромашка" } }); * ``` */ async request(endpoint, { searchParameters, ...options } = {}) { const url = this.buildUrl(endpoint); const response = await fetch( url.toString() + (searchParameters && searchParameters.size > 0 ? `?${searchParameters.toString()}` : ""), { ...options, body: options.body ? JSON.stringify(options.body) : void 0, headers: { ...options.headers, Authorization: "token" in this.auth ? `Bearer ${this.auth.token}` : `Basic ${btoa(`${this.auth.login}:${this.auth.password}`)}`, "User-Agent": this.userAgent, "Content-Type": "application/json", Accept: "application/json;charset=utf-8", "Accept-Encoding": "gzip" } } ); if (!response.ok) { await handleError(response); } return response; } /** * Shorthand для GET запроса. * * {@linkcode request} * */ get(url, options = {}) { return this.request(url, { ...options, method: "GET" }); } /** * Shorthand для POST запроса. * * {@linkcode request} */ post(url, options = {}) { return this.request(url, { ...options, method: "POST" }); } /** * Shorthand для PUT запроса. * * {@linkcode request} */ put(url, options = {}) { return this.request(url, { ...options, method: "PUT" }); } /** * Shorthand для DELETE запроса. * * {@linkcode request} */ delete(url, options = {}) { return this.request(url, { ...options, method: "DELETE" }); } /** * Нормализует URL, удаляя лишние слеши. * * @param url - URL * * @returns Нормализованный URL */ normalizeUrl(url) { return url.replaceAll(/\/{2,}/g, "/"); } /** * Строит объект типа `URL` из строки. * * @param url - URL * * @returns Объект типа `URL` */ buildStringUrl(url) { const shouldIncludeBaseUrl = !url.startsWith("http"); const returnUrl = shouldIncludeBaseUrl ? `${this.baseUrl}/${url}` : url; return new URL(this.normalizeUrl(returnUrl)); } /** * Cтроит объект типа `URL` из массива строк. * * @param url - массив строк URL * * @returns Объект типа `URL` */ buildArrayUrl(url) { const shouldIncludeBaseUrl = !url[0]?.startsWith("http"); const returnUrl = shouldIncludeBaseUrl ? `${this.baseUrl}/${url.join("/")}` : url.join("/"); return new URL(this.normalizeUrl(returnUrl)); } /** * Строит URL из строки или массива строк. * * @param url - строка или массив строк URL * * @returns Объект типа `URL` с нормализованным URL и базовым адресом, указанным в опциях инциализации * * @example С массивом строк * ```ts * buildUrl(["entity", "counterparty", "5427bc76-b95f-11eb-0a80-04bb000cd583"]) * // "https://api.moysklad.ru/api/remap/1.2/entity/counterparty/5427bc76-b95f-11eb-0a80-04bb000cd583" * ``` * * @example Со строкой * ```ts * buildUrl("entity/counterparty/5427bc76-b95f-11eb-0a80-04bb000cd583") * // "https://api.moysklad.ru/api/remap/1.2/entity/counterparty/5427bc76-b95f-11eb-0a80-04bb000cd583" * ``` */ buildUrl(url) { if (typeof url === "string") { return this.buildStringUrl(url); } return this.buildArrayUrl(url); } /** * Получить все сущности из API. Но лучше используйте метод `.all()` в эндпоинтах (например, `moysklad.counterparty.all()`). * * @param fetcher - функция, которая делает запрос к API и возвращает список сущностей * @param hasExpand - флаг, указывающий на наличие expand в запросе * * @returns Объект с массивом сущностей и контекстом */ async batchGet(fetcher, hasExpand) { const rows = []; const limit = hasExpand ? this.batchGetOptions.expandLimit : this.batchGetOptions.limit; const data = await fetcher(limit, 0); const size = data.meta.size; const context = data.context; rows.push(...data.rows); const tasks = []; for (let offset = limit; offset < size; offset += limit) { tasks.push(() => fetcher(limit, offset).then(({ rows: rows2 }) => rows2)); } const generator = batchPromises( tasks, this.batchGetOptions.concurrencyLimit ); for await (const promisesValues of generator) { rows.push(...promisesValues.flat()); } return { context, rows }; } } function traverseExpand(expand, depth = 0) { if (depth > 2) { throw new Error("Expand depth cannot be more than 3"); } const fields = []; for (const [key, value] of Object.entries(expand)) { if (!value) { continue; } if (typeof value === "object" && Object.keys(value).length > 0) { const subFields = traverseExpand( value, depth + 1 ); for (const subField of subFields) { fields.push(`${key}.${subField}`); } continue; } fields.push(key); } return fields; } function traverseOrder(order) { const fields = []; if (typeof order === "string") { fields.push(order); } else if (Array.isArray(order)) { for (const orderOption of order) { if (typeof orderOption === "string") { fields.push(orderOption); } else { fields.push(`${orderOption.field},${orderOption.direction}`); } } } else { fields.push(`${order.field},${order.direction}`); } return fields; } function traverseFilter(field, filter) { const filters = []; if (filter === void 0) { return filters; } if (typeof filter === "string" || typeof filter === "number" || typeof filter === "boolean") { filters.push(`${field}=${filter}`); return filters; } if (Array.isArray(filter)) { filters.push(...filter.map((v) => `${field}=${v}`)); return filters; } for (const [operator, condition] of Object.entries(filter)) { if (operator === "eq" || operator === "ne") { if (Array.isArray(condition)) { filters.push( ...condition.map( (v) => `${field}${operator === "eq" ? "=" : "!="}${v}` ) ); continue; } filters.push(`${field}${operator === "eq" ? "=" : "!="}${condition}`); continue; } if (operator === "isNull") { filters.push(`${field}${condition ? "" : "!"}=`); continue; } if (operator === "isNotNull") { filters.push(`${field}${condition ? "!" : ""}=`); continue; } if (operator === "gt") { filters.push(`${field}>${condition}`); continue; } if (operator === "gte") { filters.push(`${field}>=${condition}`); continue; } if (operator === "lt") { filters.push(`${field}<${condition}`); continue; } if (operator === "lte") { filters.push(`${field}<=${condition}`); continue; } if (operator === "like") { filters.push(`${field}~${condition}`); continue; } if (operator === "sw") { filters.push(`${field}~=${condition}`); continue; } if (operator === "ew") { filters.push(`${field}=~${condition}`); } } return filters; } function composeSearchParameters({ pagination, expand, order, search, filter, namedfilter, ...options }) { const searchParameters = new URLSearchParams(); const expandFields = expand && traverseExpand(expand); if (namedfilter) { searchParameters.append("namedfilter", namedfilter); } if (typeof pagination?.limit === "number") { searchParameters.append("limit", pagination.limit.toString()); } else if (expandFields && expandFields.length > 0) { searchParameters.append("limit", "100"); } if (typeof pagination?.offset === "number") { searchParameters.append("offset", pagination.offset.toString()); } if (expandFields && expandFields.length > 0) { searchParameters.append("expand", expandFields.join(",")); } if (order) { const orderFields = traverseOrder(order); if (orderFields.length > 0) { searchParameters.append("order", orderFields.join(";")); } } if (search) { searchParameters.append("search", search); } if (filter) { const filters = []; for (const [field, value] of Object.entries(filter)) { filters.push(...traverseFilter(field, value)); } if (filters.length > 0) { searchParameters.append("filter", filters.join(";")); } } for (const [field, value] of Object.entries(options)) { searchParameters.append(field, String(value)); } return searchParameters.size > 0 ? searchParameters : void 0; } const createProxy = (client, callback, path) => { const proxy = new Proxy(() => { }, { get(_object, key) { if (key === "client" && path.length === 0) { return client; } if (typeof key !== "string" || key === "then") { return; } return createProxy(client, callback, [...path, key]); }, apply(_1, _2, arguments_) { return callback({ path, args: arguments_ }); } }); return proxy; }; const createMoysklad = (options) => { const client = new ApiClient(options); const list = (path, options2) => { const searchParameters = composeSearchParameters(options2 ?? {}); return client.get(path, { searchParameters }).then((response) => response.json()); }; return createProxy( client, // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: todo (callbackOptions) => { const parts = [...callbackOptions.path]; let method; let path; if (parts[0] === "report" || parts[0] === "wizard") { path = `/${parts.join("/").toLowerCase()}`; } else { method = parts.pop(); path = `/entity/${parts.join("/").toLowerCase()}`; } if (parts[0] === "wizard") { const { action, ...body } = callbackOptions.args[0]; return client.post(path, { searchParameters: new URLSearchParams({ action }), body }).then((response) => response.json()); } if (parts[0] === "report") { const options2 = callbackOptions.args[0]; if (path === "/report/stock/allcurrent") { path = "/report/stock/all/current"; } return client.get(path, { searchParameters: composeSearchParameters(options2 ?? {}) }).then((response) => response.json()); } if (method === "list") { return list( path, callbackOptions.args[0] ); } if (method === "all") { return client.batchGet( async (limit, offset) => list(path, { ...callbackOptions.args[0], pagination: { limit, offset } }), Boolean( callbackOptions.args[0]?.expand ) ); } if (method === "first") { return list(path, { ...callbackOptions.args[0], pagination: { limit: 1 } }); } if (method === "size") { return list(path, { ...callbackOptions.args[0], pagination: { limit: 0 } }); } if (method === "get") { const id = callbackOptions.args[0]; const options2 = callbackOptions.args[1]; return client.get(`${path}/${id}`, { searchParameters: composeSearchParameters(options2 ?? {}) }).then((response) => response.json()); } if (method === "delete") { const id = callbackOptions.args[0]; return client.delete(`${path}/${id}`).then((response) => response.json()); } if (method === "batchDelete") { const ids = callbackOptions.args[0]; const entity = callbackOptions.path[0].toLowerCase(); return client.post(`${path}/delete`, { body: ids.map((id) => ({ meta: { href: client.buildUrl(`${path}/${id}`), type: entity, mediaType: MediaType.Json } })) }).then((response) => response.json()); } if (method === "trash") { const id = callbackOptions.args[0]; return client.post(`${path}/${id}/trash`).then((response) => response.json()); } if (method === "upsert" || method === "create") { const data = callbackOptions.args[0]; const options2 = callbackOptions.args[1]; return client.post(path, { body: data, searchParameters: composeSearchParameters(options2 ?? {}) }).then((response) => response.json()); } if (method === "update") { const id = callbackOptions.args[0]; const data = callbackOptions.args[1]; const options2 = callbackOptions.args[2]; return client.put(`${path}/${id}`, { body: data, searchParameters: composeSearchParameters(options2 ?? {}) }).then((response) => response.json()); } if (method === "template") { const data = callbackOptions.args[0]; return client.put(`${path}/new`, { body: data }).then((response) => response.json()); } if (method === "listAccounts") { const id = callbackOptions.args[0]; const options2 = callbackOptions.args[1]; return client.get(`${path}/${id}/accounts`, { searchParameters: composeSearchParameters(options2 ?? {}) }).then((response) => response.json()); } if (method === "updateAccounts") { const id = callbackOptions.args[0]; const data = callbackOptions.args[1]; return client.post(`${path}/${id}/accounts`, { body: data }).then((response) => response.json()); } if (method === "audit") { const id = callbackOptions.args[0]; const options2 = callbackOptions.args[1]; return client.get(`${path}/${id}/audit`, { searchParameters: composeSearchParameters(options2 ?? {}) }).then((response) => response.json()); } if (method === "metadata") { return client.get(`${path}/metadata`).then((response) => response.json()); } throw new Error(`Invalid request path: ${callbackOptions.path.join("/")}`); }, [] ); }; export { AssortmentEntityType, AttributeType, AuditEventSource, AuditEventType, AuditObjectType, BonusTransactionCategoryType, BonusTransactionStatus, BonusTransactionType, BundlePaymentItemType, CounterpartyCompanyType, DemandOverheadDistribution, EnterOverheadDistribution, EntitiesActions, Entity, IndividualCounterpartySex, MediaType, MoyskladApiError, MoyskladError, OrganizationCompanyType, ProcessingPlanCostDistributionType, ProductPaymentItemType, QuantityMode, ServicePaymentItemType, StockAllCurrentStockType, StockMode, SupplyOverheadDistribution, TaxSystem, TrackingType, WelcomeBonusMode, composeDateTime, createMoysklad, extractIdFromMetaHref, isAssortmentOfType, parseDateTime }; //# sourceMappingURL=index.js.map