zspecza / common-tags

🔖 Useful template literal tags for dealing with strings in ES2015+
Other
1.99k stars 60 forks source link

`stripIndent` not stripping 1st line of variables #208

Open latipun7 opened 3 years ago

latipun7 commented 3 years ago

I have this line of code: code

but, the 1st line of variables that contain their line break and indent not stripped at 1st line, it takes the 8 spaces indent from the code. (sorry if the description not very descriptive or hard to understand)

the result is like this: console.log(JSON.stringify(meta, null, 2)) :

{
  "code": "ERR_INVALID_ARG_TYPE"
}

console.log(stack) :

TypeError [ERR_INVALID_ARG_TYPE]: Error msg
    at stackTrace (internal/validators.js:122:11)
    ...etc

but this is the result of the stripIndent of them:

Variable that contain "\n    " would not strip for their 1st line below this.
        {
  "code": "ERR_INVALID_ARG_TYPE"
}
        TypeError [ERR_INVALID_ARG_TYPE]: Error msg
    at validateString (internal/validators.js:122:11)
    ...etc

notice the difference. Their 1st line not stripped. They take 8 spaces, same as the code.

ryan953 commented 3 years ago

I had the same issue too, but I was able to get around it. I was doing something like:

// broken
function foo() {
  const content = JSON.stringify({name: "foo"}, null, "\n");

  return stripIndent`
    Head 1
    Head 2
    ${content}
  `;
}
console.log(foo());

And I expected it to return (no leading whitespace):

Head 1
Head 2
{
  "name": "foo"
}

But instead it was returning this (leading whitespace on line 2):

Head 1
    Head 2
{
  "name": "foo"
}

The problem was that stripIndent was getting a string that had the content variable already expanded. The closing } in my json had zero indentation. It was as if I wrote:

function foo() {
  return stripIndent`
    Head 1
    Head 2
    {
  "name": "foo"
}";
  `;
}

I solved the problem by first stripping the header text, then concat the json after:

// Fixed!
function foo() {
  const content = JSON.stringify({name: "foo"}, null, "\n");

  return stripIndent`
    Head 1
    Head 2
  ` + '\n' + content;
}
console.log(foo());