adaptive-expressions
Version:
Common Expression Language
232 lines (223 loc) • 10.6 kB
text/typescript
/**
* @module adaptive-expressions
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import * as BuiltinFunctions from './builtinFunctions';
import { ExpressionEvaluator } from './expressionEvaluator';
import { ExpressionType } from './expressionType';
/**
* <summary>
* Definition of default built-in functions for expressions.
* </summary>
* <remarks>
* These functions are largely from WDL https://docs.microsoft.com/en-us/azure/logic-apps/workflow-definition-language-functions-reference
* with a few extensions like infix operators for math, logic and comparisons.
* This class also has some methods that are useful to use when defining custom functions.
* You can always construct a <see cref="ExpressionEvaluator"/> directly which gives the maximum amount of control over validation and evaluation.
* Validators are static checkers that should throw an exception if something is not valid statically.
* Evaluators are called to evaluate an expression and should try not to throw.
* There are some evaluators in this file that take in a verifier that is called at runtime to verify arguments are proper.
* </remarks>
*/
export class ExpressionFunctions {
/**
* Read only Dictionary of built in functions.
*/
static readonly standardFunctions: ReadonlyMap<string, ExpressionEvaluator> =
ExpressionFunctions.getStandardFunctions();
/**
* @private
*/
private static getStandardFunctions(): ReadonlyMap<string, ExpressionEvaluator> {
const functions: ExpressionEvaluator[] = [
new BuiltinFunctions.Abs(),
new BuiltinFunctions.Accessor(),
new BuiltinFunctions.Add(),
new BuiltinFunctions.AddDays(),
new BuiltinFunctions.AddHours(),
new BuiltinFunctions.AddMinutes(),
new BuiltinFunctions.AddOrdinal(),
new BuiltinFunctions.AddProperty(),
new BuiltinFunctions.AddSeconds(),
new BuiltinFunctions.AddToTime(),
new BuiltinFunctions.All(),
new BuiltinFunctions.And(),
new BuiltinFunctions.Any(),
new BuiltinFunctions.Average(),
new BuiltinFunctions.Base64(),
new BuiltinFunctions.Base64ToBinary(),
new BuiltinFunctions.Base64ToString(),
new BuiltinFunctions.Binary(),
new BuiltinFunctions.Bool(),
new BuiltinFunctions.Ceiling(),
new BuiltinFunctions.Coalesce(),
new BuiltinFunctions.Concat(),
new BuiltinFunctions.Contains(),
new BuiltinFunctions.ConvertFromUTC(),
new BuiltinFunctions.ConvertToUTC(),
new BuiltinFunctions.Count(),
new BuiltinFunctions.CountWord(),
new BuiltinFunctions.CreateArray(),
new BuiltinFunctions.DataUri(),
new BuiltinFunctions.DataUriToBinary(),
new BuiltinFunctions.DataUriToString(),
new BuiltinFunctions.DateFunc(),
new BuiltinFunctions.DateReadBack(),
new BuiltinFunctions.DateTimeDiff(),
new BuiltinFunctions.DayOfMonth(),
new BuiltinFunctions.DayOfWeek(),
new BuiltinFunctions.DayOfYear(),
new BuiltinFunctions.Divide(),
new BuiltinFunctions.Element(),
new BuiltinFunctions.Empty(),
new BuiltinFunctions.EndsWith(),
new BuiltinFunctions.EOL(),
new BuiltinFunctions.Equal(),
new BuiltinFunctions.Exists(),
new BuiltinFunctions.Flatten(),
new BuiltinFunctions.First(),
new BuiltinFunctions.Float(),
new BuiltinFunctions.Floor(),
new BuiltinFunctions.Foreach(),
new BuiltinFunctions.FormatDateTime(),
new BuiltinFunctions.FormatEpoch(),
new BuiltinFunctions.FormatNumber(),
new BuiltinFunctions.FormatTicks(),
new BuiltinFunctions.GetFutureTime(),
new BuiltinFunctions.GetNextViableDate(),
new BuiltinFunctions.GetNextViableTime(),
new BuiltinFunctions.GetPastTime(),
new BuiltinFunctions.GetPreviousViableDate(),
new BuiltinFunctions.GetPreviousViableTime(),
new BuiltinFunctions.GetPastTime(),
new BuiltinFunctions.GetProperty(),
new BuiltinFunctions.GetTimeOfDay(),
new BuiltinFunctions.GreaterThan(),
new BuiltinFunctions.GreaterThanOrEqual(),
new BuiltinFunctions.If(),
new BuiltinFunctions.Ignore(),
new BuiltinFunctions.IndexOf(),
new BuiltinFunctions.IndicesAndValues(),
new BuiltinFunctions.Int(),
new BuiltinFunctions.Intersection(),
new BuiltinFunctions.IsArray(),
new BuiltinFunctions.IsBoolean(),
new BuiltinFunctions.IsDate(),
new BuiltinFunctions.IsDateRange(),
new BuiltinFunctions.IsDateTime(),
new BuiltinFunctions.IsDefinite(),
new BuiltinFunctions.IsDuration(),
new BuiltinFunctions.IsFloat(),
new BuiltinFunctions.IsInteger(),
new BuiltinFunctions.IsMatch(),
new BuiltinFunctions.IsObject(),
new BuiltinFunctions.IsPresent(),
new BuiltinFunctions.IsString(),
new BuiltinFunctions.IsTime(),
new BuiltinFunctions.IsTimeRange(),
new BuiltinFunctions.Join(),
new BuiltinFunctions.JPath(),
new BuiltinFunctions.Json(),
new BuiltinFunctions.JsonStringify(),
new BuiltinFunctions.Last(),
new BuiltinFunctions.LastIndexOf(),
new BuiltinFunctions.Length(),
new BuiltinFunctions.LessThan(),
new BuiltinFunctions.LessThanOrEqual(),
new BuiltinFunctions.Max(),
new BuiltinFunctions.Merge(),
new BuiltinFunctions.Min(),
new BuiltinFunctions.Mod(),
new BuiltinFunctions.Month(),
new BuiltinFunctions.Multiply(),
new BuiltinFunctions.NewGuid(),
new BuiltinFunctions.Not(),
new BuiltinFunctions.NotEqual(),
new BuiltinFunctions.Optional(),
new BuiltinFunctions.Or(),
new BuiltinFunctions.Power(),
new BuiltinFunctions.Rand(),
new BuiltinFunctions.Range(),
new BuiltinFunctions.RemoveProperty(),
new BuiltinFunctions.Replace(),
new BuiltinFunctions.ReplaceIgnoreCase(),
new BuiltinFunctions.Reverse(),
new BuiltinFunctions.Round(),
new BuiltinFunctions.Select(),
new BuiltinFunctions.SentenceCase(),
new BuiltinFunctions.SetPathToValue(),
new BuiltinFunctions.SetProperty(),
new BuiltinFunctions.Skip(),
new BuiltinFunctions.SortBy(),
new BuiltinFunctions.SortByDescending(),
new BuiltinFunctions.Split(),
new BuiltinFunctions.Sqrt(),
new BuiltinFunctions.StartOfDay(),
new BuiltinFunctions.StartOfHour(),
new BuiltinFunctions.StartOfMonth(),
new BuiltinFunctions.StartsWith(),
new BuiltinFunctions.String(),
new BuiltinFunctions.StringOrValue(),
new BuiltinFunctions.SubArray(),
new BuiltinFunctions.Substring(),
new BuiltinFunctions.Subtract(),
new BuiltinFunctions.SubtractFromTime(),
new BuiltinFunctions.Sum(),
new BuiltinFunctions.Take(),
new BuiltinFunctions.Ticks(),
new BuiltinFunctions.TicksToDays(),
new BuiltinFunctions.TicksToHours(),
new BuiltinFunctions.TicksToMinutes(),
new BuiltinFunctions.TimexResolve(),
new BuiltinFunctions.TitleCase(),
new BuiltinFunctions.ToLower(),
new BuiltinFunctions.ToUpper(),
new BuiltinFunctions.Trim(),
new BuiltinFunctions.Union(),
new BuiltinFunctions.Unique(),
new BuiltinFunctions.UriComponent(),
new BuiltinFunctions.UriComponentToString(),
new BuiltinFunctions.UriHost(),
new BuiltinFunctions.UriPath(),
new BuiltinFunctions.UriPathAndQuery(),
new BuiltinFunctions.UriPort(),
new BuiltinFunctions.UriQuery(),
new BuiltinFunctions.UriScheme(),
new BuiltinFunctions.UtcNow(),
new BuiltinFunctions.Where(),
new BuiltinFunctions.XML(),
new BuiltinFunctions.XPath(),
new BuiltinFunctions.Year(),
];
const lookup: Map<string, ExpressionEvaluator> = new Map<string, ExpressionEvaluator>();
functions.forEach((func: ExpressionEvaluator): void => {
lookup.set(func.type, func);
});
// Attach negations
lookup.get(ExpressionType.LessThan).negation = lookup.get(ExpressionType.GreaterThanOrEqual);
lookup.get(ExpressionType.LessThanOrEqual).negation = lookup.get(ExpressionType.GreaterThan);
lookup.get(ExpressionType.Equal).negation = lookup.get(ExpressionType.NotEqual);
// Math aliases
lookup.set('add', lookup.get(ExpressionType.Add)); // more than 1 param
lookup.set('mul', lookup.get(ExpressionType.Multiply)); // more than 1 param
lookup.set('div', lookup.get(ExpressionType.Divide)); // more than 1 param
lookup.set('sub', lookup.get(ExpressionType.Subtract)); // more than 1 param
lookup.set('exp', lookup.get(ExpressionType.Power)); // more than 1 param
lookup.set('mod', lookup.get(ExpressionType.Mod));
// Comparison aliases
lookup.set('and', lookup.get(ExpressionType.And));
lookup.set('equals', lookup.get(ExpressionType.Equal));
lookup.set('greater', lookup.get(ExpressionType.GreaterThan));
lookup.set('greaterOrEquals', lookup.get(ExpressionType.GreaterThanOrEqual));
lookup.set('less', lookup.get(ExpressionType.LessThan));
lookup.set('lessOrEquals', lookup.get(ExpressionType.LessThanOrEqual));
lookup.set('not', lookup.get(ExpressionType.Not));
lookup.set('or', lookup.get(ExpressionType.Or));
lookup.set('&', lookup.get(ExpressionType.Concat));
lookup.set('??', lookup.get(ExpressionType.Coalesce));
return lookup as ReadonlyMap<string, ExpressionEvaluator>;
}
}