Using ejs, how to keep correct indentation while doing proper `join`?

Viewed 185

I'm trying to get to this result (two factors are important: exact indentation, as it outputs YAML, and no comma after last IP):

            # ... some stuff ...
            NotIpAddress:
                "aws:SourceIp": [
                    "100.200.300.400",
                    "110.200.300.400",
                    "120.200.300.400"
                ]
            # ... some more stuff ...

With the following ejs code:

            NotIpAddress:
                "aws:SourceIp": [
                    "<%- permittedIPAddresses.join('",\n"') %>"
                ]

But the result is (incorrect indentation of last two IPs):

            NotIpAddress:
                "aws:SourceIp": [
                    "100.200.300.400",
"110.200.300.400",
"120.200.300.400"
                ]

So I tried this:

            NotIpAddress:
                "aws:SourceIp": [
                    <%_ for(const i in permittedIPAddresses){ _%>
                    "<%= permittedIPAddresses[i].trim() %>",
                    <%_ } _%>
                ]

But that yielded this (last IP followed by comma):

            NotIpAddress:
                "aws:SourceIp": [                    
                    "100.200.300.400",
                    "110.200.300.400",
                    "120.200.300.400",
                ]

So I'm either giving up on correct indentation, or on correct join..

No way to keep indentation while also making proper join?

1 Answers

Here's how you can implement your second solution, but omit the comma on the last line:

NotIpAddress:
    "aws:SourceIp": [
        <%_ permittedIpAddresses.forEach((ip, i) => { _%>
        <%- `"${ip}"` + (i < (permittedIpAddresses.length - 1) ? ',' : '') %>
        <%_ }) _%>
    ]

This does the iteration in a way that provides the index position, and adds a comma when the index (i) is not the index of the last item.

As an alternative, you can take advantage of another option for formatting lists in YAML. It is uniform per line, so the comma issue just goes away and the result is cleaner.

NotIpAddress:
    "aws:SourceIp":
        <%_ permittedIpAddresses.forEach(ip => { _%>
        <%- `- "${ip}"` %>
        <%_ }) _%>

The result of using the alternative list format looks like this:

NotIpAddress:
    "aws:SourceIp":
        - "100.200.300.400"
        - "110.200.300.400"
        - "120.200.300.400"

For other alternatives, if your indentation level is fixed in every case (i.e. not dependent upon context), you could also use .map:

NotIpAddress:
    "aws:SourceIp": [
        <%- permittedIpAddresses.map(ip => `"${ip}"`).join(",\n        ") %>
    ]
NotIpAddress:
    "aws:SourceIp":
        <%- permittedIpAddresses.map(ip => `- "${ip}"`).join("\n        ") %>
Related