code: function addObjectProperty(ast, varName, propName, propValue) {
    const changes = [];
    traverse(ast, {
      VariableDeclarator(path) {
        const node = path.node;
        if (
          (varName && _.get(node, 'id.name') !== varName) ||
          _.get(node, 'init.type') !== 'ObjectExpression'
        )
          return;
        const props = _.get(node, 'init.properties');
  
        const multilines = node.loc.start.line !== node.loc.end.line;
        // Check if it exists
        const targetPropNode = _.find(
          props,
          p =>
            _.get(p, 'key.type') === 'Identifier' && _.get(p, 'key.name') === propName && !p.computed,
        );
  
        let insertPos = node.init.start + 1;
        if (props.length) {
          insertPos = _.last(props).end;
        }
        const code = `${propName}: ${propValue}`;
        if (!targetPropNode) {
          let replacement;
          if (multilines) {
            const indent = _.repeat(' ', node.loc.end.column - 1);
            replacement = `\n${indent}  ${code}`;
            if (props.length) {
              replacement = `,${replacement}`;
            } else {
              replacement = `${replacement},`;
            }
          } else {
            replacement = ` ${code} `;
            if (props.length > 0) {
              replacement = `, ${code}`;
            }
          }
          changes.push({
            start: insertPos,
            end: insertPos,
            replacement,
          });
        } else {
          console.warn(`Property name '${propName}' already exists for ${varName}.`);
        }
      },
    });
    return changes;
  }
docs: function nearestCharBefore(char, str, index) { // Find the nearest char index before given index. skip white space strings // If not found, return -1 // eg: nearestCharBefore(',', '1,    2, 3', 4) => 1 let i = index - 1; while (i >= 0) { if (str.charAt(i) === char) return i; if (!/\s/.test(str.charAt(i))) return -1; i -= 1; } return -1; }