packages/@alicloud/ros-cdk-core/lib/ros-fn.ts (432 lines of code) (raw):
import { IRosConditionExpression } from "./ros-condition";
import {minimalRosTemplateJoin, minimalRosTemplateListMerge} from "./private/template-lang";
import { Intrinsic } from "./private/intrinsic";
import { Reference } from "./reference";
import { Token } from "./token";
import { captureStackTrace } from "./stack-trace";
import { IResolveContext, IResolvable } from "./resolvable";
import * as ros from "./index";
// tslint:disable:max-line-length
/**
* Resource Orchestration Service intrinsic functions.
* https://help.aliyun.com/zh/ros/user-guide/functions
*/
export class Fn {
public static str(value: any): string {
// if (!Token.isUnresolved(value)) {
// return value.toString();
// }
return new FnStr(value).toString();
}
public static base64Decode(data: string): string {
return new FnBase64Decode(data).toString();
}
public static replace(
replaceData: { [key: string]: any },
content: string
): string {
return new FnReplace([replaceData, content]).toString();
}
public static listMerge(valueList: (any[] | ros.IResolvable)[]): IResolvable {
return new FnListMerge(valueList);
}
public static getJsonValue(key: string, jsonData: any): string {
return new FnGetJsonValue([key, jsonData]).toString();
}
public static avg(ndigits: number, values: number[]): number {
return Token.asNumber(new FnAvg([ndigits, values]));
}
public static add(values: number | any[] | {[key:string]: any}): IResolvable {
return Token.asAny(new FnAdd(values));
}
public static calculate(
values: string,
ndigits: number,
para: number[]
): number {
return Token.asNumber(new FnCalculate([values, ndigits, para]));
}
public static max(values: number[]): number {
return Token.asNumber(new FnMax(values));
}
public static min(values: number[]): number {
return Token.asNumber(new FnMin(values));
}
public static jq(method: string, script: string, inputString: string | {[key:string]: any}): IResolvable {
return Token.asAny(new FnJq([method, script, inputString]));
}
public static mergeMapToList(mapList: {[key: string]: any[]}[]): IResolvable {
return new FnMergeMapToList(mapList);
}
public static selectMapList(key: string, mapList: {[key: string]: any}[]): IResolvable {
return new FnSelectMapList([key, mapList]);
}
/**
* The ``Ref`` intrinsic function returns the value of the specified parameter or resource.
* Note that it doesn't validate the logicalName, it mainly serves paremeter/resource reference defined in a ``RosInclude`` template.
* @param logicalName The logical name of a parameter/resource for which you want to retrieve its value.
*/
public static ref(logicalName: string): string {
return new FnRef(logicalName).toString();
}
/** @internal */
public static _ref(logicalId: string): IResolvable {
return new FnRef(logicalId);
}
/**
* The ``Fn::GetAtt`` intrinsic function returns the value of an attribute
* from a resource in the template.
* @param logicalNameOfResource The logical name (also called logical ID) of
* the resource that contains the attribute that you want.
* @param attributeName The name of the resource-specific attribute whose
* value you want. See the resource's reference page for details about the
* attributes available for that resource type.
* @returns an IResolvable object
*/
public static getAtt(
logicalNameOfResource: string,
attributeName: string
): IResolvable {
return new FnGetAtt(logicalNameOfResource, attributeName);
}
/**
* The intrinsic function ``Fn::Join`` appends a set of values into a single
* value, separated by the specified delimiter. If a delimiter is the empty
* string, the set of values are concatenated with no delimiter.
* @param delimiter The value you want to occur between fragments. The
* delimiter will occur between fragments only. It will not terminate the
* final value.
* @param listOfValues The list of values you want combined.
* @returns a token represented as a string
*/
public static join(delimiter: string, listOfValues: (string | ros.IResolvable)[]): string {
if (listOfValues.length === 0) {
throw new Error("FnJoin requires at least one value to be provided");
}
return new FnJoin(delimiter, listOfValues).toString();
}
/**
* To split a string into a list of string values so that you can select an element from the
* resulting string list, use the ``Fn::Split`` intrinsic function. Specify the location of splits
* with a delimiter, such as , (a comma). After you split a string, use the ``Fn::Select`` function
* to pick a specific element.
* @param delimiter A string value that determines where the source string is divided.
* @param source The string value that you want to split.
* @returns a token represented as a string array
*/
public static split(delimiter: string, source: string): string[] {
// short-circut if source is not a token
if (!Token.isUnresolved(source)) {
return source.split(delimiter);
}
return Token.asList(new FnSplit([delimiter, source]));
}
/**
* The intrinsic function ``Fn::Select`` returns a single object from a list of objects by index.
* @param index The index of the object to retrieve. This must be a value from zero to N-1, where N represents the number of elements in the array.
* @param array The list of objects to select from. This list must not be null, nor can it have null entries.
* @returns a token represented as a string
*/
public static select(index: number | string, array: any): IResolvable {
return Token.asAny(new FnSelect([index, array]));
}
/**
* The intrinsic function ``Fn::Sub`` substitutes variables in an input string
* with values that you specify. In your templates, you can use this function
* to construct commands or outputs that include values that aren't available
* until you create or update a stack.
* @param body A string with variables that Ros Template substitutes
* with their associated values at runtime. Write variables as ${MyVarName}.
* Variables can be template parameter names, resource logical IDs, resource
* attributes, or a variable in a key-value map. If you specify only template
* parameter names, resource logical IDs, and resource attributes, don't
* specify a key-value map.
* @param variables The name of a variable that you included in the String
* parameter. The value that Ros Template substitutes for the associated
* variable name at runtime.
* @returns a token represented as a string
*/
public static sub(
body: string,
variables?: { [key: string]: any }
): string {
if (variables === undefined) {
return new FnSub(body).toString();
}
return new FnSub([body, variables]).toString();
}
/**
* The intrinsic function ``Fn::Base64`` returns the Base64 representation of
* the input string.
* @param data The string value you want to convert to Base64.
* @returns a token represented as a string
*/
public static base64Encode(data: string): string {
return new FnBase64Encode(data).toString();
}
/**
* The intrinsic function ``Fn::GetAZs`` returns an array that lists
* Availability Zones for a specified region. Because customers have access to
* different Availability Zones, the intrinsic function ``Fn::GetAZs`` enables
* template authors to write templates that adapt to the calling user's
* access. That way you don't have to hard-code a full list of Availability
* Zones for a specified region.
* @param region The name of the region for which you want to get the
* Availability Zones. You can use the ROS::Region pseudo parameter to specify
* the region in which the stack is created. Specifying an empty string is
* equivalent to specifying ROS::Region.
* @returns a token represented as a string array
*/
public static getAzs(region: string): string[] {
return Token.asList(new FnGetAZs(region));
}
/**
* The intrinsic function ``Fn::GetStackOutput`` returns the value of an output
* exported by another stack.
* @returns a token represented as a string
*/
public static getStackOutput(
stackID: string,
outputKey: string,
stackRegion?: string
): IResolvable {
return Token.asAny(new FnGetStackOutput([stackID, outputKey, stackRegion]));
}
/**
* The intrinsic function ``Fn::FindInMap`` returns the value corresponding to
* keys in a two-level map that is declared in the Mappings section.
* @returns a token represented as a string
*/
public static findInMap(
mapName: string,
topLevelKey: string,
secondLevelKey: string
): IResolvable {
return Token.asAny(new FnFindInMap([mapName, topLevelKey, secondLevelKey]));
}
/**
* Returns true if all the specified conditions evaluate to true, or returns
* false if any one of the conditions evaluates to false. ``Fn::And`` acts as
* an AND operator. The minimum number of conditions that you can include is
* 2, and the maximum is 10.
* @param conditions conditions to AND
* @returns an FnCondition token
*/
public static conditionAnd(
...conditions: (string | IRosConditionExpression)[]
): IRosConditionExpression {
return new FnAnd(...conditions);
}
/**
* Compares if two values are equal. Returns true if the two values are equal
* or false if they aren't.
* @param lhs A value of any type that you want to compare.
* @param rhs A value of any type that you want to compare.
* @returns an FnCondition token
*/
public static conditionEquals(lhs: any, rhs: any): IRosConditionExpression {
return new FnEquals(lhs, rhs);
}
/**
* Returns one value if the specified condition evaluates to true and another
* value if the specified condition evaluates to false.
* @param conditionId A reference to a condition in the Conditions section. Use
* the condition's name to reference it.
* @param valueIfTrue A value to be returned if the specified condition
* evaluates to true.
* @param valueIfFalse A value to be returned if the specified condition
* evaluates to false.
* @returns an FnCondition token
*/
public static conditionIf(
conditionId: string | IRosConditionExpression,
valueIfTrue: any,
valueIfFalse: any
): any {
return new FnIf(conditionId, valueIfTrue, valueIfFalse);
}
/**
* Returns true for a condition that evaluates to false or returns false for a
* condition that evaluates to true. ``Fn::Not`` acts as a NOT operator.
* @param condition A condition such as ``Fn::Equals`` that evaluates to true
* or false.
* @returns an FnCondition token
*/
public static conditionNot(
condition: string | IRosConditionExpression
): IRosConditionExpression {
return new FnNot(condition);
}
/**
* Returns true if any one of the specified conditions evaluate to true, or
* returns false if all of the conditions evaluates to false. ``Fn::Or`` acts
* as an OR operator. The minimum number of conditions that you can include is
* 2, and the maximum is 10.
* @param conditions conditions that evaluates to true or false.
* @returns an FnCondition token
*/
public static conditionOr(
...conditions: (string | IRosConditionExpression)[]
): IRosConditionExpression {
return new FnOr(...conditions);
}
/**
* The intrinsic function Fn::Indent adjust the indentation of the string.
* @param str Strings that need to be indented.
* @param level Indentation level. The range is [0,20].
* @param indent Optional, defaults to 2 for two Spaces per level, in the range [0,4].
*/
public static indent(str: string | ros.IResolvable, level: number | ros.IResolvable, indent?: number | ros.IResolvable): string {
return new FnIndent(str, level, indent).toString();
}
/**
* Returns the index of the item in the list.
* @param itemToFindIndex The item to find in the list.
* @param itemList The list to find the item in.
*/
public static index(itemToFindIndex: any, itemList: any[] | ros.IResolvable): string {
return new FnIndex(itemToFindIndex, itemList).toString();
}
/**
* Returns the length of the object.
* @param obj An object whose length needs to be computed. Three types are supported: strings, lists, and dictionaries.
*/
public static lengthOf(obj: any): string {
return new FnLength(obj).toString();
}
/**
* Returns the formatted time of the object.
* @param format The format of the time.
* @param timeZone The time zone.
*/
public static formatTime(format: string | ros.IResolvable, timeZone: string | ros.IResolvable): string {
return new FnFormatTime(format, timeZone).toString();
}
/**
* The intrinsic function Fn::MarketplaceImage returns the default image ID of the specified cloud marketplace image product Code.
* @param imageProductCode The product code of the cloud marketplace image.
*/
public static marketplaceImage(imageProductCode: string | ros.IResolvable): string {
return new FnMarketplaceImage(imageProductCode).toString();
}
/**
* Returns whether a value in the specified array is true or false. Returns true if any item in the array is true, and false otherwise.
* @param values An array of values.
*/
public static any(values: any[] | ros.IResolvable): string {
return new FnAny(values).toString();
}
/**
* Returns true if at least one member of the list matches the specified value and false otherwise.
* @param values An array of values.
* @param value A value.
*/
public static contains(values: any[] | ros.IResolvable, value: any): string {
return new FnContains(values, value).toString();
}
/**
* Returns true if every member of the first list is equal to at least one value in the second list, and false otherwise.
* @param values1 An array of values.
* @param values2 An array of values.
*/
public static eachMemberIn(values1: any[] | ros.IResolvable, values2: any[] | ros.IResolvable): string {
return new FnEachMemberIn(values1, values2).toString();
}
/**
* Returns true if a specified string matches a specified pattern.
* @param pattern A regular expression in string form.
* @param value The string to match.
*/
public static matchPattern(pattern: string | ros.IResolvable, value: string | ros.IResolvable): string {
return new FnMatchPattern(pattern, value).toString();
}
/**
* Returns a list of CIDR addresses.
* @param ipBlock The IP address block from which you want to allocate the CIDR. The block must be expressed in CIDR notation.
* @param count The number of IPv4 CIDRs to generate. Valid input values range from 1 to 256 and are used to decide the total number of final subnets.
* @param cidrBits The number of subnet bits of the new CIDR. For example, if the value "8" is specified for this parameter, a CIDR with a "/24" mask will be created.
*/
public static cidr(ipBlock: string | ros.IResolvable, count: number | ros.IResolvable, cidrBits: number | ros.IResolvable): string {
return new FnCidr(ipBlock, count, cidrBits).toString();
}
/**
* Returns true if a specified string matches all values in a list.
* param listOfStrings A list of strings, such as "A", "B", "C".
* param value A string, such as "A", that you want to compare against a list
* of strings.
* @returns an FnCondition token
*/
// static conditionEachMemberEquals(
// listOfStrings: string[],
// value: string
// ): IRosConditionExpression {
// return new FnEachMemberEquals(listOfStrings, value);
// }
private constructor() {}
}
/**
* Base class for tokens that represent ROS intrinsic functions.
*/
class FnBase extends Intrinsic {
constructor(name: string, value: any) {
super({ [name]: value });
}
}
export class FnIndent extends FnBase {
/**
* Creates an ``Indent`` function.
*/
constructor(str: string | ros.IResolvable, level: number | ros.IResolvable, indent?: number | ros.IResolvable) {
if (typeof level === 'number' && (level < 0 || level > 20)) {
throw new Error("level must be greater than 0 or less than 20");
}
if (indent && typeof level === 'number' && (indent < 0 || indent > 4)) {
throw new Error("indent must be greater than 0 or less than 4");
}
super("Fn::Indent", [str, level, indent]);
}
}
export class FnIndex extends FnBase {
/**
* Creates an ``Index`` function.
*/
constructor(itemToFindIndex: any, itemList: any[] | ros.IResolvable) {
super("Fn::Index", [itemToFindIndex, itemList]);
}
}
export class FnLength extends FnBase {
/**
* Creates an ``Length`` function.
*/
constructor(obj: any) {
super("Fn::Length", obj);
}
}
export class FnFormatTime extends FnBase {
/**
* Creates an ``FormatTime`` function.
*/
constructor(format: string | ros.IResolvable, timeZone: string | ros.IResolvable) {
super("Fn::FormatTime", [format, timeZone]);
}
}
export class FnMarketplaceImage extends FnBase {
/**
* Creates an ``MarketplaceImage`` function.
*/
constructor(imageProductCode: string | ros.IResolvable) {
super("Fn::MarketplaceImage", imageProductCode);
}
}
export class FnAny extends FnBase {
/**
* Creates an ``Any`` function.
*/
constructor(values: any[] | ros.IResolvable) {
super("Fn::Any", values);
}
}
export class FnContains extends FnBase {
/**
* Creates an ``Contains`` function.
*/
constructor(values: any[] | ros.IResolvable, value: any) {
super("Fn::Contains", [values, value]);
}
}
export class FnEachMemberIn extends FnBase {
/**
* Creates an ``EachMemberIn`` function.
*/
constructor(values1: any[] | ros.IResolvable, values2: any[] | ros.IResolvable) {
super("Fn::EachMemberIn", [values1, values2]);
}
}
export class FnMatchPattern extends FnBase {
/**
* Creates an ``MatchPattern`` function.
*/
constructor(pattern: string | ros.IResolvable, value: string | ros.IResolvable) {
super("Fn::MatchPattern", [pattern, value]);
}
}
export class FnCidr extends FnBase {
/**
* Creates an ``Cidr`` function.
*/
constructor(ipBlock: string | ros.IResolvable, count: number | ros.IResolvable, cidrBits: number | ros.IResolvable) {
super("Fn::Cidr", [ipBlock, count, cidrBits]);
}
}
// new function
export class FnStr extends FnBase {
/**
* Creates an ``Str`` function.
*/
constructor(value: any) {
super("Fn::Str", value);
}
}
export class FnBase64Decode extends FnBase {
constructor(data: any) {
super("Fn::Base64Decode", data);
}
}
export class FnReplace extends FnBase {
/**
* Creates an ``Replace`` function.
*/
constructor(value: any) {
super("Fn::Replace", value);
}
}
export class FnGetJsonValue extends FnBase {
/**
* Creates an ``GetJsonValue`` function.
*/
constructor(value: any) {
super("Fn::GetJsonValue", value);
}
}
export class FnAvg extends FnBase {
/**
* Creates an ``Avg`` function.
*/
constructor(value: any) {
super("Fn::Avg", value);
}
}
export class FnAdd extends FnBase {
/**
* Creates an ``Add`` function.
*/
constructor(values: any) {
super("Fn::Add", values);
}
}
export class FnCalculate extends FnBase {
/**
* Creates an ``Calculate`` function.
*/
constructor(value: any) {
super("Fn::Calculate", value);
}
}
export class FnMax extends FnBase {
/**
* Creates an ``Max`` function.
*/
constructor(values: any) {
super("Fn::Max", values);
}
}
export class FnMin extends FnBase {
/**
* Creates an ``Min`` function.
*/
constructor(values: any) {
super("Fn::Min", values);
}
}
export class FnGetStackOutput extends FnBase {
/**
* Creates an ``GetStackOutput`` function.
*/
constructor(value: any) {
super("Fn::GetStackOutput", value);
}
}
export class FnJq extends FnBase {
/**
* Creates an ``Jq`` function.
*/
constructor(value: any) {
super("Fn::Jq", value);
}
}
export class FnMergeMapToList extends FnBase {
/**
* Creates an ``FnMergeMapToList`` function.
*/
constructor(mapList: any) {
super("Fn::MergeMapToList", mapList);
}
}
export class FnSelectMapList extends FnBase {
/**
* Creates an ``FnMergeMapToList`` function.
*/
constructor(value: any) {
super("Fn::SelectMapList", value);
}
}
/**
* The intrinsic function ``Ref`` returns the value of the specified parameter or resource.
* When you specify a parameter's logical name, it returns the value of the parameter.
* When you specify a resource's logical name, it returns a value that you can typically use to refer to that resource, such as a physical ID.
*/
export class FnRef extends FnBase {
/**
* Creates an ``Ref`` function.
* @param logicalName The logical name of a parameter/resource for which you want to retrieve its value.
*/
constructor(logicalName: string) {
super("Ref", logicalName);
}
}
/**
* The intrinsic function ``Fn::FindInMap`` returns the value corresponding to keys in a two-level
* map that is declared in the Mappings section.
*/
export class FnFindInMap extends FnBase {
/**
* Creates an ``Fn::FindInMap`` function.
* param mapName The logical name of a mapping declared in the Mappings section that contains the keys and values.
* param topLevelKey The top-level key name. Its value is a list of key-value pairs.
* param secondLevelKey The second-level key name, which is set to one of the keys from the list assigned to TopLevelKey.
*/
constructor(value: any) {
super("Fn::FindInMap", value);
}
}
/**
* The ``Fn::GetAtt`` intrinsic function returns the value of an attribute from a resource in the template.
*/
export class FnGetAtt extends FnBase {
/**
* Creates a ``Fn::GetAtt`` function.
* @param logicalNameOfResource The logical name (also called logical ID) of the resource that contains the attribute that you want.
* @param attributeName The name of the resource-specific attribute whose value you want. See the resource's reference page for details about the attributes available for that resource type.
*/
constructor(logicalNameOfResource: string, attributeName: string) {
super("Fn::GetAtt", [logicalNameOfResource, attributeName]);
}
}
/**
* The intrinsic function ``Fn::GetAZs`` returns an array that lists Availability Zones for a
* specified region. Because customers have access to different Availability Zones, the intrinsic
* function ``Fn::GetAZs`` enables template authors to write templates that adapt to the calling
* user's access. That way you don't have to hard-code a full list of Availability Zones for a
* specified region.
*/
export class FnGetAZs extends FnBase {
/**
* Creates an ``Fn::GetAZs`` function.
* @param region The name of the region for which you want to get the Availability Zones.
*/
constructor(region: any) {
super("Fn::GetAZs", region);
}
}
/**
* The intrinsic function ``Fn::Select`` returns a single object from a list of objects by index.
*/
export class FnSelect extends FnBase {
/**
* Creates an ``Fn::Select`` function.
* param index The index of the object to retrieve. This must be a value from zero to N-1, where N represents the number of elements in the array.
* param array The list of objects to select from. This list must not be null, nor can it have null entries.
*/
constructor(value: any) {
super("Fn::Select", value);
}
}
/**
* To split a string into a list of string values so that you can select an element from the
* resulting string list, use the ``Fn::Split`` intrinsic function. Specify the location of splits
* with a delimiter, such as , (a comma). After you split a string, use the ``Fn::Select`` function
* to pick a specific element.
*/
export class FnSplit extends FnBase {
/**
* Create an ``Fn::Split`` function.
* param delimiter A string value that determines where the source string is divided.
* param source The string value that you want to split.
*/
constructor(value: any) {
super("Fn::Split", value);
}
}
/**
* The intrinsic function ``Fn::Sub`` substitutes variables in an input string with values that
* you specify. In your templates, you can use this function to construct commands or outputs
* that include values that aren't available until you create or update a stack.
*/
export class FnSub extends FnBase {
/**
* Creates an ``Fn::Sub`` function.
* param body A string with variables that Ros Template substitutes with their
* associated values at runtime. Write variables as ${MyVarName}. Variables
* can be template parameter names, resource logical IDs, resource attributes,
* or a variable in a key-value map. If you specify only template parameter names,
* resource logical IDs, and resource attributes, don't specify a key-value map.
* param variables The name of a variable that you included in the String parameter.
* The value that Ros Template substitutes for the associated variable name at runtime.
*/
constructor(value: any) {
super("Fn::Sub", value);
}
}
/**
* The intrinsic function ``Fn::Base64`` returns the Base64 representation of the input string.
*/
export class FnBase64Encode extends FnBase {
/**
* Creates an ``Fn::Base64`` function.
* @param data The string value you want to convert to Base64.
*/
constructor(data: any) {
super("Fn::Base64Encode", data);
}
}
class FnConditionBase extends Intrinsic implements IRosConditionExpression {
constructor(type: string, value: any) {
super({ [type]: value });
}
}
/**
* Returns true if all the specified conditions evaluate to true, or returns false if any one
* of the conditions evaluates to false. ``Fn::And`` acts as an AND operator. The minimum number of
* conditions that you can include is 2, and the maximum is 10.
*/
export class FnAnd extends FnConditionBase {
constructor(...condition: (string | IRosConditionExpression)[]) {
super("Fn::And", condition);
}
}
/**
* Compares if two values are equal. Returns true if the two values are equal or false
* if they aren't.
*/
export class FnEquals extends FnConditionBase {
/**
* Creates an ``Fn::Equals`` condition function.
* @param lhs A value of any type that you want to compare.
* @param rhs A value of any type that you want to compare.
*/
constructor(lhs: any, rhs: any) {
super("Fn::Equals", [lhs, rhs]);
}
}
/**
* Returns one value if the specified condition evaluates to true and another value if the
* specified condition evaluates to false.
*/
export class FnIf extends FnConditionBase {
/**
* Creates an ``Fn::If`` condition function.
* @param condition A reference to a condition in the Conditions section. Use the condition's name to reference it.
* @param valueIfTrue A value to be returned if the specified condition evaluates to true.
* @param valueIfFalse A value to be returned if the specified condition evaluates to false.
*/
constructor(condition: string | IRosConditionExpression, valueIfTrue: any, valueIfFalse: any) {
super("Fn::If", [condition, valueIfTrue, valueIfFalse]);
}
}
/**
* Returns true for a condition that evaluates to false or returns false for a condition that evaluates to true.
* ``Fn::Not`` acts as a NOT operator.
*/
export class FnNot extends FnConditionBase {
/**
* Creates an ``Fn::Not`` condition function.
* @param condition A condition such as ``Fn::Equals`` that evaluates to true or false.
*/
constructor(condition: string | IRosConditionExpression) {
super("Fn::Not", [condition]);
}
}
/**
* Returns true if any one of the specified conditions evaluate to true, or returns false if
* all of the conditions evaluates to false. ``Fn::Or`` acts as an OR operator. The minimum number
* of conditions that you can include is 2, and the maximum is 10.
*/
export class FnOr extends FnConditionBase {
/**
* Creates an ``Fn::Or`` condition function.
* @param condition A condition that evaluates to true or false.
*/
constructor(...condition: (string | IRosConditionExpression)[]) {
super("Fn::Or", condition);
}
}
/**
* Returns true if a specified string matches all values in a list.
*/
// class FnEachMemberEquals extends FnConditionBase {
// /**
// * Creates an ``Fn::EachMemberEquals`` function.
// * @param listOfStrings A list of strings, such as "A", "B", "C".
// * @param value A string, such as "A", that you want to compare against a list of strings.
// */
// constructor(listOfStrings: any, value: string) {
// super("Fn::EachMemberEquals", [listOfStrings, value]);
// }
// }
export class FnListMerge implements IResolvable {
public readonly creationStack: string[];
private readonly listOfValues: any[];
/**
* Creates an ``ListMerge`` function.
*/
constructor(listOfValues: any[]) {
if (listOfValues.length === 0) {
throw new Error("FnListMerge requires at least one value to be provided");
}
this.listOfValues = listOfValues;
this.creationStack = captureStackTrace();
}
public resolve(context: IResolveContext): any {
if (Token.isUnresolved(this.listOfValues)) {
// This is a list token, don't try to do smart things with it.
return { "Fn::ListMerge": this.listOfValues };
}
const resolved = this.resolveValues(context);
if (resolved.length === 1) {
return resolved[0];
}
return { "Fn::ListMerge": resolved };
}
public toString() {
return Token.asString(this, { displayHint: "Fn::ListMerge" });
}
public toJSON() {
return "<Fn::ListMerge>";
}
/**
* Optimization: if an Fn::ListMerge is nested in another one, then flatten it up.
*/
private resolveValues(context: IResolveContext) {
const resolvedValues = this.listOfValues.map((x) =>
Reference.isReference(x) ? x : context.resolve(x)
);
return minimalRosTemplateListMerge(resolvedValues);
}
}
/**
* The intrinsic function ``Fn::Join`` appends a set of values into a single value, separated by
* the specified delimiter. If a delimiter is the empty string, the set of values are concatenated
* with no delimiter.
*/
export class FnJoin implements IResolvable {
public readonly creationStack: string[];
private readonly delimiter: string;
private readonly listOfValues: any[];
/**
* Creates an ``Fn::Join`` function.
* @param delimiter The value you want to occur between fragments. The delimiter will occur between fragments only.
* It will not terminate the final value.
* @param listOfValues The list of values you want combined.
*/
constructor(delimiter: string, listOfValues: any[]) {
if (listOfValues.length === 0) {
throw new Error("FnJoin requires at least one value to be provided");
}
this.delimiter = delimiter;
this.listOfValues = listOfValues;
this.creationStack = captureStackTrace();
}
public resolve(context: IResolveContext): any {
if (Token.isUnresolved(this.listOfValues)) {
// This is a list token, don't try to do smart things with it.
return { "Fn::Join": [this.delimiter, this.listOfValues] };
}
const resolved = this.resolveValues(context);
if (resolved.length === 1) {
return resolved[0];
}
return { "Fn::Join": [this.delimiter, resolved] };
}
public toString() {
return Token.asString(this, { displayHint: "Fn::Join" });
}
public toJSON() {
return "<Fn::Join>";
}
/**
* Optimization: if an Fn::Join is nested in another one and they share the same delimiter, then flatten it up. Also,
* if two concatenated elements are literal strings (not tokens), then pre-concatenate them with the delimiter, to
* generate shorter output.
*/
private resolveValues(context: IResolveContext) {
const resolvedValues = this.listOfValues.map((x) =>
Reference.isReference(x) ? x : context.resolve(x)
);
return minimalRosTemplateJoin(this.delimiter, resolvedValues);
}
}