UNPKG

@bitrix24/b24jssdk

Version:

Bitrix24 REST API JavaScript SDK

165 lines (162 loc) • 6.77 kB
/** * @package @bitrix24/b24jssdk * @version 3.0.0 * @copyright (c) 2026 Bitrix24 * @license MIT * @see https://github.com/bitrix24/b24jssdk * @see https://bitrix24.github.io/b24jssdk/ */ import { SdkError } from '../../sdk-error.mjs'; import { LoggerFactory } from '../../../logger/logger-factory.mjs'; var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); const READ_COMMAND_KEYS = ["method", "params", "as", "parallel"]; class AbstractInteractionBatch { static { __name(this, "AbstractInteractionBatch"); } parallelDefaultValue; requestId; restrictionManager; logger; // @memo this regeneration -> isObjectMode processingStrategy; _commands = []; constructor(options) { this.parallelDefaultValue = options.parallelDefaultValue; this.requestId = options.requestId; this.restrictionManager = options.restrictionManager; this.processingStrategy = options.processingStrategy; this.logger = options.logger; } // region Setter Strategy //// setProcessingStrategy(processingStrategy) { this.processingStrategy = processingStrategy; } // endregion //// // region Getter //// get size() { return this._commands.length; } get maxSize() { return 0; } // endregion //// // region Request //// addCommands(calls) { if (!this.processingStrategy) { throw new SdkError({ code: "JSSDK_INTERACTION_BATCH_EMPTY_PROCESSING_STRATEGY", description: "ProcessingStrategy not set", status: 500 }); } try { this._warnUnreadCommandKeys(calls); } catch { } this._commands = this.processingStrategy.prepareCommands(calls, { parallelDefaultValue: this.parallelDefaultValue }); } /** * Warns, once per `addCommands`, when a batch command lost its arguments to a * key the parser does not read — a command with no `params`, or one naming * `query`. A key beside a populated `params` is left alone. * * `query` is the reason this exists. On `restApi:v3` the portal's own * reference calls a command's arguments `query`, and so does every `curl` * example; the SDK's key is `params`, and it writes the wire name for you. * Write `query` yourself and the arguments are read by nobody — the command * goes out with an empty `query`, which the portal **accepts**. Measured on * `main.eventlog.list` with `select: ['id']` and `pagination: { limit: 2 }`: * under `params` the portal answered 2 rows of 1 field, the same request * spelled `query` answered 50 rows of 13 fields — the whole default page, with * the `select` and the limit both gone. HTTP 200 either way, no error * anywhere. * * `restApi:v2` loses them just as quietly by a different route: there the * arguments are serialised into the `cmd` querystring from `params`, so the * command goes out as `method?` with nothing after it. Measured on `user.get` * with `filter: { ACTIVE: 'N' }`, against a portal whose only user is active: * under `params` the portal answered 0 rows — the filter worked — and the same * request spelled `query` answered 1 row, the user the filter was meant to * exclude. * * So there is nothing to notice on either version: no error, no empty result, * just an answer to a question nobody asked. * * TypeScript catches a fresh object literal and nothing more — assign it to a * variable first, or build the commands from a config object, a `JSON.parse`, * or plain JavaScript, and the compiler never sees it. Same hole * `_warnMisplacedOptions` was written for (#426), and the same trade: warn * rather than throw, because the call still does something. Through * `forcedLog`, because the default logger is silent and a caller who has not * wired one up is exactly who this is for (#483). * * Once per `addCommands` — i.e. once per batch **request** — not once per * command: 50 commands built from one bad template would otherwise be 50 * identical console lines. The keys are collected across the batch and * reported together, with the positions that carried them. A `batchByChunk` * walk still warns once per chunk, since each chunk is its own request. * * Own enumerable string keys only, so a key on a prototype, a symbol key, or a * non-enumerable one is not seen — and a tuple carrying extra elements is not * checked at all. All are the quiet direction: this exists to catch the * ordinary mistake, not to validate every shape a caller can build. * * `forcedLog` reaches the console only while the app has wired no logger of * its own. One that filters by level may drop this, like every other SDK * warning. */ _warnUnreadCommandKeys(calls) { const unread = /* @__PURE__ */ new Set(); const positions = []; for (const [index, row] of Object.entries(calls)) { if (!row || typeof row !== "object" || Array.isArray(row)) { continue; } const rowUnread = Object.keys(row).filter((key) => !READ_COMMAND_KEYS.includes(key) && void 0 !== row[key]); if (0 === rowUnread.length) { continue; } const params = row.params; const hasParams = null !== params && "object" === typeof params && Object.keys(params).length > 0; const namesTheWireKey = rowUnread.some((key) => "query" === key.toLowerCase()); if (hasParams && !namesTheWireKey) { continue; } rowUnread.forEach((key) => unread.add(key)); positions.push(index); } if (0 === unread.size) { return; } const keys = [...unread]; LoggerFactory.forcedLog( this.logger ?? LoggerFactory.createNullLogger(), "warning", `[b24jssdk] batch command: ${keys.join(", ")} ${1 === keys.length ? "is" : "are"} ignored \u2014 a command's arguments go in \`params\`. Write \`params: { \u2026 }\`. (\`query\` is the portal's own wire spelling on \`restApi:v3\`, which the SDK writes for you; on \`restApi:v2\` the arguments are serialised into the \`cmd\` querystring instead.)`, { code: "JSSDK_BATCH_UNREAD_COMMAND_KEY", unread: keys.join(", "), read: READ_COMMAND_KEYS.join(", "), commands: positions.join(", ") } ).catch(() => { }); } getCommandsForCall() { if (!this.processingStrategy) { throw new SdkError({ code: "JSSDK_INTERACTION_BATCH_EMPTY_PROCESSING_STRATEGY", description: "ProcessingStrategy not set", status: 500 }); } return this.processingStrategy.buildCommands(this._commands); } // endregion //// } export { AbstractInteractionBatch }; //# sourceMappingURL=abstract-interaction-batch.mjs.map