Quick Start
How to add a new formula
In this section, we will take the example of adding a new formula - IS_ODD, and learn how to quickly add a custom formula.
The main function of the IS_ODD formula is to identify whether the specified number is an odd number.
Add IS_ODD formula class
Since the formula IS_ODD returns a Boolean type, you can inherit directly from the base class LogicalFunc and implement the basic methods of the formula, as follows:
// FilePath: "apitable/packages/core/src/formula_parser/functions/logical.ts"
export class IsOdd extends LogicalFunc {
static override acceptValueType = new Set([BasicValueType.Number]);
static override validateParams(params: AstNode[]) {
if (params.length < 1) {
throw new ParamsCountError(ParamsErrorType.AtLeastCount, 'IS_ODD', 1);
}
}
static override getReturnType(params?: AstNode[]) {
params && this.validateParams(params);
return BasicValueType.Boolean;
}
static override func(params: [IFormulaParam<number>]): boolean | null {
const [{ value: num }] = params;
if (num == null || typeof num !== 'number') {
return null;
}
return num % 2 !== 0;
}
}Add IS_ODD formula definition
The list of formulas on the front and back ends will be read according to the following list:
// FilePath: "apitable/packages/core/src/formula_parser/functions/index.ts"
export const Functions = new Map<string, IFunction>([
// ...
['IS_ODD', {
name: 'IS_ODD',
func: logical.IsOdd,
definition: 'IS_ODD(number)',
summary: t(Strings.function_isodd_summary), // 新增 function_isodd_summary key
example: t(Strings.function_isodd_example), // 新增 function_isodd_example key
}],
])Add unit test for IS_ODD formula
To ensure that formula-related changes do not affect the results of the formula runs, unit tests need to be written for each formula, as follows:
// FilePath: "apitable/packages/core/src/formula_parser/__tests__/logical.test.ts"
it('IS_ODD', () => {
expect(evaluate(
'IS_ODD({a})',
mergeContext({ a: 1, b: 2, c: 1591414562369, d: ['opt1'] }),
)).toEqual(true);
expect(evaluate(
'IS_ODD({b})',
mergeContext({ a: 1, b: 2, c: 1591414562369, d: ['opt1'] }),
)).toEqual(false);
expect(evaluate(
'IS_ODD({a})',
mergeContext({ a: 'abc', b: 1, c: 1591414562369, d: ['opt1'] }),
)).toEqual(null);
expect(evaluate(
'IS_ODD({a}, {b})',
mergeContext({ a: -2, b: 1, c: 1591414562369, d: ['opt1'] }),
)).toEqual(true);
expect(() => evaluate(
'IS_ODD()',
mergeContext({ a: 1, b: 2, c: 1591414562369, d: ['opt1'] }),
)).toThrow(ParamsCountError);
});