function inspectRequires(ast, packagesToInspect, deep = true) {
  /** @type {string[][]} */
  const cjsImports = []
  const requireCalls = findAllCallsToRequire(ast)
  requireCalls.forEach((path) => {
    const { node } = path
    const {
      arguments: [moduleNameNode],
    } = node
    // skip invalid or dynamic require calls
    if (!moduleNameNode || moduleNameNode.type !== 'StringLiteral') {
      return
    }
    // skip if not specified in "packagesToInspect"
    const moduleName = moduleNameNode.value
    if (packagesToInspect && !packagesToInspect.includes(moduleName)) {
      return
    }
    // if not deep, done
    if (!deep) {
      cjsImports.push([moduleName])
      return
    }
    // inspect for member chain
    // eg:  require("abc").xyz
    const parents = getParents(path)
    const { memberExpressions, parentOfMembershipChain } =
      getMemberExpressionNesting(node, parents)
    const initialKeyPath = [
      moduleName,
      ...getPathFromMemberExpressionChain(memberExpressions),
    ]
    // if import not used in a var declaration, exit early
    if (parentOfMembershipChain.type !== 'VariableDeclarator') {
      // result of require has not been assigned, it has been consumed
      cjsImports.push(initialKeyPath)
      return
    }
    // get all declared vars (destructuring)
    // for each declared var, detect usage keyPath
    // eg:  const { ijk } = require("abc").xyz
    const identifierOrPattern = parentOfMembershipChain.id
    const declaredVars = inspectPatternElementForDeclarations(
      identifierOrPattern,
      initialKeyPath
    )
    declaredVars.forEach(({ node, keyPath }) => {
      // @ts-ignore - FIXME - `name` not present on all nodes of type `Declaration`
      const varName = node.name
      const refs = path.scope.getBinding(varName)?.referencePaths
      // if the var is not used anywhere, still whitelist it so the require call doesnt fail
      if (!refs?.length) {
        // add to results
        cjsImports.push(keyPath)
        return
      }
      // for each reference of the var, detect usage keyPath
      refs.forEach((refPath) => {
        const parents = getParents(refPath)
        const { memberExpressions } = getMemberExpressionNesting(
          refPath.node,
          parents
        )
        const subPath = getPathFromMemberExpressionChain(memberExpressions)
        const usageKeyPath = [...keyPath, ...subPath]
        // add to results
        cjsImports.push(usageKeyPath)
      })
    })
  })
  // stringify paths
  let cjsImportStrings = cjsImports.map((item) => item.join('.'))
  // get unique results
  cjsImportStrings = Array.from(new Set(cjsImportStrings))
  return { cjsImports: cjsImportStrings }
}
This finds all modules `required`ed into the AST, as well as any re-exported
modules.

@param {import('@babel/types').Node} ast
@param {string[]} [packagesToInspect]
@param {boolean} [deep]
@returns {{ cjsImports: string[] }}