UNPKG

hyperformula-dc

Version:

HyperFormula is a JavaScript engine for efficient processing of spreadsheet-like data and formulas

1,451 lines (1,311 loc) 175 kB
"use strict"; require("core-js/modules/es.array.slice.js"); require("core-js/modules/es.function.name.js"); require("core-js/modules/es.symbol.js"); require("core-js/modules/es.symbol.description.js"); require("core-js/modules/es.symbol.iterator.js"); exports.__esModule = true; exports.HyperFormula = void 0; require("core-js/modules/es.array.concat.js"); require("core-js/modules/es.array.map.js"); require("core-js/modules/es.array.from.js"); require("core-js/modules/es.string.iterator.js"); require("core-js/modules/es.array.iterator.js"); require("core-js/modules/es.object.to-string.js"); require("core-js/modules/web.dom-collections.iterator.js"); require("core-js/modules/es.map.js"); var _AbsoluteCellRange = require("./AbsoluteCellRange"); var _ArgumentSanitization = require("./ArgumentSanitization"); var _BuildEngineFactory = require("./BuildEngineFactory"); var _Cell = require("./Cell"); var _CellContentParser = require("./CellContentParser"); var _DateTimeHelper = require("./DateTimeHelper"); var _Destroy = require("./Destroy"); var _Emitter = require("./Emitter"); var _errors = require("./errors"); var _i18n = require("./i18n"); var _FunctionRegistry = require("./interpreter/FunctionRegistry"); var _Operations = require("./Operations"); var _parser2 = require("./parser"); function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * This is a class for creating HyperFormula instance, all the following public methods * ale related to this class. * * The instance can be created only by calling one of the static methods * `buildFromArray`, `buildFromSheets` or `buildEmpty` and should be disposed of with the * `destroy` method when it's no longer needed to free the resources. * * The instance can be seen as a workbook where worksheets can be created and * manipulated. They are organized within a widely know structure of columns and rows * which can be manipulated as well. The smallest possible data unit are the cells, which * may contain simple values or formulas to be calculated. * * All CRUD methods are called directly on HyperFormula instance and will trigger * corresponding lifecycle events. The events are marked accordingly, as well as thrown * errors so they can be correctly handled. */ var HyperFormula = /*#__PURE__*/function () { function HyperFormula(_config, _stats, _dependencyGraph, _columnSearch, _parser, _unparser, _cellContentParser, _evaluator, _lazilyTransformingAstService, _crudOperations, _exporter, _namedExpressions, _serialization, _functionRegistry) { _classCallCheck(this, HyperFormula); this._config = _config; this._stats = _stats; this._dependencyGraph = _dependencyGraph; this._columnSearch = _columnSearch; this._parser = _parser; this._unparser = _unparser; this._cellContentParser = _cellContentParser; this._evaluator = _evaluator; this._lazilyTransformingAstService = _lazilyTransformingAstService; this._crudOperations = _crudOperations; this._exporter = _exporter; this._namedExpressions = _namedExpressions; this._serialization = _serialization; this._functionRegistry = _functionRegistry; this._emitter = new _Emitter.Emitter(); this._evaluationSuspended = false; } /** * Calls the `graph` method on the dependency graph. * Allows to execute `graph` directly without a need to refer to `dependencyGraph`. * * @internal */ _createClass(HyperFormula, [{ key: "graph", get: function get() { return this.dependencyGraph.graph; } /** * Calls the `rangeMapping` method on the dependency graph. * Allows to execute `rangeMapping` directly without a need to refer to `dependencyGraph`. * * @internal */ }, { key: "rangeMapping", get: function get() { return this.dependencyGraph.rangeMapping; } /** * Calls the `arrayMapping` method on the dependency graph. * Allows to execute `arrayMapping` directly without a need to refer to `dependencyGraph`. * * @internal */ }, { key: "arrayMapping", get: function get() { return this.dependencyGraph.arrayMapping; } /** * Calls the `sheetMapping` method on the dependency graph. * Allows to execute `sheetMapping` directly without a need to refer to `dependencyGraph`. * * @internal */ }, { key: "sheetMapping", get: function get() { return this.dependencyGraph.sheetMapping; } /** * Calls the `addressMapping` method on the dependency graph. * Allows to execute `addressMapping` directly without a need to refer to `dependencyGraph`. * * @internal */ }, { key: "addressMapping", get: function get() { return this.dependencyGraph.addressMapping; } /** @internal */ }, { key: "dependencyGraph", get: function get() { return this._dependencyGraph; } /** @internal */ }, { key: "evaluator", get: function get() { return this._evaluator; } /** @internal */ }, { key: "columnSearch", get: function get() { return this._columnSearch; } /** @internal */ }, { key: "lazilyTransformingAstService", get: function get() { return this._lazilyTransformingAstService; } /** * Returns state of the validity of the license key. * * @internal */ }, { key: "licenseKeyValidityState", get: function get() { return this._config.licenseKeyValidityState; } }, { key: "getCellValue", value: /** * Returns the cell value of a given address. * Applies rounding and post-processing. * * @param {SimpleCellAddress} cellAddress - cell coordinates * * @throws [[ExpectedValueOfTypeError]] when cellAddress is of incorrect type * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[EvaluationSuspendedError]] when the evaluation is suspended * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['=SUM(1,2,3)', '2'], * ]); * * // get value of A1 cell, should be '6' * const A1Value = hfInstance.getCellValue({ sheet: 0, col: 0, row: 0 }); * * // get value of B1 cell, should be '2' * const B1Value = hfInstance.getCellValue({ sheet: 0, col: 1, row: 0 }); * ``` * * @category Cells */ function getCellValue(cellAddress) { if (!(0, _Cell.isSimpleCellAddress)(cellAddress)) { throw new _errors.ExpectedValueOfTypeError('SimpleCellAddress', 'cellAddress'); } this.ensureEvaluationIsNotSuspended(); return this._serialization.getCellValue(cellAddress); } }, { key: "ensureEvaluationIsNotSuspended", value: function ensureEvaluationIsNotSuspended() { if (this._evaluationSuspended) { throw new _errors.EvaluationSuspendedError(); } } /** * Returns a normalized formula string from the cell of a given address or `undefined` for an address that does not exist and empty values. * * @param {SimpleCellAddress} cellAddress - cell coordinates * * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[ExpectedValueOfTypeError]] when cellAddress is of incorrect type * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['=SUM(1,2,3)', '0'], * ]); * * // should return a normalized A1 cell formula: '=SUM(1,2,3)' * const A1Formula = hfInstance.getCellFormula({ sheet: 0, col: 0, row: 0 }); * * // should return a normalized B1 cell formula: 'undefined' * const B1Formula = hfInstance.getCellFormula({ sheet: 0, col: 1, row: 0 }); * ``` * * @category Cells */ }, { key: "getCellFormula", value: function getCellFormula(cellAddress) { if (!(0, _Cell.isSimpleCellAddress)(cellAddress)) { throw new _errors.ExpectedValueOfTypeError('SimpleCellAddress', 'cellAddress'); } return this._serialization.getCellFormula(cellAddress); } /** * Returns [[RawCellContent]] with a serialized content of the cell of a given address: either a cell formula, an explicit value, or an error. * * @param {SimpleCellAddress} cellAddress - cell coordinates * * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[EvaluationSuspendedError]] when the evaluation is suspended * @throws [[ExpectedValueOfTypeError]] when cellAddress is of incorrect type * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['=SUM(1,2,3)', '0'], * ]); * * // should return serialized content of A1 cell: '=SUM(1,2,3)' * const cellA1Serialized = hfInstance.getCellSerialized({ sheet: 0, col: 0, row: 0 }); * * // should return serialized content of B1 cell: '0' * const cellB1Serialized = hfInstance.getCellSerialized({ sheet: 0, col: 1, row: 0 }); * ``` * * @category Cells */ }, { key: "getCellSerialized", value: function getCellSerialized(cellAddress) { if (!(0, _Cell.isSimpleCellAddress)(cellAddress)) { throw new _errors.ExpectedValueOfTypeError('SimpleCellAddress', 'cellAddress'); } this.ensureEvaluationIsNotSuspended(); return this._serialization.getCellSerialized(cellAddress); } /** * Returns an array of arrays of [[CellValue]] with values of all cells from [[Sheet]]. * Applies rounding and post-processing. * * @param {number} sheetId - sheet ID number * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[EvaluationSuspendedError]] when the evaluation is suspended * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['0', '=SUM(1,2,3)', '=A1'], * ['1', '=TEXT(A2, "0.0%")', '=C1'], * ['2', '=SUM(A1:C1)', '=C1'], * ]); * * // should return all values of a sheet: [[0, 6, 0], [1, '1.0%', 0], [2, 6, 0]] * const sheetValues = hfInstance.getSheetValues(0); * ``` * * @category Sheets */ }, { key: "getSheetValues", value: function getSheetValues(sheetId) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); this.ensureEvaluationIsNotSuspended(); return this._serialization.getSheetValues(sheetId); } /** * Returns an array with normalized formula strings from [[Sheet]] or `undefined` for a cells that have no value. * * @param {SimpleCellAddress} sheetId - sheet ID number * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['0', '=SUM(1,2,3)', '=A1'], * ['1', '=TEXT(A2, "0.0%")', '=C1'], * ['2', '=SUM(A1:C1)', '=C1'], * ]); * * // should return all formulas of a sheet: * // [ * // [undefined, '=SUM(1,2,3)', '=A1'], * // [undefined, '=TEXT(A2, "0.0%")', '=C1'], * // [undefined, '=SUM(A1:C1)', '=C1'], * // ]; * const sheetFormulas = hfInstance.getSheetFormulas(0); * ``` * * @category Sheets */ }, { key: "getSheetFormulas", value: function getSheetFormulas(sheetId) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); return this._serialization.getSheetFormulas(sheetId); } /** * Returns an array of arrays of [[RawCellContent]] with serialized content of cells from [[Sheet]], either a cell formula or an explicit value. * * @param {SimpleCellAddress} sheetId - sheet ID number * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[EvaluationSuspendedError]] when the evaluation is suspended * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['0', '=SUM(1,2,3)', '=A1'], * ['1', '=TEXT(A2, "0.0%")', '=C1'], * ['2', '=SUM(A1:C1)', '=C1'], * ]); * * // should return: * // [ * // ['0', '=SUM(1,2,3)', '=A1'], * // ['1', '=TEXT(A2, "0.0%")', '=C1'], * // ['2', '=SUM(A1:C1)', '=C1'], * // ]; * const serializedContent = hfInstance.getSheetSerialized(0); * ``` * * @category Sheets */ }, { key: "getSheetSerialized", value: function getSheetSerialized(sheetId) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); this.ensureEvaluationIsNotSuspended(); return this._serialization.getSheetSerialized(sheetId); } /** * Returns a map containing dimensions of all sheets for the engine instance represented as a key-value pairs where keys are sheet IDs and dimensions are returned as numbers, width and height respectively. * * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * * @example * ```js * const hfInstance = HyperFormula.buildFromSheets({ * Sheet1: [ * ['1', '2', '=Sheet2!$A1'], * ], * Sheet2: [ * ['3'], * ['4'], * ], * }); * * // should return the dimensions of all sheets: * // { Sheet1: { width: 3, height: 1 }, Sheet2: { width: 1, height: 2 } } * const allSheetsDimensions = hfInstance.getAllSheetsDimensions(); * ``` * * @category Sheets */ }, { key: "getAllSheetsDimensions", value: function getAllSheetsDimensions() { var _this = this; return this._serialization.genericAllSheetsGetter(function (arg) { return _this.getSheetDimensions(arg); }); } /** * Returns dimensions of a specified sheet. * The sheet dimensions is represented with numbers: width and height. * * @param {number} sheetId - sheet ID number * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1', '2', '=Sheet2!$A1'], * ]); * * // should return provided sheet's dimensions: { width: 3, height: 1 } * const sheetDimensions = hfInstance.getSheetDimensions(0); * ``` * * @category Sheets */ }, { key: "getSheetDimensions", value: function getSheetDimensions(sheetId) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); return { width: this.dependencyGraph.getSheetWidth(sheetId), height: this.dependencyGraph.getSheetHeight(sheetId) }; } /** * Returns values of all sheets in a form of an object which property keys are strings and values are arrays of arrays of [[CellValue]]. * * @throws [[EvaluationSuspendedError]] when the evaluation is suspended * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1', '=A1+10', '3'], * ]); * * // should return all sheets values: { Sheet1: [ [ 1, 11, 3 ] ] } * const allSheetsValues = hfInstance.getAllSheetsValues(); * ``` * * @category Sheets */ }, { key: "getAllSheetsValues", value: function getAllSheetsValues() { this.ensureEvaluationIsNotSuspended(); return this._serialization.getAllSheetsValues(); } /** * Returns formulas of all sheets in a form of an object which property keys are strings and values are arrays of arrays of strings or possibly `undefined` when the call does not contain a formula. * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1', '2', '=A1+10'], * ]); * * // should return only formulas: { Sheet1: [ [ undefined, undefined, '=A1+10' ] ] } * const allSheetsFormulas = hfInstance.getAllSheetsFormulas(); * ``` * @category Sheets */ }, { key: "getAllSheetsFormulas", value: function getAllSheetsFormulas() { return this._serialization.getAllSheetsFormulas(); } /** * Returns formulas or values of all sheets in a form of an object which property keys are strings and values are arrays of arrays of [[RawCellContent]]. * * @throws [[EvaluationSuspendedError]] when the evaluation is suspended * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1', '2', '=A1+10'], * ]); * * // should return all sheets serialized content: { Sheet1: [ [ 1, 2, '=A1+10' ] ] } * const allSheetsSerialized = hfInstance.getAllSheetsSerialized(); * ``` * * @category Sheets */ }, { key: "getAllSheetsSerialized", value: function getAllSheetsSerialized() { this.ensureEvaluationIsNotSuspended(); return this._serialization.getAllSheetsSerialized(); } /** * Updates the config with given new metadata. * * @param {Partial<ConfigParams>} newParams configuration options to be updated or added * * @throws [[ExpectedValueOfTypeError]] when some parameters of config are of wrong type (e.g. currencySymbol) * @throws [[ConfigValueEmpty]] when some parameters of config are of invalid value (e.g. currencySymbol) * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1', '2'], * ]); * * // add a config param, for example maxColumns, * // you can check the configuration with getConfig method * hfInstance.updateConfig({ maxColumns: 1000 }); * ``` * * @category Instance */ }, { key: "updateConfig", value: function updateConfig(newParams) { var newConfig = this._config.mergeConfig(newParams); var configNewLanguage = this._config.mergeConfig({ language: newParams.language }); var serializedSheets = this._serialization.withNewConfig(configNewLanguage, this._namedExpressions).getAllSheetsSerialized(); var serializedNamedExpressions = this._serialization.getAllNamedExpressionsSerialized(); var newEngine = _BuildEngineFactory.BuildEngineFactory.rebuildWithConfig(newConfig, serializedSheets, serializedNamedExpressions, this._stats); this._config = newEngine.config; this._stats = newEngine.stats; this._dependencyGraph = newEngine.dependencyGraph; this._columnSearch = newEngine.columnSearch; this._parser = newEngine.parser; this._unparser = newEngine.unparser; this._cellContentParser = newEngine.cellContentParser; this._evaluator = newEngine.evaluator; this._lazilyTransformingAstService = newEngine.lazilyTransformingAstService; this._crudOperations = newEngine.crudOperations; this._exporter = newEngine.exporter; this._namedExpressions = newEngine.namedExpressions; this._serialization = newEngine.serialization; this._functionRegistry = newEngine.functionRegistry; } /** * Returns current configuration of the engine instance. * * @example * ```js * // should return all config metadata including default and those which were added * const hfConfig = hfInstance.getConfig(); * ``` * * @category Instance */ }, { key: "getConfig", value: function getConfig() { return this._config.getConfig(); } /** * Serializes and deserializes whole engine, effectively reloading it. * * @example * ```js * hfInstance.rebuildAndRecalculate(); * ``` * * @category Instance */ }, { key: "rebuildAndRecalculate", value: function rebuildAndRecalculate() { this.updateConfig({}); } /** * Returns a snapshot of computation time statistics. * It returns a map with key-value pairs where keys are enums for stat type and time (number). * * @internal * * @category Instance */ }, { key: "getStats", value: function getStats() { return this._stats.snapshot(); } /** * Undo the previous operation. * * Note that this method may trigger dependency graph recalculation. * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[NoOperationToUndoError]] when there is no operation running that can be undone * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1', '2'], * ['3', ''], * ]); * * // perform CRUD operation, for example remove the second row * hfInstance.removeRows(0, [1, 1]); * * // do an undo, it should return the changes * const changes = hfInstance.undo(); * ``` * * @category Undo and Redo */ }, { key: "undo", value: function undo() { this._crudOperations.undo(); return this.recomputeIfDependencyGraphNeedsIt(); } /** * Re-do recently undone operation. * * Note that this method may trigger dependency graph recalculation. * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[NoOperationToRedoError]] when there is no operation running that can be re-done * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1'], * ['2'], * ['3'], * ]); * * // perform CRUD operation, for example remove the second row * hfInstance.removeRows(0, [1, 1]); * * // do an undo, it should return prvious values: [['1'], ['2'], ['3']] * hfInstance.undo(); * * // do a redo, it should return the values after removing the second row: [['1'], ['3']] * const changes = hfInstance.redo(); * ``` * * @category Undo and Redo */ }, { key: "redo", value: function redo() { this._crudOperations.redo(); return this.recomputeIfDependencyGraphNeedsIt(); } /** * Checks if there is at least one operation that can be undone. * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1'], * ['2'], * ['3'], * ]); * * // perform CRUD operation, for example remove the second row * hfInstance.removeRows(0, [1, 1]); * * // should return 'true', it is possible to undo last operation * // which is removing rows in this example * const isSomethingToUndo = hfInstance.isThereSomethingToUndo(); * ``` * * @category Undo and Redo */ }, { key: "isThereSomethingToUndo", value: function isThereSomethingToUndo() { return this._crudOperations.isThereSomethingToUndo(); } /** * Checks if there is at least one operation that can be re-done. * * @example * ```js * hfInstance.undo(); * * // when there is an action to redo, this returns 'true' * const isSomethingToRedo = hfInstance.isThereSomethingToRedo(); * ``` * * @category Undo and Redo */ }, { key: "isThereSomethingToRedo", value: function isThereSomethingToRedo() { return this._crudOperations.isThereSomethingToRedo(); } /** * Returns information whether it is possible to change the content in a rectangular area bounded by the box. * If returns `true`, doing [[setCellContents]] operation won't throw any errors. * Returns `false` if the address is invalid or the sheet does not exist. * * @param {SimpleCellAddress | SimpleCellRange} address - single cell or block of cells to check * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[SheetsNotEqual]] if range provided has distinct sheet numbers for start and end * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1', '2'], * ]); * * // top left corner * const address1 = { col: 0, row: 0, sheet: 0 }; * // bottom right corner * const address2 = { col: 1, row: 0, sheet: 0 }; * * // should return 'true' for this example, it is possible to set content of * // width 2, height 1 in the first row and column of sheet 0 * const isSettable = hfInstance.isItPossibleToSetCellContents({ start: address1, end: address2 }); * ``` * * @category Cells */ }, { key: "isItPossibleToSetCellContents", value: function isItPossibleToSetCellContents(address) { var range; if ((0, _Cell.isSimpleCellAddress)(address)) { range = new _AbsoluteCellRange.AbsoluteCellRange(address, address); } else if ((0, _AbsoluteCellRange.isSimpleCellRange)(address)) { range = new _AbsoluteCellRange.AbsoluteCellRange(address.start, address.end); } else { throw new _errors.ExpectedValueOfTypeError('SimpleCellAddress | SimpleCellRange', 'address'); } try { this._crudOperations.ensureRangeInSizeLimits(range); var _iterator = _createForOfIteratorHelper(range.addresses(this._dependencyGraph)), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var it = _step.value; this._crudOperations.ensureItIsPossibleToChangeContent(it); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } } catch (e) { return false; } return true; } /** * Sets the content for a block of cells of a given coordinates. * * Note that this method may trigger dependency graph recalculation. * * @param {SimpleCellAddress} topLeftCornerAddress - top left corner of block of cells * @param {(RawCellContent[][]|RawCellContent)} cellContents - array with content * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[InvalidArgumentsError]] when the value is not an array of arrays or a raw cell value * @throws [[SheetSizeLimitExceededError]] when performing this operation would result in sheet size limits exceeding * @throws [[ExpectedValueOfTypeError]] if topLeftCornerAddress argument is of wrong type * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1', '2', '=A1'], * ]); * * // should set the content, returns: * // [{ * // address: { sheet: 0, col: 3, row: 0 }, * // newValue: 2, * // }] * const changes = hfInstance.setCellContents({ col: 3, row: 0, sheet: 0 }, [['=B1']]); * ``` * * @category Cells */ }, { key: "setCellContents", value: function setCellContents(topLeftCornerAddress, cellContents) { this._crudOperations.setCellContents(topLeftCornerAddress, cellContents); return this.recomputeIfDependencyGraphNeedsIt(); } /** * Reorders rows of a sheet according to a source-target mapping. * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - ID of a sheet to operate on * @param {[number, number][]} rowMapping - array mapping original positions to final positions of rows * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[InvalidArgumentsError]] when rowMapping does not define correct row permutation for some subset of rows of the given sheet * @throws [[SourceLocationHasArrayError]] when the selected position has array inside * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * [1], * [2], * [4, 5], * ]); * * // should set swap rows 0 and 2 in place, returns: * // [{ * // address: { sheet: 0, col: 0, row: 2 }, * // newValue: 1, * // }, * // { * // address: { sheet: 0, col: 1, row: 2 }, * // newValue: null, * // }, * // { * // address: { sheet: 0, col: 0, row: 0 }, * // newValue: 4, * // }, * // { * // address: { sheet: 0, col: 1, row: 0 }, * // newValue: 5, * // }] * const changes = hfInstance.swapRowIndexes(0, [[0,2],[2,0]]); * ``` * * @category Rows */ }, { key: "swapRowIndexes", value: function swapRowIndexes(sheetId, rowMapping) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); this._crudOperations.setRowOrder(sheetId, rowMapping); return this.recomputeIfDependencyGraphNeedsIt(); } /** * Checks if it is possible to reorder rows of a sheet according to a source-target mapping. * * @param {number} sheetId - ID of a sheet to operate on * @param {[number, number][]} rowMapping - array mapping original positions to final positions of rows * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * [1], * [2], * [4, 5], * ]); * * // returns true * const isSwappable = hfInstance.isItPossibleToSwapRowIndexes(0, [[0,2],[2,0]]); * * // returns false * const isSwappable = hfInstance.isItPossibleToSwapRowIndexes(0, [[0,1]]); * ``` * * @category Rows */ }, { key: "isItPossibleToSwapRowIndexes", value: function isItPossibleToSwapRowIndexes(sheetId, rowMapping) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); try { this._crudOperations.validateSwapRowIndexes(sheetId, rowMapping); this._crudOperations.testRowOrderForArrays(sheetId, rowMapping); return true; } catch (e) { return false; } } /** * Reorders rows of a sheet according to a permutation. * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - ID of a sheet to operate on * @param {number[]} newRowOrder - permutation of rows * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[InvalidArgumentsError]] when rowMapping does not define correct row permutation for some subset of rows of the given sheet * @throws [[SourceLocationHasArrayError]] when the selected position has array inside * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * [1], * [2], * [4, 5], * ]); * // rows 0 and 2 swap places * * // returns: * // [{ * // address: { sheet: 0, col: 0, row: 2 }, * // newValue: 1, * // }, * // { * // address: { sheet: 0, col: 1, row: 2 }, * // newValue: null, * // }, * // { * // address: { sheet: 0, col: 0, row: 0 }, * // newValue: 4, * // }, * // { * // address: { sheet: 0, col: 1, row: 0 }, * // newValue: 5, * // }] * const changes = hfInstance.setRowOrder(0, [2, 1, 0]); * ``` * * @category Rows */ }, { key: "setRowOrder", value: function setRowOrder(sheetId, newRowOrder) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); var mapping = this._crudOperations.mappingFromOrder(sheetId, newRowOrder, 'row'); return this.swapRowIndexes(sheetId, mapping); } /** * Checks if it is possible to reorder rows of a sheet according to a permutation. * * @param {number} sheetId - ID of a sheet to operate on * @param {number[]} newRowOrder - permutation of rows * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * [1], * [2], * [4, 5], * ]); * * // returns true * hfInstance.isItPossibleToSetRowOrder(0, [2, 1, 0]); * * // returns false * hfInstance.isItPossibleToSetRowOrder(0, [2]); * ``` * * @category Rows */ }, { key: "isItPossibleToSetRowOrder", value: function isItPossibleToSetRowOrder(sheetId, newRowOrder) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); try { var rowMapping = this._crudOperations.mappingFromOrder(sheetId, newRowOrder, 'row'); this._crudOperations.validateSwapRowIndexes(sheetId, rowMapping); this._crudOperations.testRowOrderForArrays(sheetId, rowMapping); return true; } catch (e) { return false; } } /** * Reorders columns of a sheet according to a source-target mapping. * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - ID of a sheet to operate on * @param {[number, number][]} columnMapping - array mapping original positions to final positions of columns * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[InvalidArgumentsError]] when columnMapping does not define correct column permutation for some subset of columns of the given sheet * @throws [[SourceLocationHasArrayError]] when the selected position has array inside * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * [1, 2, 4], * [5] * ]); * * // should set swap columns 0 and 2 in place, returns: * // [{ * // address: { sheet: 0, col: 2, row: 0 }, * // newValue: 1, * // }, * // { * // address: { sheet: 0, col: 2, row: 1 }, * // newValue: 5, * // }, * // { * // address: { sheet: 0, col: 0, row: 0 }, * // newValue: 4, * // }, * // { * // address: { sheet: 0, col: 0, row: 1 }, * // newValue: null, * // }] * const changes = hfInstance.swapColumnIndexes(0, [[0,2],[2,0]]); * ``` * * @category Columns */ }, { key: "swapColumnIndexes", value: function swapColumnIndexes(sheetId, columnMapping) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); this._crudOperations.setColumnOrder(sheetId, columnMapping); return this.recomputeIfDependencyGraphNeedsIt(); } /** * Checks if it is possible to reorder columns of a sheet according to a source-target mapping. * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * [1, 2, 4], * [5] * ]); * * // returns true * hfInstance.isItPossibleToSwapColumnIndexes(0, [[0,2],[2,0]]); * * // returns false * hfInstance.isItPossibleToSwapColumnIndexes(0, [[0,1]]); * ``` * * @category Columns */ }, { key: "isItPossibleToSwapColumnIndexes", value: function isItPossibleToSwapColumnIndexes(sheetId, columnMapping) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); try { this._crudOperations.validateSwapColumnIndexes(sheetId, columnMapping); this._crudOperations.testColumnOrderForArrays(sheetId, columnMapping); return true; } catch (e) { return false; } } /** * Reorders columns of a sheet according to a permutation. * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - ID of a sheet to operate on * @param {number[]} newColumnOrder - permutation of columns * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[InvalidArgumentsError]] when columnMapping does not define correct column permutation for some subset of columns of the given sheet * @throws [[SourceLocationHasArrayError]] when the selected position has array inside * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * [1, 2, 4], * [5] * ]); * // columns 0 and 2 swap places * * // returns: * // [{ * // address: { sheet: 0, col: 2, row: 0 }, * // newValue: 1, * // }, * // { * // address: { sheet: 0, col: 2, row: 1 }, * // newValue: 5, * // }, * // { * // address: { sheet: 0, col: 0, row: 0 }, * // newValue: 4, * // }, * // { * // address: { sheet: 0, col: 0, row: 1 }, * // newValue: null, * // }] * const changes = hfInstance.setColumnOrder(0, [2, 1, 0]]); * ``` * * @category Columns */ }, { key: "setColumnOrder", value: function setColumnOrder(sheetId, newColumnOrder) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); var mapping = this._crudOperations.mappingFromOrder(sheetId, newColumnOrder, 'column'); return this.swapColumnIndexes(sheetId, mapping); } /** * Checks if it possible to reorder columns of a sheet according to a permutation. * * @param {number} sheetId - ID of a sheet to operate on * @param {number[]} newColumnOrder - permutation of columns * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * [1, 2, 4], * [5] * ]); * * // returns true * hfInstance.isItPossibleToSetColumnOrder(0, [2, 1, 0]]); * * // returns false * hfInstance.isItPossibleToSetColumnOrder(0, [1]]); * ``` * * @category Columns */ }, { key: "isItPossibleToSetColumnOrder", value: function isItPossibleToSetColumnOrder(sheetId, newColumnOrder) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); try { var columnMapping = this._crudOperations.mappingFromOrder(sheetId, newColumnOrder, 'column'); this._crudOperations.validateSwapColumnIndexes(sheetId, columnMapping); this._crudOperations.testColumnOrderForArrays(sheetId, columnMapping); return true; } catch (e) { return false; } } /** * Returns information whether it is possible to add rows into a specified position in a given sheet. * Checks against particular rules to ascertain that addRows can be called. * If returns `true`, doing [[addRows]] operation won't throw any errors. * Returns `false` if adding rows would exceed the sheet size limit or given arguments are invalid. * * @param {number} sheetId - sheet ID in which rows will be added * @param {ColumnRowIndex[]} indexes - non-contiguous indexes with format [row, amount], where row is a row number above which the rows will be added * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1', '2', '3'], * ]); * * // should return 'true' for this example, * // it is possible to add one row in the second row of sheet 0 * const isAddable = hfInstance.isItPossibleToAddRows(0, [1, 1]); * ``` * * @category Rows */ }, { key: "isItPossibleToAddRows", value: function isItPossibleToAddRows(sheetId) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); for (var _len = arguments.length, indexes = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { indexes[_key - 1] = arguments[_key]; } var normalizedIndexes = (0, _Operations.normalizeAddedIndexes)(indexes); try { var _this$_crudOperations; (_this$_crudOperations = this._crudOperations).ensureItIsPossibleToAddRows.apply(_this$_crudOperations, [sheetId].concat(_toConsumableArray(normalizedIndexes))); return true; } catch (e) { return false; } } /** * Adds multiple rows into a specified position in a given sheet. * Does nothing if rows are outside of effective sheet size. * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - sheet ID in which rows will be added * @param {ColumnRowIndex[]} indexes - non-contiguous indexes with format [row, amount], where row is a row number above which the rows will be added * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * @throws [[SheetSizeLimitExceededError]] when performing this operation would result in sheet size limits exceeding * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1'], * ['2'], * ]); * * // should return a list of cells which values changed after the operation, * // their absolute addresses and new values * const changes = hfInstance.addRows(0, [0, 1]); * ``` * * @category Rows */ }, { key: "addRows", value: function addRows(sheetId) { var _this$_crudOperations2; (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); for (var _len2 = arguments.length, indexes = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { indexes[_key2 - 1] = arguments[_key2]; } (_this$_crudOperations2 = this._crudOperations).addRows.apply(_this$_crudOperations2, [sheetId].concat(indexes)); return this.recomputeIfDependencyGraphNeedsIt(); } /** * Returns information whether it is possible to remove rows from a specified position in a given sheet. * Checks against particular rules to ascertain that removeRows can be called. * If returns `true`, doing [[removeRows]] operation won't throw any errors. * Returns `false` if given arguments are invalid. * * @param {number} sheetId - sheet ID from which rows will be removed * @param {ColumnRowIndex[]} indexes - non-contiguous indexes with format: [row, amount] * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1'], * ['2'], * ]); * * // should return 'true' for this example * // it is possible to remove one row from row 1 of sheet 0 * const isRemovable = hfInstance.isItPossibleToRemoveRows(0, [1, 1]); * ``` * * @category Rows */ }, { key: "isItPossibleToRemoveRows", value: function isItPossibleToRemoveRows(sheetId) { (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); for (var _len3 = arguments.length, indexes = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { indexes[_key3 - 1] = arguments[_key3]; } var normalizedIndexes = (0, _Operations.normalizeRemovedIndexes)(indexes); try { var _this$_crudOperations3; (_this$_crudOperations3 = this._crudOperations).ensureItIsPossibleToRemoveRows.apply(_this$_crudOperations3, [sheetId].concat(_toConsumableArray(normalizedIndexes))); return true; } catch (e) { return false; } } /** * Removes multiple rows from a specified position in a given sheet. * Does nothing if rows are outside of the effective sheet size. * * Note that this method may trigger dependency graph recalculation. * * @param {number} sheetId - sheet ID from which rows will be removed * @param {ColumnRowIndex[]} indexes - non-contiguous indexes with format: [row, amount] * * @fires [[valuesUpdated]] if recalculation was triggered by this change * * @throws [[ExpectedValueOfTypeError]] if any of its basic type argument is of wrong type * @throws [[InvalidArgumentsError]] when the given arguments are invalid * @throws [[NoSheetWithIdError]] when the given sheet ID does not exist * * @example * ```js * const hfInstance = HyperFormula.buildFromArray([ * ['1'], * ['2'], * ]); * * // should return: [{ sheet: 0, col: 1, row: 2, value: null }] for this example * const changes = hfInstance.removeRows(0, [1, 1]); * ``` * * @category Rows */ }, { key: "removeRows", value: function removeRows(sheetId) { var _this$_crudOperations4; (0, _ArgumentSanitization.validateArgToType)(sheetId, 'number', 'sheetId'); for (var _len4 = arguments.length, indexes = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) { indexes[_key4 - 1] = arguments[_key4]; } (_this$_crudOperations4 = this._crudOperations).removeRows.apply(_this$_crudOperations4, [sheetId].concat(indexes)); return this.recomputeIfDependencyGraphNeedsIt(); } /** * Returns information whether it is possible to add columns into a specified position in a given sheet. * Checks against particular rules to ascertain that addColumns can be called. * If returns `true`, doing [[addColumns]] operation won't throw any errors. * Returns `false` if adding columns would exceed the sheet size limit or given arguments are invali