@bitrix24/b24jssdk
Version:
Bitrix24 REST API JavaScript SDK
1,589 lines (1,553 loc) • 188 kB
TypeScript
import { Writable } from 'node:stream';
import { DateTimeOptions, DateTime } from 'luxon';
import { AxiosInstance, AxiosError } from 'axios';
/**
* Log levels in ascending order of severity.
*
* Levels allow filtering messages: when a specific level is set,
* messages of that level and all higher levels will be logged.
*/
declare enum LogLevel {
/**
* Detailed debug information for developers.
* Default level in development environment.
*/
DEBUG = 0,
/**
* Informational messages about normal application operation.
* Used for tracking business logic.
*/
INFO = 1,
/**
* Important but non-critical events.
* Examples: successful request processing, configuration changes.
*/
NOTICE = 2,
/**
* Warnings about potential problems.
* Application continues to run but attention is required.
*/
WARNING = 3,
/**
* Runtime errors requiring intervention.
* Some functionality is unavailable but the application is running.
*/
ERROR = 4,
/**
* Critical errors disrupting component operation.
* Require immediate intervention during working hours.
*/
CRITICAL = 5,
/**
* Serious problems requiring immediate resolution.
* Examples: database unavailable, disk space exhausted.
*/
ALERT = 6,
/**
* System is unusable, requires urgent intervention.
* Highest severity level.
*/
EMERGENCY = 7
}
type LogLevelName = keyof typeof LogLevel;
interface LogRecord {
channel: string;
level: LogLevel;
levelName: LogLevelName;
message: string;
context: Record<string, any>;
extra: Record<string, any>;
timestamp: Date;
}
interface Formatter {
format(record: LogRecord): any;
}
interface HandlerOptions {
bubble?: boolean;
[key: string]: any;
}
interface Handler {
/**
* Handles a log record.
*
* @param {LogRecord} record - Log record to handle.
* @returns {boolean}
*/
handle(record: LogRecord): Promise<boolean>;
isHandling(level: LogLevel): boolean;
shouldBubble(): boolean;
setFormatter(formatter: Formatter): void;
getFormatter(): Formatter | null;
}
type Processor = (record: LogRecord) => LogRecord;
interface LoggerInterface {
/**
* Logs with an arbitrary level.
*/
log(level: LogLevel, message: string, context?: Record<string, any>): Promise<void>;
/**
* Detailed debug information.
*/
debug(message: string, context?: Record<string, any>): Promise<void>;
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*/
info(message: string, context?: Record<string, any>): Promise<void>;
/**
* Normal but significant events.
*/
notice(message: string, context?: Record<string, any>): Promise<void>;
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*/
warning(message: string, context?: Record<string, any>): Promise<void>;
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*/
error(message: string, context?: Record<string, any>): Promise<void>;
/**
* Critical conditions
*
* Example: Application component unavailable, unexpected exception
*/
critical(message: string, context?: Record<string, any>): Promise<void>;
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*/
alert(message: string, context?: Record<string, any>): Promise<void>;
/**
* System is unusable.
*/
emergency(message: string, context?: Record<string, any>): Promise<void>;
}
/**
* Support date format:
* - `YYYY` - Full year (e.g., 2024)
* - `YY` - Two-digit year (e.g., 24)
* - `MMMM` - Full month name (e.g., "January")
* - `MMM` - Abbreviated month name (e.g., "Jan")
* - `MM` - Month with leading zero (01-12)
* - `M` - Month without leading zero (1-12)
* - `DD` - Day of month with leading zero (01-31)
* - `D` - Day of month without leading zero (1-31)
* - `HH` - Hour (24-hour) with leading zero (00-23)
* - `H` - Hour (24-hour) without leading zero (0-23)
* - `hh` - Hour (12-hour) with leading zero (00-11)
* - `h` - Hour (12-hour) without leading zero (0-11)
* - `mm` - Minutes with leading zero (00-59)
* - `m` - Minutes without leading zero (0-59)
* - `ss` - Seconds with leading zero (00-59)
* - `s` - Seconds without leading zero (0-59)
* - `SSS` - Milliseconds (000-999)
* - `a` - AM/PM lowercase (am/pm)
* - `A` - AM/PM uppercase (AM/PM)
* - `ZZZ` - Timezone (e.g., UTC)
* - `ZZ` - Timezone offset (e.g., +03:00)
*/
declare abstract class AbstractFormatter implements Formatter {
protected dateFormat: string;
constructor(dateFormat?: string);
abstract format(record: LogRecord): string;
protected _formatTimestamp(date: Date): string;
protected _formatDate(date: Date): string;
}
/**
* JsonFormatter
*
* @inheritDoc
*/
declare class JsonFormatter extends AbstractFormatter implements Formatter {
constructor(dateFormat?: string);
format(record: LogRecord): string;
}
/**
* LineFormatter
*
* @inheritDoc
*/
declare class LineFormatter extends AbstractFormatter implements Formatter {
protected formatString: string;
constructor(formatString?: string, dateFormat?: string);
format(record: LogRecord): string;
}
/**
* TelegramFormatter
*
* Formats a log entry for sending to Telegram.
* Supports HTML markup with escaped special characters.
*
* @link https://core.telegram.org/bots/api#html-style
*/
declare class TelegramFormatter extends AbstractFormatter implements Formatter {
private useHtml;
private maxMessageLength;
constructor(useHtml?: boolean, dateFormat?: string, maxMessageLength?: number);
format(record: LogRecord): string;
protected _formatBaseMessage(record: LogRecord): string;
protected _formatAdditionalInfo(record: LogRecord): string;
protected _escapeHtml(text: string): string;
protected _escapeMarkdownV2(text: string): string;
/**
* Set the use of HTML markup
*/
setUseHtml(useHtml: boolean): this;
/**
* // Set the maximum message length
*/
setMaxMessageLength(maxLength: number): this;
}
declare const pidProcessor: Processor;
declare const memoryUsageProcessor: Processor;
/**
* Abstract Handler
*/
declare abstract class AbstractHandler implements Handler {
protected level: LogLevel;
protected formatter: Formatter | null;
protected bubble: boolean;
constructor(level?: LogLevel, bubble?: boolean);
isHandling(level: LogLevel): boolean;
shouldBubble(): boolean;
setFormatter(formatter: Formatter): void;
getFormatter(): Formatter | null;
/**
* @inheritDoc
*/
abstract handle(record: LogRecord): Promise<boolean>;
}
interface ConsoleHandlerOptions extends HandlerOptions {
useStyles?: boolean;
}
/**
* Console Handler
*/
declare class ConsoleHandler extends AbstractHandler implements Handler {
protected _styles: Map<LogLevel, string[]>;
protected readonly _useStyles: boolean;
constructor(level?: LogLevel, options?: ConsoleHandlerOptions);
protected _initStyles(): void;
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
protected _getConsoleMethod(level: LogLevel): 'log' | 'info' | 'warn' | 'error' | 'trace';
}
/**
* Console Handler V2
*/
declare class ConsoleV2Handler extends ConsoleHandler implements Handler {
constructor(level?: LogLevel, options?: ConsoleHandlerOptions);
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
}
interface MemoryHandlerOptions extends HandlerOptions {
limit?: number;
}
/**
* Memory Handler
*/
declare class MemoryHandler extends AbstractHandler implements Handler {
private records;
private readonly limit;
constructor(level?: LogLevel, options?: MemoryHandlerOptions);
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
getRecords(): LogRecord[];
clear(): void;
}
interface StreamHandlerOptions extends HandlerOptions {
stream: Writable;
}
/**
* Stream Handler
*
* Node.js stream handler for writing logs to streams.
*/
declare class StreamHandler extends AbstractHandler implements Handler {
/**
* Stream for writing logs.
* @private
*/
private stream;
/**
* Creates a StreamHandler instance.
*
* @param {LogLevel} level - Minimum log level.
* @param options
* - `stream: Writable` - Stream to write to (e.g., `process.stdout`, `process.stderr`, `fs.WriteStream`)
* - `bubble?: boolean` - Determines whether the handler should bubble the record to the next handler.
*/
constructor(level: LogLevel | undefined, options: StreamHandlerOptions);
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
/**
* Closes the stream (if supported).
*
* @returns {Promise<void>}
*/
close(): Promise<void>;
}
interface ConsolaAdapterOptions extends HandlerOptions {
consolaInstance: any;
}
/**
* Adapter for Consola
*
* @memo Consola has its own formatter
* @link https://github.com/unjs/consola
*/
declare class ConsolaAdapter extends AbstractHandler implements Handler {
private consolaInstance;
constructor(level: LogLevel | undefined, options: ConsolaAdapterOptions);
setFormatter(_formatter: Formatter): void;
getFormatter(): Formatter | null;
handle(record: LogRecord): Promise<boolean>;
}
interface WinstonAdapterOptions extends HandlerOptions {
winstonLogger: any;
}
/**
* Adapter for Winston
*
* @memo Winston has its own formatter
* @link https://github.com/winstonjs/winston
*/
declare class WinstonAdapter extends AbstractHandler implements Handler {
private winstonLogger;
constructor(level: LogLevel | undefined, options: WinstonAdapterOptions);
setFormatter(_formatter: Formatter): void;
getFormatter(): Formatter | null;
handle(record: LogRecord): Promise<boolean>;
}
/**
* Define the environment
*/
declare enum Environment {
UNKNOWN = "unknown",
BROWSE = "browser",
NODE = "node"
}
declare function getEnvironment(): Environment;
interface TelegramHandlerOptions extends HandlerOptions {
botToken: string;
chatId: string | number;
parseMode?: 'HTML' | 'Markdown' | 'MarkdownV2';
disableNotification?: boolean;
disableWebPagePreview?: boolean;
useStyles?: boolean;
warnInBrowser?: boolean;
}
/**
* Telegram Handler
*
* Sends logs to Telegram chat.
* The browser displays a warning in the console.
* In Node.js, sends a message via the Telegram Bot API.
*/
declare class TelegramHandler extends AbstractHandler implements Handler {
protected botToken: string;
protected chatId: string | number;
protected parseMode: 'HTML' | 'Markdown' | 'MarkdownV2';
protected disableNotification: boolean;
protected disableWebPagePreview: boolean;
protected readonly environment: Environment;
protected warnInBrowser: boolean;
constructor(level: LogLevel | undefined, options: TelegramHandlerOptions);
/**
* @inheritDoc
*/
handle(record: LogRecord): Promise<boolean>;
/**
* Processing in the browser
*/
protected _handleInBrowser(_message: string, record: LogRecord): Promise<boolean>;
/**
* Processing in Node.js
*/
protected _handleInNode(message: string, _record: LogRecord): Promise<boolean>;
/**
* Fallback processing for unknown environments
*/
protected _handleFallback(message: string): Promise<boolean>;
updateSettings(options: Partial<TelegramHandlerOptions>): this;
/**
* Get current environment
*/
getEnvironment(): Environment;
/**
* Check if the Telegram API is available
*/
testConnection(): Promise<boolean>;
}
declare abstract class AbstractLogger implements LoggerInterface {
/**
* @inheritDoc
*/
abstract log(_level: LogLevel, _message: string, _context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
debug(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
info(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
notice(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
warning(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
error(message: string, context: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
critical(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
alert(message: string, context?: Record<string, any>): Promise<void>;
/**
* @inheritDoc
*/
emergency(message: string, context?: Record<string, any>): Promise<void>;
}
/**
* This Logger can be used to avoid conditional log calls.
*
* Logging should always be optional, and if no logger is provided to your
* library creating a NullLogger instance to have something to throw logs at
* is a good way to avoid littering your code with `if (this.logger) { }`
* blocks.
*/
declare class NullLogger extends AbstractLogger implements LoggerInterface {
static create(): NullLogger;
/**
* @inheritDoc
*/
log(_level: LogLevel, _message: string, _context?: Record<string, any>): Promise<void>;
}
/**
* A logger created according to the principles of `Monolog`
*
* @link https://github.com/Seldaek/monolog
*/
declare class Logger extends AbstractLogger implements LoggerInterface {
private readonly channel;
private handlers;
private processors;
constructor(channel: string);
static create(channel: string): Logger;
pushHandler(handler: Handler): this;
popHandler(): Handler | null;
setHandlers(handlers: Handler[]): this;
pushProcessor(processor: Processor): this;
/**
* @inheritDoc
*/
log(level: LogLevel, message: string, context?: Record<string, any>): Promise<void>;
}
declare class LoggerFactory {
static createNullLogger(): LoggerInterface;
static createForBrowser(channel: string, isDevMode?: boolean): LoggerInterface;
static createForBrowserDevelopment(channel: string, level?: LogLevel): LoggerInterface;
static createForBrowserProduction(channel: string, level?: LogLevel): LoggerInterface;
static forcedLog(logger: LoggerInterface, action: 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical' | 'alert' | 'emergency', message: string, context: Record<string, any>): Promise<void>;
}
/**
* @deprecate This enum is deprecated and will be removed in version `2.0.0`
*/
declare enum LoggerType {
desktop = "desktop",
log = "log",
info = "info",
warn = "warn",
error = "error",
trace = "trace"
}
/**
* LoggerBrowser
*
* @deprecate This class is deprecated and will be removed in version `2.0.0`
* - use {@link Logger `Logger`}
*
* @removed 2.0.0
*/
declare class LoggerBrowser implements LoggerInterface {
#private;
/**
* Create a LoggerBrowser instance
*
* @deprecated This method is deprecated and will be removed in version `2.0.0`
*
* @removed 2.0.0
*/
static build(title: string, isDevelopment?: boolean): LoggerBrowser;
private constructor();
/**
* Set config
*
* @deprecated This method is deprecated and will be removed in version `2.0.0`
*
* @removed 2.0.0
*/
setConfig(_types: Record<string | LoggerType, boolean>): void;
/**
* Set enable
*
* @deprecated This method is deprecated and will be removed in version `2.0.0`
*
* @removed 2.0.0
*/
enable(_type: LoggerType): boolean;
/**
* Set disable
*
* @deprecated This method is deprecated and will be removed in version `2.0.0`
*
* @removed 2.0.0
*/
disable(_type: LoggerType): boolean;
/**
* Test is enable
*
* @deprecated This method is deprecated and will be removed in version `2.0.0`
*
* @removed 2.0.0
*/
isEnabled(_type: LoggerType): boolean;
desktop(...params: any[]): Promise<void>;
log(...params: any[]): Promise<void>;
info(...params: any[]): Promise<void>;
warn(...params: any[]): Promise<void>;
error(...params: any[]): Promise<void>;
trace(...params: any[]): Promise<void>;
debug(...params: any[]): Promise<void>;
notice(...params: any[]): Promise<void>;
warning(...params: any[]): Promise<void>;
critical(...params: any[]): Promise<void>;
alert(...params: any[]): Promise<void>;
emergency(...params: any[]): Promise<void>;
}
/**
* String which is actually a number, like `'20.23'`
*/
type NumberString = string;
/**
* Like `'2018-06-07T03:00:00+03:00'`
*/
type ISODate = string;
type BoolString = 'Y' | 'N';
type GenderString = 'M' | 'F' | '';
type PlacementViewMode = 'view' | 'edit';
type TextType = 'text' | 'html';
type Fields = {
readonly [key: string]: {
readonly type: string;
readonly isRequired: boolean;
readonly isReadOnly: boolean;
readonly isImmutable: boolean;
readonly isMultiple: boolean;
readonly isDynamic: boolean;
readonly title: string;
readonly upperName?: string;
};
};
type MultiField = {
readonly ID: NumberString;
readonly VALUE_TYPE: string;
readonly VALUE: string;
readonly TYPE_ID: string;
};
type MultiFieldArray = ReadonlyArray<Pick<MultiField, 'VALUE' | 'VALUE_TYPE'>>;
/**
* Describes the inline settings in UF
*/
type UserFieldType = {
USER_TYPE_ID: string;
HANDLER: string;
TITLE: string;
DESCRIPTION: string;
OPTIONS?: {
height: number;
};
};
/**
* Data types
* @link https://apidocs.bitrix24.ru/api-reference/data-types.html
* @link https://dev.1c-bitrix.ru/rest_help/crm/dynamic/methodscrmitem/crm_item_fields.php
*/
declare enum DataType {
undefined = "undefined",
any = "any",
integer = "integer",
boolean = "boolean",
double = "double",
date = "date",
datetime = "datetime",
string = "string",
text = "text",
file = "file",
array = "array",
object = "object",
user = "user",
location = "location",
crmCategory = "crm_category",
crmStatus = "crm_status",
crmCurrency = "crm_currency"
}
interface BlobLike {
readonly size: number;
readonly type: string;
slice(start?: number, end?: number, contentType?: string): Blob;
}
interface FileLike extends BlobLike {
name: string;
lastModified?: number;
lastModifiedDate?: object;
}
/**
* The `Type` class is designed to check and determine data types
*
* @see bitrix/js/main/core/src/lib/type.js
*/
declare class TypeManager {
getTag(value: any): string;
/**
* Checks that value is string
* @param value
* @return {boolean}
*
* @memo get from pull.client.Utils
*/
isString(value: any): value is string;
/**
* Returns true if a value is not an empty string
* @param value
* @returns {boolean} Returns true if a value is not an empty string
*/
isStringFilled(value: any): value is string;
/**
* Checks that value is function
* @param value
* @return {boolean}
*
* @memo get from pull.client.Utils
*/
isFunction(value: any): value is Function;
/**
* Checks that value is an object
* @param value
* @return {boolean}
*/
isObject(value: any): value is object | Function;
/**
* Checks that value is object like
* @param value
* @return {boolean}
*/
isObjectLike<T>(value: any): value is T;
/**
* Checks that value is plain object
* @param value
* @return {boolean}
*/
isPlainObject(value: any): value is Record<string | number, any>;
isJsonRpcRequest(value: any): boolean;
isJsonRpcResponse(value: any): boolean;
/**
* Checks that value is boolean
* @param value
* @return {boolean}
*/
isBoolean(value: any): value is boolean;
/**
* Checks that value is number
* @param value
* @return {boolean}
*/
isNumber(value: any): value is number;
/**
* Checks that value is integer
* @param value
* @return {boolean}
*/
isInteger(value: any): value is number;
/**
* Checks that value is float
* @param value
* @return {boolean}
*/
isFloat(value: any): value is number;
/**
* Checks that value is nil
* @param value
* @return {boolean}
*/
isNil(value: any): value is null | undefined;
/**
* Checks that value is an array
* @param value
* @return {boolean}
*/
isArray(value: any): value is any[];
/**
* Returns true if a value is an array, and it has at least one element
* @param value
* @returns {boolean} Returns true if a value is an array, and it has at least one element
*/
isArrayFilled(value: any): value is any[];
/**
* Checks that value is array like
* @param value
* @return {boolean}
*/
isArrayLike(value: any): value is ArrayLike<any>;
/**
* Checks that value is Date
* @param value
* @return {boolean}
*/
isDate(value: any): value is Date;
/**
* Checks that is a DOM node
* @param value
* @return {boolean}
*/
isDomNode(value: any): value is Node;
/**
* Checks that value is element node
* @param value
* @return {boolean}
*/
isElementNode(value: any): value is HTMLElement;
/**
* Checks that value is a text node
* @param value
* @return {boolean}
*/
isTextNode(value: any): value is Text;
/**
* Checks that value is Map
* @param value
* @return {boolean}
*/
isMap(value: any): value is Map<unknown, unknown>;
/**
* Checks that value is Set
* @param value
* @return {boolean}
*/
isSet(value: any): value is Set<unknown>;
/**
* Checks that value is WeakMap
* @param value
* @return {boolean}
*/
isWeakMap(value: any): value is WeakMap<object, unknown>;
/**
* Checks that value is WeakSet
* @param value
* @return {boolean}
*/
isWeakSet(value: any): value is WeakSet<object>;
/**
* Checks that value is prototype
* @param value
* @return {boolean}
*/
isPrototype(value: any): value is object;
/**
* Checks that value is regexp
* @param value
* @return {boolean}
*/
isRegExp(value: any): value is RegExp;
/**
* Checks that value is null
* @param value
* @return {boolean}
*/
isNull(value: any): value is null;
/**
* Checks that value is undefined
* @param value
* @return {boolean}
*/
isUndefined(value: any): value is undefined;
/**
* Checks that value is ArrayBuffer
* @param value
* @return {boolean}
*/
isArrayBuffer(value: any): value is ArrayBuffer;
/**
* Checks that value is typed array
* @param value
* @return {boolean}
*/
isTypedArray(value: any): value is Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
/**
* Checks that value is Blob
* @param value
* @return {boolean}
*/
isBlob(value: any): value is BlobLike;
/**
* Checks that value is File
* @param value
* @return {boolean}
*/
isFile(value: any): value is FileLike;
/**
* Checks that value is FormData
* @param value
* @return {boolean}
*/
isFormData(value: any): value is FormData;
clone(obj: any, bCopyObj?: boolean): any;
}
declare const Type: TypeManager;
/**
* @todo add docs
*/
declare function pick<Data extends object, Keys extends keyof Data>(data: Data, keys: Keys[]): Pick<Data, Keys>;
/**
* @todo add docs
*/
declare function omit<Data extends object, Keys extends keyof Data>(data: Data, keys: Keys[]): Omit<Data, Keys>;
/**
* @todo add docs
*/
declare function isArrayOfArray<A>(item: A[] | A[][]): item is A[][];
/**
* @todo add docs
*
* @example
* const result = getEnumValue(EnumBizprocDocumentType, 'CCrmDocumentSmartOrder')
*/
declare function getEnumValue<T extends Record<string, string | number>>(enumObj: T, value: string | number): T[keyof T] | undefined;
/**
* The `Text` class provides a set of utility methods for working with text data.
* It includes functions for encoding and decoding HTML entities, generating random strings,
* converting values to different data types, and changing the case and format of strings
*
* @see bitrix/js/main/core/src/lib/text.js
*/
declare class TextManager {
getRandom(length?: number): string;
/**
* Generates UUID
*/
getUniqId(): string;
/**
* Generate uuid v7
* @return {string}
*/
getUuidRfc4122(): string;
/**
* Encodes all unsafe entities
* @param {string} value
* @return {string}
*/
encode(value: string): string;
/**
* Decodes all encoded entities
* @param {string} value
* @return {string}
*/
decode(value: string): string;
toNumber(value: any): number;
toInteger(value: any): number;
toBoolean(value: any, trueValues?: string[]): boolean;
toCamelCase(str: string): string;
toPascalCase(str: string): string;
toKebabCase(str: string): string;
capitalize(str: string): string;
numberFormat(number: number, decimals?: number, decPoint?: string, thousandsSep?: string): string;
/**
* Convert string to DateTime from ISO 8601 or self template
*
* @param {string} dateString
* @param {string} template
* @param opts
* @returns {DateTime} Convert string to DateTime from ISO 8601 or self template
*
* @link https://moment.github.io/luxon/#/parsing?id=parsing-technical-formats
*/
toDateTime(dateString: string, template?: string, opts?: DateTimeOptions): DateTime;
/**
* Convert Date to Bitrix24 REST API FORMAT Y-m-d\TH:i:sP
* @param date
*/
toB24Format(date: string | DateTime | Date): string;
getDateForLog(): string;
buildQueryString(params: any): string;
}
declare const Text$1: TextManager;
/**
* @see bitrix/js/main/core/src/lib/browser.js
*/
declare class BrowserManager {
isOpera(): boolean;
isIE(): boolean;
isIE6(): boolean;
isIE7(): boolean;
isIE8(): boolean;
isIE9(): boolean;
isIE10(): boolean;
isSafari(): boolean;
isFirefox(): boolean;
isChrome(): boolean;
detectIEVersion(): number;
isIE11(): boolean;
isMac(): boolean;
isWin(): boolean;
isLinux(): boolean;
isAndroid(): boolean;
isIPad(): boolean;
isIPhone(): boolean;
isIOS(): boolean;
isMobile(): boolean;
isRetina(): boolean;
isTouchDevice(): boolean;
isDoctype(target: any): boolean;
isLocalStorageSupported(): boolean;
detectAndroidVersion(): number;
}
declare const Browser: BrowserManager;
/**
* Interface defining the structure and methods of a Result object.
*/
interface IResult<T = any> {
/**
* Indicates whether the operation resulted in success (no errors).
*/
readonly isSuccess: boolean;
/**
* Collection of errors
*/
readonly errors: Map<string, Error>;
/**
* Sets the data associated with the result.
*
* @param data The data to be stored in the result.
* @returns The current Result object for chaining methods.
*/
setData: (data: T) => IResult<T>;
/**
* Retrieves the data associated with the result.
*
* @returns The data stored in the result, if any.
*/
getData: () => T | null | undefined;
/**
* Adds an error message or Error object to the result.
* @param error The error message or Error object to be added.
* @param key Error key. You can leave it blank. Then it will be generated automatically.
* @returns {IResult} The current Result object for chaining methods.
*/
addError: (error: Error | string, key?: string) => IResult;
/**
* Adds multiple errors to the result in a single call.
*
* @param errors An array of errors or strings that will be converted to errors.
* @returns {IResult} The current Result object for chaining methods.
*/
addErrors: (errors: (Error | string)[]) => IResult;
/**
* Retrieves an iterator for the errors collected in the result.
*
* @returns {IterableIterator<Error>} An iterator over the stored Error objects.
*/
getErrors: () => IterableIterator<Error>;
/**
* Retrieves an array of error messages from the collected errors.
*
* @returns {string[]} An array of strings representing the error messages.
*/
getErrorMessages: () => string[];
/**
* Checks for an error in a collection by key
* @param key - Error key
*/
hasError(key: string): boolean;
/**
* Converts the Result object to a string.
*
* @returns {string} Returns a string representation of the result operation
*/
toString: () => string;
}
/**
* A class representing an operation result with success/failure status, data, and errors.
* Similar to \Bitrix\Main\Result from Bitrix Framework.
* @link https://dev.1c-bitrix.ru/api_d7/bitrix/main/result/index.php
*/
declare class Result<T = any> implements IResult<T> {
protected _errors: Map<string, Error>;
protected _data: T | null | undefined;
constructor(data?: T);
get isSuccess(): boolean;
get errors(): Map<string, Error>;
setData(data: T | null | undefined): Result<T>;
getData(): T | null | undefined;
addError(error: Error | string, key?: string): Result<T>;
addErrors(errors: (Error | string)[]): Result<T>;
getErrors(): IterableIterator<Error>;
hasError(key: string): boolean;
/**
* Retrieves an array of error messages from the collected errors.
*
* @returns An array of strings representing the error messages. Each string
* contains the message of a corresponding error object.
*/
getErrorMessages(): string[];
/**
* Converts the Result object to a string.
*
* @returns {string} Returns a string representation of the result operation
*/
toString(): string;
private safeStringify;
private replacer;
static ok<U>(data?: U): Result<U>;
static fail<U>(error: Error | string, key?: string): Result<U>;
}
/**
* Special cases of data passed to handlers
* @todo add docs
*/
interface HandlerAuthParams {
access_token: string;
expires: string;
expires_in: string;
scope: string;
domain: string;
server_endpoint: string;
status: string;
client_endpoint: string;
member_id: string;
user_id: string;
refresh_token: string;
application_token: string;
}
type PayloadOAuthToken = Pick<HandlerAuthParams, 'access_token' | 'refresh_token' | 'expires' | 'expires_in' | 'client_endpoint' | 'server_endpoint' | 'member_id' | 'status' | 'user_id'>;
declare enum LoadDataType {
App = "app",
Profile = "profile",
Currency = "currency",
AppOptions = "appOptions",
UserOptions = "userOptions"
}
type TypeUser = {
readonly isAdmin: boolean;
readonly id: null | number;
readonly lastName: null | string;
readonly name: null | string;
readonly gender: GenderString;
readonly photo: null | string;
readonly TimeZone: null | string;
readonly TimeZoneOffset: null | number;
};
declare const EnumAppStatus: {
readonly Free: "F";
readonly Demo: "D";
readonly Trial: "T";
readonly Paid: "P";
readonly Local: "L";
readonly Subscription: "S";
};
declare const StatusDescriptions: Record<(typeof EnumAppStatus)[keyof typeof EnumAppStatus], string>;
type TypeEnumAppStatus = keyof typeof EnumAppStatus;
/**
* @link https://dev.1c-bitrix.ru/rest_help/general/app_info.php
*/
type TypeApp = {
/**
* Local application identifier on the portal
*/
readonly id: number;
/**
* application code
*/
readonly code: string;
/**
* installed version of the application
*/
readonly version: number;
/**
* application status
*/
readonly status: TypeEnumAppStatus;
/**
* application installed flag
*/
readonly isInstalled: boolean;
};
/**
* @link https://dev.1c-bitrix.ru/rest_help/general/app_info.php
*/
type TypePayment = {
/**
* flag indicating whether the paid period or trial period has expired
*/
readonly isExpired: boolean;
/**
* number of days remaining until the end of the paid period or trial period
*/
readonly days: number;
};
/**
* @link https://dev.1c-bitrix.ru/rest_help/general/app_info.php
*/
type TypeLicense = {
/**
* language code designation
*/
readonly languageId: null | string;
/**
* tariff designation with indication of the region as a prefix
*/
readonly license: null | string;
/**
* internal tariff designation without indication of region
*/
readonly licenseType: null | string;
/**
* past meaning of license
*/
readonly licensePrevious: null | string;
/**
* Tariff designation without specifying the region.
*/
readonly licenseFamily: null | string;
/**
* flag indicating whether it is a box (true) or a cloud (false)
*/
readonly isSelfHosted: boolean;
};
declare const TypeSpecificUrl: {
readonly MainSettings: "MainSettings";
readonly UfList: "UfList";
readonly UfPage: "UfPage";
};
type TypeB24Form = {
readonly app_code: string;
readonly app_status: string;
readonly payment_expired: BoolString;
readonly days: number;
/**
* B24 tariff plan identifier (if cloud)
*/
readonly b24_plan: string;
readonly c_name: string;
readonly c_last_name: string;
readonly hostname: string;
};
type CurrencyFormat = {
decimals: number;
decPoint: string;
formatString: string;
fullName: string;
isHideZero: boolean;
thousandsSep?: string;
thousandsVariant?: 'N' | 'D' | 'C' | 'S' | 'B' | 'OWN' | string;
};
type Currency = {
amount: number;
amountCnt: number;
isBase: boolean;
currencyCode: string;
dateUpdate: DateTime;
decimals: number;
decPoint: string;
formatString: string;
fullName: string;
lid: string;
sort: number;
thousandsSep?: string;
lang: Record<string, CurrencyFormat>;
};
declare enum TypeOption {
NotSet = "notSet",
JsonArray = "jsonArray",
JsonObject = "jsonObject",
FloatVal = "float",
IntegerVal = "integer",
BoolYN = "boolYN",
StringVal = "string"
}
/**
* @todo docs
*/
/**
* Settings for operating limiting
*/
interface OperatingLimitConfig {
/**
* Operating limit time period in milliseconds
* Default: 10 minutes (600_000 ms)
*/
windowMs: number;
/**
* Maximum total execution time (operating) in milliseconds
* Default: 480 seconds (480_000 ms)
* When calculating the operating limit, we will use 5 seconds less
* @see Http.getTimeToFree
*/
limitMs: number;
/**
* Threshold for notifications about heavy queries (%)
*/
heavyPercent: number;
}
/**
* Adaptive pause settings
*/
interface AdaptiveConfig {
/**
* Threshold for heavy queries (%)
* Default: 80% - this means that `operating >= 384`
* Specifies what % of `operatingLimit.limitMs` in `operating` should pause.
*/
thresholdPercent: number;
/**
* Pause multiplier
* Default: 0.01 - 0.002 will result in a 1.2-second pause with increasing load
* If: operating_reset_at > Date.now()
* Then: Pause = (operating_reset_at - Date.now()) * coefficient
* Otherwise: Pause = 7_000
* There's no point in specifying a value close to 1, as this will create unnecessary delays.
* In other words: if coefficient === 1, the pause will last until the blocking is unblocked, and our code hasn't yet reached the limits.
* It's important to understand that the goal of adaptive blocking is to smoothly reduce the 'operating' of heavy queries.
*/
coefficient: number;
/**
* Maximum pause (ms)
* Default: 7_000 ms
* Limits the maximum estimated pause time
*/
maxDelay: number;
/**
* Whether adaptive pause is enabled
* Default: true
*/
enabled: boolean;
}
/**
* Rate limiting settings (Leaky Bucket)
*/
interface RateLimitConfig {
/**
* X - limit before blocking (bucket capacity)
* For standard plans: 50
* For Enterprise: 250
*/
burstLimit: number;
/**
* Y - leak rate (requests per second)
* For standard plans: 2
* For Enterprise: 5
*/
drainRate: number;
/**
* Whether adaptive control is enabled
* Default: true
*/
adaptiveEnabled: boolean;
}
/**
* Parameters for managing all types of restrictions
*/
interface RestrictionParams {
rateLimit?: RateLimitConfig;
operatingLimit?: OperatingLimitConfig;
adaptiveConfig?: AdaptiveConfig;
/**
* Maximum number of retries
* Default: 3
*/
maxRetries?: number;
/**
* Base delay between retries (ms)
* Default: 1_000
*/
retryDelay?: number;
}
/**
* Limiter operation statistics
*/
interface RestrictionManagerStats {
/** Retries */
retries: number;
/** Consecutive errors */
consecutiveErrors: number;
/** Limit hits */
limitHits: number;
/** Current number of tokens */
tokens: number;
/** Adaptive delays */
adaptiveDelays: number;
/** Total time of adaptive delays */
totalAdaptiveDelay: number;
/** Heavy requests */
heavyRequestCount: number;
/** Method statistics in seconds */
operatingStats: {
[method: string]: number;
};
}
interface ILimiter {
getTitle(): string;
setConfig(config: any): Promise<void>;
setLogger(logger: LoggerInterface): void;
getLogger(): LoggerInterface;
canProceed(requestId: string, method: string, params?: any): Promise<boolean>;
waitIfNeeded(requestId: string, method: string, params?: any): Promise<number>;
updateStats(requestId: string, method: string, data: any): Promise<void>;
reset(): Promise<void>;
getStats(): Record<string, any>;
}
/**
* Abstract Class for working with actions
*/
type ActionOptions = {
[key: string]: any;
};
declare abstract class AbstractAction {
protected _b24: TypeB24;
protected _logger: LoggerInterface;
constructor(b24: TypeB24, logger: LoggerInterface);
abstract make(options?: ActionOptions): AsyncGenerator | Promise<unknown>;
}
type ActionCallV2 = ActionOptions & {
method: string;
params?: TypeCallParams;
requestId?: string;
};
/**
* Calls the Bitrix24 REST API method `restApi:v2`
*
* @todo add docs
*/
declare class CallV2 extends AbstractAction {
/**
* Calls the Bitrix24 REST API method.
*
* @template T - The expected data type in the response (default is `unknown`).
*
* @param {ActionCallV2} options - parameters for executing the request.
* - `method: string` - REST API method name (eg: `crm.item.get`)
* - `params?: TypeCallParams` - Parameters for calling the method.
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.
*
* @returns {Promise<AjaxResult<T>>} A promise that resolves to the result of an REST API call.
*
* @example
* import { EnumCrmEntityTypeId } from '@bitrix24/b24jssdk'
*
* interface CrmItem { id: number, name: string, lastName: string }
* const response = await b24.actions.v2.call.make<{ item: CrmItem }>({
* method: 'crm.item.get',
* params: {
* entityTypeId: EnumCrmEntityTypeId.contact,
* id: 123
* },
* requestId: 'item-123'
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
* console.log(response.getData().result.item.name)
*/
make<T = unknown>(options: ActionCallV2): Promise<AjaxResult<T>>;
}
type ActionCallListV2 = ActionOptions & {
method: string;
params?: Omit<TypeCallParams, 'start'>;
idKey?: string;
customKeyForResult?: string;
requestId?: string;
};
/**
* Fast data retrieval without counting the total number of records. `restApi:v2`
*
* @todo add docs
*/
declare class CallListV2 extends AbstractAction {
/**
* Fast data retrieval without counting the total number of records.
*
* @template T - The type of the elements of the returned array (default is `unknown`).
*
* @param {ActionCallListV2} options - parameters for executing the request.
* - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)
* - `params?: Omit<TypeCallParams, 'start'>` - Request parameters, excluding the `start` parameter,
* since the method is designed to obtain all data in one call.
* Note: Use `filter`, `order`, and `select` to control the selection.
* - `idKey?: string` - The name of the field containing the unique identifier of the element.
* Default is 'ID' (uppercase). Alternatively, it can be 'id' (lowercase).
* or another field, depending on the REST API data structure.
* - `customKeyForResult?: string` - A custom key indicating that the response REST API will be
* grouped by this field.
* Example: `items` to group a list of CRM items.
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.
*
* @returns {Promise<Result<T[]>>} A promise that resolves to the result of an REST API call.
*
* @example
* import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk'
*
* interface CrmItem { id: number, title: string }
* const sixMonthAgo = new Date()
* sixMonthAgo.setMonth((new Date()).getMonth() - 6)
* sixMonthAgo.setHours(0, 0, 0)
* const response = await b24.actions.v2.callList.make<CrmItem>({
* method: 'crm.item.list',
* params: {
* entityTypeId: EnumCrmEntityTypeId.company,
* filter: {
* '=%title': 'A%',
* '>=createdTime': Text.toB24Format(sixMonthAgo) // created at least 6 months ago
* },
* select: ['id', 'title']
* },
* idKey: 'id',
* customKeyForResult: 'items',
* requestId: 'list-123'
* })
* if (!response.isSuccess) {
* throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)
* }
* const list = response.getData()
* console.log(`Result: ${list?.length}`) // Number of items received
*/
make<T = unknown>(options: ActionCallListV2): Promise<Result<T[]>>;
}
type ActionFetchListV2 = ActionOptions & {
method: string;
params?: Omit<TypeCallParams, 'start'>;
idKey?: string;
customKeyForResult?: string;
requestId?: string;
};
/**
* Calls a REST API list method and returns an async generator for efficient large data retrieval. `restApi:v2`
*
* @todo add docs
*/
declare class FetchListV2 extends AbstractAction {
/**
* Calls a REST API list method and returns an async generator for efficient large data retrieval.
* Implements the fast algorithm for iterating over large datasets without loading all data into memory at once.
*
* @template T - The type of items in the returned arrays (default is `unknown`).
*
* @param {ActionFetchListV2} options - parameters for executing the request.
* - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)
* - `params?: Omit<TypeCallParams, 'start'>` - Request parameters, excluding the `start` parameter,
* since the method is designed to obtain all data in one call.
* Note: Use `filter`, `order`, and `select` to control the selection.
* - `idKey?: string` - The name of the field containing the unique identifier of the element.
* Default is 'ID' (uppercase). Alternatively, it can be 'id' (lowercase).
* or another field, depending on the REST API data structure.
* - `customKeyForResult?: string` - A custom key indicating that the response REST API will be
* grouped by this field.
* Example: `items` to group a list of CRM items.
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.
*
* @returns {AsyncGenerator<T[]>} An async generator that yields chunks of data as arrays of type `T`.
* Each iteration returns the next page/batch of results until all data is fetched.
*
* @example
* import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk'
*
* interface CrmItem { id: number, title: string }
* const sixMonthAgo = new Date()
* sixMonthAgo.setMonth((new Date()).getMonth() - 6)
* sixMonthAgo.setHours(0, 0, 0)
* const generator = b24.actions.v2.fetchList.make<CrmItem>({
* method: 'crm.item.list',
* params: {
* entityTypeId: EnumCrmEntityTypeId.company,
* filter: {
* '=%title': 'A%',
* '>=createdTime': Text.toB24Format(sixMonthAgo) // created at least 6 months ago
* },
* select: ['id', 'title']
* },
* idKey: 'id',
* customKeyForResult: 'items',
* requestId: 'list-123'
* })
*
* for await (const chunk of generator) {
* // Process chunk (e.g., save to database, analyze, etc.)
* console.log(`Processing ${chunk.length} items`)
* }
*
* @see {@link https://apidocs.bitrix24.com/settings/performance/huge-data.html Bitrix24: Fast algorithm for large data}
*/
make<T = unknown>(options: ActionFetchListV2): AsyncGenerator<T[]>;
}
declare abstract class AbstractBatch extends AbstractAction {
protected _addBatchErrorsIfAny(response: Result<ICallBatchResult<any>>, result: Result): void;
protected _processBatchResponse<T>(response: Result<ICallBatchResult<T>>, calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal, options: IB24BatchOptions): CallBatchResult<T>;
protected _createBatchResultWithAjax<T>(response: Result<ICallBatchResult<T>>, isArrayCall: boolean): CallBatchResult<T>;
protected _createBatchArrayResult<T>(response: Result<ICallBatchResult<T>>): Result<AjaxResult<T>[]>;
protected _createBatchObjectResult<T>(response: Result<ICallBatchResult<T>>): Result<Record<string | number, AjaxResult<T>>>;
protected _createBatchResultSimple<T>(response: Result<ICallBatchResult<T>>, isArrayCall: boolean): CallBatchResult<T>;
protected _extractBatchSimpleData<T>(response: Result<ICallBatchResult<T>>, isArrayCall: boolean): T;
chunkArray<T = unknown>(array: Array<T>, chunkSize?: number): T[][];
}
type ActionBatchV2 = ActionOptions & {
calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal;
options?: IB24BatchOptions;
};
/**
* Executes a batch request to the Bitrix24 REST API with a maximum number of commands of no more than 50. `restApi:v2`
* Allows you to execute multiple requests in a single API call, significantly improving performance.
*
* @todo add docs
*/
declare class BatchV2 extends AbstractBatch {
/**
* Executes a batch request to the Bitrix24 REST API with a maximum number of commands of no more than 50.
* Allows you to execute multiple requests in a single API call, significantly improving performance.
*
* @template T - The data type returned by batch query commands (default is `unknown`)
*
* @param {ActionBatchV2} options - parameters for executing the request.
* - `calls: BatchCommandsArrayUniversal | BatchCommandsObjectUniversal | BatchNamedCommandsUniversal` - Commands to execute in a batch.
* Supports several formats:
* 1. Array of tuples: `[['method1', params1], ['method2', params2], ...]`
* 2. Array of objects: `[{ method: 'method1', params: params1 }, { method: 'method2', params: params2 }, ...]`
* 3. An object with named commands: `{ cmd1: { method: 'method1', params: params1 }, cmd2: ['method2', params2], ...}`
* - `options?: IB24BatchOptions` - Additional options for executing a batch request.
* - `isHaltOnError?: boolean` - Whether to stop execution on the first error (default: true)
* - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging (default: undefined)
* - `returnAjaxResult?: boolean` - Whether to return an AjaxResult object instead of data (default: false)
*
* @returns {Promise<CallBatchResult<T>>} A promise that is resolved by the result of executing a batch request:
* - On success: a