javascripttypescriptjscodeshift

How to add 'await' at node using jscodeshift?


I recently have spotted jscodeshift and leveraging it for refactoring.

But I can't find a way to add await before the node that I am seeking.

// AS-IS
   userEvent.click(a);
   await userEvent.click(b);

// TO-BE
   await userEvent.click(a);
   await userEvent.click(b);

This is how I query userEvent.click

const getFunctionCall = (obj:string, prop:string) => {
     return source.find(j.CallExpression, {
         callee: {
           type: 'MemberExpression',
           object: {
             name: obj
           }, 
           property: {
             name:prop
           }
         }
     })
 }

const clicks = getFunctionCall('userEvent', 'click');
  
  clicks.forEach(i=> {
    if (i.parentPath.value.type !== 'AwaitExpression') {

      // code goes here

    }
  })

How can I add await before userEvent and let the rest code stay same in this case?

I checked out the document to find out how to build a statement or expression, but it wasn't understandable for me as I've just started to use this. I would appreciate if you can introduce any good materials for this library.

Thanks in advance!


Solution

  • It is simple, you need to wrap the existing CallExpression inside an await expression like this:

    // Press ctrl+space for code completion
    export default function transformer(file, api) {
      const j = api.jscodeshift;
      const root = j(file.source);
      const body = root.get().value.program.body;
    
      root.find(j.CallExpression, {
        callee: {
    object: {
            name: "userEvent"
          },
    
          property: {
            name: "click"
          }
        }
      }).filter(path => {
        return path.value.arguments[0].name === "a" ;
      }).replaceWith(path => {
        return j.awaitExpression(path.value)
      });
    
      return root.toSource();
    }