moysklad-ts
Version:
Полностью типизированный, современный и лёгкий клиент МойСклад JSON API
949 lines (917 loc) • 34.4 kB
JavaScript
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