UNPKG

@odoo/o-spreadsheet

Version:
1,338 lines (1,298 loc) 520 kB
import * as chart_js from 'chart.js'; import { ChartConfiguration, ChartDataset, CoreChartOptions, Scriptable, Color as Color$1, ScriptableContext, FontSpec, Point, ChartType as ChartType$1, ChartMeta } from 'chart.js'; import * as ChartGeo from 'chartjs-chart-geo'; import * as chart_js_dist_types_utils from 'chart.js/dist/types/utils'; import * as chart_js_dist_types_geometric from 'chart.js/dist/types/geometric'; import * as _odoo_owl from '@odoo/owl'; import { Component, ComponentConstructor } from '@odoo/owl'; import * as chart_js_dist_types_basic from 'chart.js/dist/types/basic'; import * as chart_js_auto from 'chart.js/auto'; import { Chart, ChartConfiguration as ChartConfiguration$1 } from 'chart.js/auto'; type LocaleCode = string & Alias; interface Locale { name: string; code: LocaleCode; thousandsSeparator?: string; decimalSeparator: string; weekStart: number; dateFormat: string; timeFormat: string; formulaArgSeparator: string; } declare const DEFAULT_LOCALES: Locale[]; declare const DEFAULT_LOCALE: Locale; type Format = string & Alias; type FormattedValue = string & Alias; interface LocaleFormat { locale: Locale; format?: Format; } interface CellAttributes { readonly id: UID; /** * Raw cell content */ readonly content: string; readonly format?: Format; } interface LiteralCell extends CellAttributes { readonly isFormula: false; readonly parsedValue: CellValue; } interface FormulaCell extends CellAttributes { readonly isFormula: true; readonly compiledFormula: RangeCompiledFormula; } type Cell = LiteralCell | FormulaCell; interface EvaluatedCellProperties extends FunctionResultObject { readonly format?: Format; /** * Cell value formatted based on the format */ readonly formattedValue: FormattedValue; readonly defaultAlign: "right" | "center" | "left"; /** * Can the cell appear in an automatic sum zone. */ readonly isAutoSummable: boolean; readonly link?: Link; } type CellValue = string | number | boolean | null; type EvaluatedCell = NumberCell | TextCell | BooleanCell | EmptyCell | ErrorCell; interface NumberCell extends EvaluatedCellProperties { readonly type: CellValueType.number; readonly value: number; } interface TextCell extends EvaluatedCellProperties { readonly type: CellValueType.text; readonly value: string; } interface BooleanCell extends EvaluatedCellProperties { readonly type: CellValueType.boolean; readonly value: boolean; } interface EmptyCell extends EvaluatedCellProperties { readonly type: CellValueType.empty; readonly value: null; } interface ErrorCell extends EvaluatedCellProperties { readonly type: CellValueType.error; readonly value: string; readonly message?: string; } declare enum CellValueType { boolean = "boolean", number = "number", text = "text", empty = "empty", error = "error" } type TokenType = "OPERATOR" | "NUMBER" | "STRING" | "SYMBOL" | "SPACE" | "DEBUGGER" | "ARG_SEPARATOR" | "ARRAY_ROW_SEPARATOR" | "LEFT_PAREN" | "RIGHT_PAREN" | "LEFT_BRACE" | "RIGHT_BRACE" | "REFERENCE" | "INVALID_REFERENCE" | "UNKNOWN"; interface Token { readonly type: TokenType; readonly value: string; } declare function tokenize(str: string, locale?: Locale): Token[]; interface GenericCriterion { type: GenericCriterionType; values: string[]; } type GenericDateCriterion = GenericCriterion & { dateValue: DateCriterionValue; }; type GenericCriterionType = "containsText" | "notContainsText" | "isEqualText" | "isEmail" | "isLink" | "dateIs" | "dateIsBefore" | "dateIsOnOrBefore" | "dateIsAfter" | "dateIsOnOrAfter" | "dateIsBetween" | "dateIsNotBetween" | "dateIsValid" | "isEqual" | "isNotEqual" | "isGreaterThan" | "isGreaterOrEqualTo" | "isLessThan" | "isLessOrEqualTo" | "isBetween" | "isNotBetween" | "isBoolean" | "isValueInList" | "isValueInRange" | "customFormula" | "beginsWithText" | "endsWithText" | "isNotEmpty" | "isEmpty"; type DateCriterionValue = "today" | "tomorrow" | "yesterday" | "lastWeek" | "lastMonth" | "lastYear" | "exactDate"; type EvaluatedCriterion<T extends GenericCriterion = GenericCriterion> = Omit<T, "values"> & { values: CellValue[]; }; type EvaluatedDateCriterion = EvaluatedCriterion<GenericDateCriterion>; interface RangePart { readonly colFixed: boolean; readonly rowFixed: boolean; } interface Range { readonly zone: Readonly<Zone>; readonly unboundedZone: Readonly<UnboundedZone>; readonly parts: readonly RangePart[]; readonly invalidXc?: string; /** true if the user provided the range with the sheet name */ readonly prefixSheet: boolean; /** the name of any sheet that is invalid */ readonly invalidSheetName?: string; /** the sheet on which the range is defined */ readonly sheetId: UID; } interface BoundedRange { sheetId: UID; zone: Zone; } interface RangeStringOptions { useBoundedReference?: boolean; useFixedReference?: boolean; } interface RangeData { _zone: Zone | UnboundedZone; _sheetId: UID; } /** * https://docs.microsoft.com/en-us/openspecs/office_standards/ms-xlsx/025ea6e4-ad42-43ea-a016-16f4e4688ac8 */ interface ConditionalFormat { id: UID; rule: ConditionalFormatRule; stopIfTrue?: boolean; ranges: string[]; } interface ConditionalFormatInternal extends Omit<ConditionalFormat, "ranges" | "rule"> { ranges: Range[]; rule: ConditionalFormatRuleInternal; } type ConditionalFormatRule = SingleColorRules | ColorScaleRule | IconSetRule | DataBarRule; type ConditionalFormatRuleInternal = SingleColorRules | ColorScaleRule | IconSetRule | DataBarRuleInternal; type SingleColorRules = CellIsRule; interface SingleColorRule { style: Style; } interface TextRule extends SingleColorRule { text: string; } interface CellIsRule extends SingleColorRule { type: "CellIsRule"; operator: ConditionalFormattingOperatorValues; values: string[]; dateValue?: DateCriterionValue; } interface ExpressionRule extends SingleColorRule { type: "ExpressionRule"; } type ThresholdType = "value" | "number" | "percentage" | "percentile" | "formula"; type ColorScaleThreshold = { color: number; type: ThresholdType; value?: string; }; type ColorScaleMidPointThreshold = { color: number; type: Exclude<ThresholdType, "value">; value: string; }; type IconThreshold = { type: Exclude<ThresholdType, "value">; operator: "gt" | "ge"; value: string; }; interface ColorScaleRule { type: "ColorScaleRule"; minimum: ColorScaleThreshold; maximum: ColorScaleThreshold; midpoint?: ColorScaleMidPointThreshold; } interface DataBarRule { type: "DataBarRule"; color: number; rangeValues?: string; } interface DataBarRuleInternal extends Omit<DataBarRule, "rangeValues"> { rangeValues?: Range; } interface IconSet { upper: string; middle: string; lower: string; } interface IconSetRule { type: "IconSetRule"; icons: IconSet; upperInflectionPoint: IconThreshold; lowerInflectionPoint: IconThreshold; } interface ContainsTextRule extends TextRule { type: "ContainsTextRule"; } interface NotContainsTextRule extends TextRule { type: "NotContainsTextRule"; } interface BeginsWithRule extends TextRule { type: "BeginsWithRule"; } interface EndsWithRule extends TextRule { type: "EndsWithRule"; } interface containsBlanksRule extends TextRule { type: "containsBlanksRule"; } interface notContainsBlanksRule extends TextRule { type: "notContainsBlanksRule"; } interface containsErrorsRule extends SingleColorRule { type: "containsErrorsRule"; } interface notContainsErrorsRule extends SingleColorRule { type: "notContainsErrorsRule"; } interface TimePeriodRule extends SingleColorRule { type: "TimePeriodRule"; timePeriod: string; } interface AboveAverageRule extends SingleColorRule { type: "AboveAverageRule"; aboveAverage: boolean; equalAverage: boolean; } interface Top10Rule extends SingleColorRule { type: "Top10Rule"; percent: boolean; bottom: boolean; rank: number; } declare const cfOperators: readonly ["containsText", "notContainsText", "isGreaterThan", "isGreaterOrEqualTo", "isLessThan", "isLessOrEqualTo", "isBetween", "isNotBetween", "beginsWithText", "endsWithText", "isNotEmpty", "isEmpty", "isNotEqual", "isEqual", "customFormula", "dateIs", "dateIsBefore", "dateIsAfter", "dateIsOnOrBefore", "dateIsOnOrAfter"]; type ConditionalFormattingOperatorValues = (typeof cfOperators)[number]; declare const availableConditionalFormatOperators: Set<ConditionalFormattingOperatorValues>; declare const functionCache: { [key: string]: FormulaToExecute; }; declare function compile(formula: string): CompiledFormula; declare function compileTokens(tokens: Token[]): CompiledFormula; interface ASTBase { debug?: boolean; tokenStartIndex: number; tokenEndIndex: number; } interface ASTNumber extends ASTBase { type: "NUMBER"; value: number; } interface ASTReference extends ASTBase { type: "REFERENCE"; value: string; } interface ASTString extends ASTBase { type: "STRING"; value: string; } interface ASTBoolean extends ASTBase { type: "BOOLEAN"; value: boolean; } interface ASTUnaryOperation extends ASTBase { type: "UNARY_OPERATION"; value: any; operand: AST; postfix?: boolean; } interface ASTOperation extends ASTBase { type: "BIN_OPERATION"; value: any; left: AST; right: AST; } interface ASTFuncall extends ASTBase { type: "FUNCALL"; value: string; args: AST[]; } interface ASTSymbol extends ASTBase { type: "SYMBOL"; value: string; } interface ASTArray extends ASTBase { type: "ARRAY"; value: AST[][]; } interface ASTEmpty extends ASTBase { type: "EMPTY"; value: ""; } type AST = ASTOperation | ASTUnaryOperation | ASTFuncall | ASTSymbol | ASTArray | ASTNumber | ASTBoolean | ASTString | ASTReference | ASTEmpty; /** * Parse an expression (as a string) into an AST. */ declare function parse(str: string): AST; declare function parseTokens(tokens: Token[]): AST; /** * Allows to visit all nodes of an AST and apply a mapping function * to nodes of a specific type. * Useful if you want to convert some part of a formula. * * @example * convertAstNodes(ast, "FUNCALL", convertFormulaToExcel) * * function convertFormulaToExcel(ast: ASTFuncall) { * // ... * return modifiedAst * } */ declare function convertAstNodes<T extends AST["type"]>(ast: AST, type: T, fn: (ast: Extract<AST, { type: T; }>) => AST): AST; declare function iterateAstNodes(ast: AST): AST[]; declare class Registry$1<T> { content: Record<string, T>; add(key: string, value: T): this; replace(key: string, value: T): this; get(key: string): T; contains(key: string): boolean; getAll(): T[]; getKeys(): string[]; remove(key: string): void; } type ArgType = "ANY" | "BOOLEAN" | "NUMBER" | "STRING" | "DATE" | "RANGE" | "RANGE<BOOLEAN>" | "RANGE<NUMBER>" | "RANGE<DATE>" | "RANGE<STRING>" | "RANGE<ANY>" | "META" | "RANGE<META>"; interface ArgDefinition { acceptMatrix?: boolean; acceptMatrixOnly?: boolean; acceptErrors?: boolean; repeating?: boolean; optional?: boolean; description: string; name: string; type: ArgType[]; default?: boolean; defaultValue?: any; proposalValues?: ArgProposal[]; } type ArgProposal = { value: CellValue; label?: string; }; type ComputeFunction<R> = (this: EvalContext, ...args: Arg[]) => R; interface AddFunctionDescription { compute: ComputeFunction<FunctionResultObject | Matrix<FunctionResultObject> | CellValue | Matrix<CellValue>>; description: string; category?: string; args: ArgDefinition[]; isExported?: boolean; hidden?: boolean; } type FunctionDescription = AddFunctionDescription & { name: string; minArgRequired: number; maxArgPossible: number; nbrArgRepeating: number; nbrOptionalNonRepeatingArgs: number; }; type EvalContext = { __originSheetId: UID; __originCellPosition?: CellPosition; locale: Locale; getters: Getters; [key: string]: any; updateDependencies?: (position: CellPosition) => void; addDependencies?: (position: CellPosition, ranges: Range[]) => void; debug?: boolean; lookupCaches?: LookupCaches; }; /** * used to cache lookup values for linear search **/ type LookupCaches = { forwardSearch: Map<unknown, Map<CellValue, number>>; reverseSearch: Map<unknown, Map<CellValue, number>>; }; declare class FunctionRegistry extends Registry$1<FunctionDescription> { mapping: { [key: string]: ComputeFunction<Matrix<FunctionResultObject> | FunctionResultObject>; }; add(name: string, addDescr: AddFunctionDescription): this; replace(name: string, addDescr: AddFunctionDescription): this; } type Functions = { [functionName: string]: AddFunctionDescription; }; type Category = { name: string; functions: Functions; }; declare const categories: Category[]; interface SearchOptions { matchCase: boolean; exactMatch: boolean; searchFormulas: boolean; searchScope: "allSheets" | "activeSheet" | "specificRange"; specificRange?: Range; } /** * Deep copy arrays, plain objects and primitive values. * Throws an error for other types such as class instances. * Sparse arrays remain sparse. */ declare function deepCopy<T>(obj: T): T; /** * Remove quotes from a quoted string. */ declare function unquote(string: string, quoteChar?: "'" | '"'): string; /** Replace the excel-excluded characters of a sheetName */ declare function sanitizeSheetName(sheetName: string, replacementChar?: string): string; declare function isMarkdownLink(str: string): boolean; /** * Build a markdown link from a label and an url */ declare function markdownLink(label: string, url: string): string; declare function parseMarkdownLink(str: string): { url: string; label: string; }; /** * This helper function can be used as a type guard when filtering arrays. * const foo: number[] = [1, 2, undefined, 4].filter(isDefined) */ declare function isDefined<T>(argument: T | undefined): argument is T; /** * Lazy value computed by the provided function. */ declare function lazy<T>(fn: (() => T) | T): Lazy<T>; /** * Compares n objects. */ declare function deepEquals(...o: any[]): boolean; declare function getUniqueText(text: string, texts: string[], options?: { compute?: (text: string, increment: number) => string; start?: number; computeFirstOne?: boolean; }): string; declare function isFormula(content: string): boolean; /** * Return true if the argument is a "number string". * * Note that "" (empty string) does not count as a number string */ declare function isNumber(value: string | undefined, locale: Locale): boolean; declare function splitReference(ref: string): { sheetName?: string; xc: string; }; declare class UuidGenerator { private getCrypto; /** * Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters) * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4, * it also has a smaller size, which is preferable to alleviate the overall data size. * * This method is preferable when generating uuids for the core data (sheetId, figureId, etc) * as they will appear several times in the revisions and local history. * */ smallUuid(): string; /** * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid. * This method should be used when you need to avoid collisions at all costs, like the id of a revision. */ uuidv4(): string; } /** * This is a generic event bus based on the Owl event bus. * This bus however ensures type safety across events and subscription callbacks. */ declare class EventBus<Event extends { type: string; }> { subscriptions: { [eventType: string]: Subscription[]; }; /** * Add a listener for the 'eventType' events. * * Note that the 'owner' of this event can be anything, but will more likely * be a component or a class. The idea is that the callback will be called with * the proper owner bound. * * Also, the owner should be kind of unique. This will be used to remove the * listener. */ on<T extends Event["type"], E extends Extract<Event, { type: T; }>>(type: T, owner: any, callback: (r: Omit<E, "type">) => void): void; /** * Emit an event of type 'eventType'. Any extra arguments will be passed to * the listeners callback. */ trigger<T extends Event["type"], E extends Extract<Event, { type: T; }>>(type: T, payload?: Omit<E, "type">): void; /** * Remove a listener */ off<T extends Event["type"]>(eventType: T, owner: any): void; /** * Remove all subscriptions. */ clear(): void; } type Callback = (...args: any[]) => void; interface Subscription { owner: any; callback: Callback; } declare class PositionMap<T> { private map; constructor(entries?: Iterable<readonly [CellPosition, T]>); set({ sheetId, col, row }: CellPosition, value: T): void; setMany(values: Iterable<[CellPosition, T]>): void; get({ sheetId, col, row }: CellPosition): T | undefined; getSheet(sheetId: UID): Record<number, Record<number, T>> | undefined; clearSheet(sheetId: UID): void; has({ sheetId, col, row }: CellPosition): boolean; delete({ sheetId, col, row }: CellPosition): void; keys(): CellPosition[]; keysForSheet(sheetId: UID): CellPosition[]; entries(): IterableIterator<[CellPosition, T]>; } /** * An Operation can be executed to change a data structure from state A * to state B. * It should hold the necessary data used to perform this transition. * It should be possible to revert the changes made by this operation. * * In the context of o-spreadsheet, the data from an operation would * be a revision (the commands are used to execute it, the `changes` are used * to revert it). */ declare class Operation<T> { readonly id: UID; readonly data: T; constructor(id: UID, data: T); transformed(transformation: Transformation<T>): Operation<T>; } /** * A branch holds a sequence of operations. * It can be represented as "A - B - C - D" if A, B, C and D are executed one * after the other. * * @param buildTransformation Factory to build transformations * @param operations initial operations */ declare class Branch<T> { private readonly buildTransformation; private operations; constructor(buildTransformation: TransformationFactory<T>, operations?: Operation<T>[]); getOperations(): readonly Operation<T>[]; getOperation(operationId: UID): Operation<T>; getLastOperationId(): UID | undefined; /** * Get the id of the operation appears first in the list of operations */ getFirstOperationAmong(op1: UID, op2: UID): UID; contains(operationId: UID): boolean; /** * Add the given operation as the first operation */ prepend(operation: Operation<T>): void; /** * add the given operation after the given predecessorOpId */ insert(newOperation: Operation<T>, predecessorOpId: UID): void; /** * Add the given operation as the last operation */ append(operation: Operation<T>): void; /** * Append operations in the given branch to this branch. */ appendBranch(branch: Branch<T>): void; /** * Create and return a copy of this branch, starting after the given operationId */ fork(operationId: UID): Branch<T>; /** * Transform all the operations in this branch with the given transformation */ transform(transformation: Transformation<T>): void; /** * Cut the branch before the operation, meaning the operation * and all following operations are dropped. */ cutBefore(operationId: UID): void; /** * Cut the branch after the operation, meaning all following operations are dropped. */ cutAfter(operationId: UID): void; /** * Find an operation in this branch based on its id. * This returns the operation itself, operations which comes before it * and operation which comes after it. */ private locateOperation; } interface CreateRevisionOptions { revisionId?: UID; clientId?: UID; pending?: boolean; } interface HistoryChange { key: string; target: any; before: any; } interface WorkbookHistory<Plugin> { update<T extends keyof Plugin>(key: T, val: Plugin[T]): void; update<T extends keyof Plugin, U extends keyof NonNullable<Plugin[T]>>(key1: T, key2: U, val: NonNullable<Plugin[T]>[U]): void; update<T extends keyof Plugin, U extends keyof NonNullable<Plugin[T]>, K extends keyof NonNullable<NonNullable<Plugin[T]>[U]>>(key1: T, key2: U, key3: K, val: NonNullable<NonNullable<Plugin[T]>[U]>[K]): void; update<T extends keyof Plugin, U extends keyof NonNullable<Plugin[T]>, K extends keyof NonNullable<NonNullable<Plugin[T]>[U]>, V extends keyof NonNullable<NonNullable<NonNullable<Plugin[T]>[U]>[K]>>(key1: T, key2: U, key3: K, key4: V, val: NonNullable<NonNullable<NonNullable<Plugin[T]>[U]>[K]>[V]): void; update<T extends keyof Plugin, U extends keyof NonNullable<Plugin[T]>, K extends keyof NonNullable<NonNullable<Plugin[T]>[U]>, V extends keyof NonNullable<NonNullable<NonNullable<Plugin[T]>[U]>[K]>, W extends keyof NonNullable<NonNullable<NonNullable<NonNullable<Plugin[T]>[U]>[K]>[V]>>(key1: T, key2: U, key3: K, key4: V, key5: W, val: NonNullable<NonNullable<NonNullable<NonNullable<Plugin[T]>[U]>[K]>[V]>[W]): void; update<T extends keyof Plugin, U extends keyof NonNullable<Plugin[T]>, K extends keyof NonNullable<NonNullable<Plugin[T]>[U]>, V extends keyof NonNullable<NonNullable<NonNullable<Plugin[T]>[U]>[K]>, W extends keyof NonNullable<NonNullable<NonNullable<NonNullable<Plugin[T]>[U]>[K]>[V]>, Y extends keyof NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<Plugin[T]>[U]>[K]>[V]>[W]>>(key1: T, key2: U, key3: K, key4: V, key5: W, key6: Y, val: NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<Plugin[T]>[U]>[K]>[V]>[W]>[Y]): void; } type Transformation<T = unknown> = (dataToTransform: T) => T; interface TransformationFactory<T = unknown> { /** * Build a transformation function to transform any operation as if the execution of * a previous `operation` was omitted. */ without: (operation: T) => Transformation<T>; /** * Build a transformation function to transform any operation as if a new `operation` was * executed before. */ with: (operation: T) => Transformation<T>; } interface OperationSequenceNode<T> { operation: Operation<T>; branch: Branch<T>; isCancelled: boolean; next?: { operation: Operation<T>; branch: Branch<T>; }; } type HistoryPath = [any, ...(number | string)[]]; declare class StateObserver { private changes; private commands; /** * Record the changes which could happen in the given callback, save them in a * new revision with the given id and userId. */ recordChanges(callback: () => void): { changes: HistoryChange[]; commands: CoreCommand[]; }; addCommand(command: CoreCommand): void; addChange(...args: [...HistoryPath, any]): void; } interface CarouselState { readonly carousels: Record<UID, Record<UID, Carousel | undefined> | undefined>; } declare class CarouselPlugin extends CorePlugin<CarouselState> implements CarouselState { static getters: readonly ["getCarousel", "doesCarouselExist"]; readonly carousels: Record<UID, Record<UID, Carousel | undefined> | undefined>; allowDispatch(cmd: CoreCommand): CommandResult.Success | CommandResult.InvalidFigureId | CommandResult.DuplicatedFigureId; handle(cmd: CoreCommand): void; doesCarouselExist(figureId: UID): boolean; getCarousel(figureId: UID): Carousel; private removeDeletedCharts; import(data: WorkbookData): void; export(data: WorkbookData): void; } interface CoreState$1 { cells: Record<UID, Record<UID, Cell | undefined> | undefined>; nextId: number; } /** * Core Plugin * * This is the most fundamental of all plugins. It defines how to interact with * cell and sheet content. */ declare class CellPlugin extends CorePlugin<CoreState$1> implements CoreState$1 { static getters: readonly ["zoneToXC", "getCells", "getTranslatedCellFormula", "getCellById", "getFormulaString", "getFormulaMovedInSheet"]; readonly nextId = 1; readonly cells: { [sheetId: string]: { [id: string]: Cell; }; }; adaptRanges({ applyChange }: RangeAdapterFunctions, sheetId: UID, sheetName: AdaptSheetName): void; allowDispatch(cmd: CoreCommand): CommandResult | CommandResult[]; handle(cmd: CoreCommand): void; private clearZones; /** * Set a format to all the cells in a zone */ private setFormatter; /** * Clear the styles and format of zones */ private clearFormatting; /** * Clear the styles, the format and the content of zones */ private clearCells; /** * Copy the format of the reference column/row to the new columns/rows. */ private handleAddColumnsRows; import(data: WorkbookData): void; export(data: WorkbookData): void; importCell(sheetId: UID, content?: string, format?: Format): Cell; exportForExcel(data: ExcelWorkbookData): void; getCells(sheetId: UID): Record<UID, Cell>; /** * get a cell by ID. Used in evaluation when evaluating an async cell, we need to be able to find it back after * starting an async evaluation even if it has been moved or re-allocated */ getCellById(cellId: UID): Cell | undefined; getFormulaString(sheetId: UID, tokens: Token[], dependencies: Range[], useBoundedReference?: boolean): string; getTranslatedCellFormula(sheetId: UID, offsetX: number, offsetY: number, tokens: Token[]): string; getFormulaMovedInSheet(originSheetId: UID, targetSheetId: UID, tokens: Token[]): string; /** * Converts a zone to a XC coordinate system * * The conversion also treats merges as one single cell * * Examples: * {top:0,left:0,right:0,bottom:0} ==> A1 * {top:0,left:0,right:1,bottom:1} ==> A1:B2 * * if A1:B2 is a merge: * {top:0,left:0,right:1,bottom:1} ==> A1 * {top:1,left:0,right:1,bottom:2} ==> A1:B3 * * if A1:B2 and A4:B5 are merges: * {top:1,left:0,right:1,bottom:3} ==> A1:A5 */ zoneToXC(sheetId: UID, zone: Zone, fixedParts?: RangePart[]): string; /** * Copy the format of one column to other columns. */ private copyColumnFormat; /** * Copy the format of one row to other rows. */ private copyRowFormat; /** * gets the currently used style and format of a cell based on it's coordinates */ private getFormat; private getNextUid; private updateCell; private createCell; private createLiteralCell; private createFormulaCell; /** * Create a new formula cell with the content * being a computed property to rebuild the dependencies XC. */ private createFormulaCellWithDependencies; private checkCellOutOfSheet; private checkUselessClearCell; private checkUselessUpdateCell; } interface Validator { /** * Combine multiple validation functions into a single function * returning the list of result of every validation. */ batchValidations<T>(...validations: Validation<T>[]): Validation<T>; /** * Combine multiple validation functions. Every validation is executed one after * the other. As soon as one validation fails, it stops and the cancelled reason * is returned. */ chainValidations<T>(...validations: Validation<T>[]): Validation<T>; checkValidations<T>(command: T, ...validations: Validation<T>[]): CommandResult | CommandResult[]; } /** * AbstractChart is the class from which every Chart should inherit. * The role of this class is to maintain the state of each chart. */ declare abstract class AbstractChart { readonly sheetId: UID; readonly title: TitleDesign; abstract readonly type: ChartType; protected readonly getters: CoreGetters; readonly humanize: boolean; constructor(definition: ChartDefinition, sheetId: UID, getters: CoreGetters); /** * Validate the chart definition given as arguments. This function will be * called from allowDispatch function */ static validateChartDefinition(validator: Validator, definition: ChartDefinition): CommandResult | CommandResult[]; /** * Get a new chart definition transformed with the executed command. This * functions will be called during operational transform process */ static transformDefinition(chartSheetId: UID, definition: ChartDefinition, applyChange: RangeAdapter): ChartDefinition; /** * Get an empty definition based on the given context */ static getDefinitionFromContextCreation(context: ChartCreationContext): ChartDefinition; /** * Get the definition of the chart */ abstract getDefinition(): ChartDefinition; /** * Get the definition of the chart that will be used for excel export. * If the chart is not supported by Excel, this function returns undefined. */ abstract getDefinitionForExcel(getters: CoreGetters): ExcelChartDefinition | undefined; /** * This function should be used to update all the ranges of the chart after * a grid change (add/remove col/row, rename sheet, ...) */ abstract updateRanges(rangeAdapters: RangeAdapterFunctions): AbstractChart; /** * Duplicate the chart when a sheet is duplicated. * The ranges that are in the same sheet as the chart are adapted to the new sheetId. */ abstract duplicateInDuplicatedSheet(newSheetId: UID): AbstractChart; /** * Get a copy a the chart in the given sheetId. * The ranges of the chart will stay the same as the copied chart. */ abstract copyInSheetId(sheetId: UID): AbstractChart; /** * Extract the ChartCreationContext of the chart */ abstract getContextCreation(): ChartCreationContext; protected getCommonDataSetAttributesForExcel(labelRange: Range | undefined, dataSets: DataSet[], shouldRemoveFirstLabel: boolean): { dataSets: ExcelChartDataset[]; labelRange: string | undefined; }; } interface FigureChart { figureId: UID; chart: AbstractChart; } interface ChartState { readonly charts: Record<UID, FigureChart | undefined>; } declare class ChartPlugin extends CorePlugin<ChartState> implements ChartState { static getters: readonly ["isChartDefined", "getChartDefinition", "getChartType", "getChartIds", "getChart", "getFigureIdFromChartId", "getContextCreationChart"]; readonly charts: Record<UID, FigureChart | undefined>; private createChart; private validateChartDefinition; adaptRanges(rangeAdapters: RangeAdapterFunctions): void; allowDispatch(cmd: Command): CommandResult | CommandResult[]; handle(cmd: CoreCommand): void; getContextCreationChart(chartId: UID): ChartCreationContext | undefined; getChart(chartId: UID): AbstractChart | undefined; getFigureIdFromChartId(chartId: UID): UID; getChartType(chartId: UID): ChartType; isChartDefined(chartId: UID): boolean; getChartIds(sheetId: UID): string[]; getChartDefinition(chartId: UID): ChartDefinition; import(data: WorkbookData): void; export(data: WorkbookData): void; /** * Add a figure with tag chart with the given id at the given position */ private addFigure; /** * Add a chart in the local state. If a chart already exists, this chart is * replaced */ private addChart; private checkChartDuplicate; private checkChartExists; private checkChartChanged; /** If the command is meant to create a new figure, the position & offset argument need to be defined in the command */ private checkFigureArguments; } interface ConditionalFormatState { readonly cfRules: { [sheet: string]: ConditionalFormatInternal[]; }; } declare class ConditionalFormatPlugin extends CorePlugin<ConditionalFormatState> implements ConditionalFormatState { static getters: readonly ["getConditionalFormats", "getRulesSelection", "getRulesByCell", "getAdaptedCfRanges"]; readonly cfRules: { [sheet: string]: ConditionalFormatInternal[]; }; adaptCFFormulas({ applyChange, adaptFormulaString }: RangeAdapterFunctions): void; adaptCFRanges(sheetId: UID, { applyChange }: RangeAdapterFunctions): void; adaptRanges(rangeAdapters: RangeAdapterFunctions, sheetId: UID): void; allowDispatch(cmd: Command): CommandResult | CommandResult[]; handle(cmd: CoreCommand): void; import(data: WorkbookData): void; export(data: Partial<WorkbookData>): void; exportForExcel(data: ExcelWorkbookData): void; /** * Returns all the conditional format rules defined for the current sheet to display the user */ getConditionalFormats(sheetId: UID): ConditionalFormat[]; getRulesSelection(sheetId: UID, selection: Zone[]): UID[]; getRulesByZone(sheetId: UID, zone: Zone): Set<UID>; getRulesByCell(sheetId: UID, cellCol: number, cellRow: number): Set<ConditionalFormat>; /** * Add or remove cells to a given conditional formatting rule and return the adapted CF's XCs. */ getAdaptedCfRanges(sheetId: UID, cf: ConditionalFormat, toAdd: Zone[], toRemove: Zone[]): RangeData[] | undefined; private mapToConditionalFormat; private mapToConditionalFormatInternal; /** * Add or replace a conditional format rule */ private addConditionalFormatting; private checkValidPriorityChange; private checkEmptyRange; private checkCFRule; private checkCFHasChanged; private checkOperatorArgsNumber; private checkNaN; private checkFormulaCompilation; private checkThresholds; private checkInflectionPoints; private checkLowerBiggerThanUpper; private checkMinBiggerThanMax; private checkMidBiggerThanMax; private checkMinBiggerThanMid; private checkCFValues; private removeConditionalFormatting; private changeCFPriority; } interface DataValidationRule { id: UID; criterion: DataValidationCriterion; ranges: Range[]; isBlocking?: boolean; } type TextContainsCriterion = { type: "containsText"; values: string[]; }; type TextNotContainsCriterion = { type: "notContainsText"; values: string[]; }; type TextIsCriterion = { type: "isEqualText"; values: string[]; }; type TextIsEmailCriterion = { type: "isEmail"; values: string[]; }; type TextIsLinkCriterion = { type: "isLink"; values: string[]; }; type DateIsCriterion = { type: "dateIs"; dateValue: DateCriterionValue; values: string[]; }; type DateIsBeforeCriterion = { type: "dateIsBefore"; dateValue: DateCriterionValue; values: string[]; }; type DateIsOnOrBeforeCriterion = { type: "dateIsOnOrBefore"; dateValue: DateCriterionValue; values: string[]; }; type DateIsAfterCriterion = { type: "dateIsAfter"; dateValue: DateCriterionValue; values: string[]; }; type DateIsOnOrAfterCriterion = { type: "dateIsOnOrAfter"; dateValue: DateCriterionValue; values: string[]; }; type DateIsBetweenCriterion = { type: "dateIsBetween"; values: string[]; }; type DateIsNotBetweenCriterion = { type: "dateIsNotBetween"; values: string[]; }; type DateIsValidCriterion = { type: "dateIsValid"; values: string[]; }; type IsEqualCriterion = { type: "isEqual"; values: string[]; }; type IsNotEqualCriterion = { type: "isNotEqual"; values: string[]; }; type IsGreaterThanCriterion = { type: "isGreaterThan"; values: string[]; }; type IsGreaterOrEqualToCriterion = { type: "isGreaterOrEqualTo"; values: string[]; }; type IsLessThanCriterion = { type: "isLessThan"; values: string[]; }; type IsLessOrEqualToCriterion = { type: "isLessOrEqualTo"; values: string[]; }; type IsBetweenCriterion = { type: "isBetween"; values: string[]; }; type IsNotBetweenCriterion = { type: "isNotBetween"; values: string[]; }; type IsCheckboxCriterion = { type: "isBoolean"; values: string[]; }; type IsValueInListCriterion = { type: "isValueInList"; values: string[]; colors?: Record<string, Color | undefined>; displayStyle: "arrow" | "plainText" | "chip"; }; type IsValueInRangeCriterion = { type: "isValueInRange"; values: string[]; colors?: Record<string, Color | undefined>; displayStyle: "arrow" | "plainText" | "chip"; }; type CustomFormulaCriterion = { type: "customFormula"; values: string[]; }; type DataValidationCriterion = TextContainsCriterion | TextNotContainsCriterion | TextIsCriterion | TextIsEmailCriterion | TextIsLinkCriterion | IsBetweenCriterion | DateIsCriterion | DateIsBeforeCriterion | DateIsOnOrBeforeCriterion | DateIsAfterCriterion | DateIsOnOrAfterCriterion | DateIsBetweenCriterion | DateIsNotBetweenCriterion | DateIsValidCriterion | IsEqualCriterion | IsNotEqualCriterion | IsGreaterThanCriterion | IsGreaterOrEqualToCriterion | IsLessThanCriterion | IsLessOrEqualToCriterion | IsNotBetweenCriterion | IsCheckboxCriterion | IsValueInListCriterion | IsValueInRangeCriterion | CustomFormulaCriterion; type DataValidationCriterionType = DataValidationCriterion["type"]; type DataValidationDateCriterion = Extract<DataValidationCriterion, { dateValue: DateCriterionValue; }>; declare const availableDataValidationOperators: Set<DataValidationCriterionType>; interface DataValidationState { readonly rules: { [sheet: string]: DataValidationRule[]; }; } declare class DataValidationPlugin extends CorePlugin<DataValidationState> implements DataValidationState { static getters: readonly ["cellHasListDataValidationIcon", "getDataValidationRule", "getDataValidationRules", "getValidationRuleForCell"]; readonly rules: { [sheet: string]: DataValidationRule[]; }; adaptRanges(rangeAdapters: RangeAdapterFunctions, sheetId: UID): void; private adaptDVFormulas; private adaptDVRanges; allowDispatch(cmd: Command): CommandResult | CommandResult[]; handle(cmd: CoreCommand): void; getDataValidationRules(sheetId: UID): DataValidationRule[]; getDataValidationRule(sheetId: UID, id: UID): DataValidationRule | undefined; getValidationRuleForCell({ sheetId, col, row }: CellPosition): DataValidationRule | undefined; cellHasListDataValidationIcon(cellPosition: CellPosition): boolean; private addDataValidationRule; private removeRangesFromRules; private removeDataValidationRule; private setCenterStyleToBooleanCells; private checkEmptyRange; import(data: WorkbookData): void; export(data: Partial<WorkbookData>): void; exportForExcel(data: ExcelWorkbookData): void; private checkCriterionTypeIsValid; private checkCriterionHasValidNumberOfValues; private checkCriterionValuesAreValid; private checkValidRange; } interface FigureState { readonly figures: { [sheet: string]: Record<UID, Figure | undefined> | undefined; }; readonly insertionOrders: UID[]; } declare class FigurePlugin extends CorePlugin<FigureState> implements FigureState { static getters: readonly ["getFigures", "getFigure", "getFigureSheetId"]; readonly figures: { [sheet: string]: Record<UID, Figure | undefined> | undefined; }; readonly insertionOrders: UID[]; adaptRanges({ applyChange }: RangeAdapterFunctions, sheetId: UID): void; allowDispatch(cmd: CoreCommand): CommandResult | CommandResult[]; beforeHandle(cmd: CoreCommand): void; handle(cmd: CoreCommand): void; private onColRemove; private onRowRemove; private getPositionInSheet; private updateFigure; private addFigure; private deleteSheet; private removeFigure; private checkFigureExists; private checkFigureDuplicate; private checkFigureAnchorOffset; getFigures(sheetId: UID): Figure[]; getFigure(sheetId: UID, figureId: string): Figure | undefined; getFigureSheetId(figureId: string): UID | undefined; import(data: WorkbookData): void; export(data: WorkbookData): void; exportForExcel(data: ExcelWorkbookData): void; } interface State$6 { groups: Record<UID, Record<Dimension, HeaderGroup[]>>; } declare class HeaderGroupingPlugin extends CorePlugin<State$6> { static getters: readonly ["getHeaderGroups", "getGroupsLayers", "getVisibleGroupLayers", "getHeaderGroup", "getHeaderGroupsInZone", "isGroupFolded", "isRowFolded", "isColFolded"]; private readonly groups; allowDispatch(cmd: CoreCommand): CommandResult; handle(cmd: CoreCommand): void; getHeaderGroups(sheetId: UID, dim: Dimension): HeaderGroup[]; getHeaderGroup(sheetId: UID, dim: Dimension, start: number, end: number): HeaderGroup | undefined; getHeaderGroupsInZone(sheetId: UID, dim: Dimension, zone: Zone): HeaderGroup[]; /** * Get all the groups of a sheet in a dimension, and return an array of layers of those groups. * * The layering rules are: * 1) A group containing another group should be on a layer above the group it contains * 2) The widest/highest groups should be on the left/top layer compared to the groups it contains * 3) The group should be on the left/top-most layer possible, barring intersections with other groups (see rules 1 and 2) */ getGroupsLayers(sheetId: UID, dimension: Dimension): HeaderGroup[][]; /** * Get all the groups of a sheet in a dimension, and return an array of layers of those groups, * excluding the groups that are totally hidden. */ getVisibleGroupLayers(sheetId: UID, dimension: Dimension): HeaderGroup[][]; isGroupFolded(sheetId: UID, dimension: Dimension, start: number, end: number): boolean; isRowFolded(sheetId: UID, row: HeaderIndex): boolean; isColFolded(sheetId: UID, col: HeaderIndex): boolean; private getGroupId; /** * To get layers of groups, and to add/remove headers from groups, we can see each header of a group as a brick. Each * brick falls down in the pile corresponding to its header, until it hits another brick, or the ground. * * With this abstraction, we can very simply group/ungroup headers from groups, and get the layers of groups. * - grouping headers is done by adding a brick to each header pile * - un-grouping headers is done by removing a brick from each header pile * - getting the layers of groups is done by simply letting the brick fall and checking the result * * Example: * We have 2 groups ([A=>E] and [C=>D]), and we want to group headers [C=>F] * * Headers : A B C D E F G A B C D E F G A B C D E F G * Headers to group: [C=>D]: _ _ [C=>F]: _ _ _ _ * | | ==> | | | | ==> ==> Result: 3 groups * | | ˅ ˅ | | _ _ - [C=>D] * Groups: ˅ ˅ _ _ ˅ | _ _ _ - [C=>E] * Groups: _ _ _ _ _ _ _ _ _ _ ˅ _ _ _ _ _ _ - [A=>F] * @param groups * @param start start of the range where to add/remove headers * @param end end of the range where to add/remove headers * @param delta -1: remove headers, 1: add headers, 0: get layers (don't add/remove anything) */ private bricksFallingAlgorithm; private groupHeaders; /** * Ungroup the given headers. The headers will be taken out of the group they are in. This might split a group into two * if the headers were in the middle of a group. If multiple groups contains a header, it will only be taken out of the * lowest group in the layering of the groups. */ private unGroupHeaders; private moveGroupsOnHeaderInsertion; private moveGroupsOnHeaderDeletion; private doGroupOverlap; private removeDuplicateGroups; private findGroupWithStartEnd; /** * Fold the given group, and all the groups starting at the same index that are contained inside the given group. */ private foldHeaderGroup; /** * Unfold the given group, and all the groups starting at the same index that contain the given group. */ private unfoldHeaderGroup; private getGroupIndex; import(data: WorkbookData): void; export(data: WorkbookData): void; exportForExcel(data: ExcelWorkbookData): void; } interface HeaderSizeState$1 { sizes: Record<UID, Record<Dimension, Array<Pixel | undefined>>>; } declare class HeaderSizePlugin extends CorePlugin<HeaderSizeState$1> implements HeaderSizeState$1 { static getters: readonly ["getUserRowSize", "getColSize"]; readonly sizes: Record<UID, Record<Dimension, Array<Pixel | undefined>>>; handle(cmd: Command): void; getColSize(sheetId: UID, index: HeaderIndex): Pixel; getUserRowSize(sheetId: UID, index: HeaderIndex): Pixel | undefined; import(data: WorkbookData): void; exportForExcel(data: ExcelWorkbookData): void; export(data: WorkbookData): void; /** * Export the header sizes * * @param exportDefaults : if true, export column/row sizes even if they have the default size */ exportData(data: WorkbookData, exportDefaults?: boolean): void; } declare class HeaderVisibilityPlugin extends CorePlugin { static getters: readonly ["checkElementsIncludeAllVisibleHeaders", "getHiddenColsGroups", "getHiddenRowsGroups", "isHeaderHiddenByUser", "isRowHiddenByUser", "isColHiddenByUser"]; private readonly hiddenHeaders; allowDispatch(cmd: Command): CommandResult.Success | CommandResult.NotEnoughElements | CommandResult.InvalidSheetId | CommandResult.TooManyHiddenElements | CommandResult.InvalidHeaderIndex; handle(cmd: Command): void; checkElementsIncludeAllVisibleHeaders(sheetId: UID, dimension: Dimension, elements: HeaderIndex[]): boolean; isHeaderHiddenByUser(sheetId: UID, dimension: Dimension, index: HeaderIndex): boolean; isRowHiddenByUser(sheetId: UID, index: HeaderIndex): boolean; isColHiddenByUser(sheetId: UID, index: HeaderIndex): boolean; getHiddenColsGroups(sheetId: UID): ConsecutiveIndexes[]; getHiddenRowsGroups(sheetId: UID): ConsecutiveIndexes[]; private getAllVisibleHeaders; import(data: WorkbookData): void; exportForExcel(data: ExcelWorkbookData): void; export(data: WorkbookData): void; exportData(data: WorkbookData, exportDefaults?: boolean): void; } type FilePath = string; /** * FileStore manage the transfer of file with the server. */ interface FileStore { /** * Upload a file to a server and returns its path. */ upload(file: File): Promise<FilePath>; /** * get File from the server */ getFile(filePath: FilePath): Promise<File | Blob>; } /** * ImageProvider can request the user to input an image file before sending it to a server. */ interface ImageProviderInterface { /** * RequestImage ask the user to input an image file. Then send it to a server trough an FileStore. Finally it return the path and the size of the image in the server. */ requestImage(): Promise<Image>; uploadFile(file: File | Blob): Promise<Image>; getImageOriginalSize(path: string): Promise<FigureSize>; } interface ImageState { readonly images: Record<UID, Record<UID, Image | undefined> | undefined>; } declare class ImagePlugin extends CorePlugin<ImageState> implements ImageState { static getters: readonly ["getImage", "getImagePath", "getImageSize"]; readonly fileStore?: FileStore; readonly images: Record<UID, Record<UID, Image | undefined> | undefined>; /** * paths of images synced with the file store server. */ readonly syncedImages: Set<Image["path"]>; constructor(config: CorePluginConfig); allowDispatch(cmd: CoreCommand): CommandResult.Success | CommandResult.InvalidFigureId; handle(cmd: CoreCommand): void; getImage(figureId: UID): Image; getImagePath(figureId: UID): string; getImageSize(figureId: UID): FigureSize; private addFigure; import(data: WorkbookData): void; export(data: WorkbookData): void; exportForExcel(data: ExcelWorkbookData): void; } type SheetMergeCellMap = Record<number, Record<number, number | undefined> | undefined>; interface MergeState { readonly merges: Record<UID, Record<number, Range | undefined> | undefined>; readonly mergeCellMap: Record<UID, SheetMergeCellMap | undefined>; } declare class MergePlugin extends CorePlugin<MergeState> implements MergeState { static getters: readonly ["isInMerge", "isInSameMerge", "isMergeHidden", "getMainCellPosition", "expandZone", "doesIntersectMerge", "doesColumnsHaveCommonMerges", "doesRowsHaveCommonMerges", "getMerges", "getMerge", "getMergesInZone", "isSingleCellOrMerge", "getSelectionRangeString", "isMainCellPosition"]; private nextId; readonly merges: Record<UID, Record<number, Range | undefined> | undefined>; readonly mergeCellMap: Record<UID, SheetMergeCellMap | undefined>; allowDispatch(cmd: CoreCommand): CommandResult | CommandResult[];