const fs = require('fs') const path = require('path') const compiler = require('vue/compiler-sfc') const babel = require('@babel/parser') const traverse = require('@babel/traverse').default function walk(dir) { let results = [] const list = fs.readdirSync(dir) list.forEach(function (file) { file = dir + '/' + file const stat = fs.statSync(file) if (stat && stat.isDirectory()) { results = results.concat(walk(file)) } else { if (file.endsWith('.vue')) results.push(file) } }) return results } const vueFiles = walk('docs/.vitepress/theme/components') vueFiles.forEach((file) => { const content = fs.readFileSync(file, 'utf8') if (!content.includes('setInterval')) return const { descriptor } = compiler.parse(content) if (!descriptor.scriptSetup) return const ast = babel.parse(descriptor.scriptSetup.content, { sourceType: 'module', plugins: ['typescript'] }) traverse(ast, { CallExpression(path) { if (path.node.callee.name === 'setInterval') { // check if we are inside a function declaration or arrow function or onMounted check let parent = path.parentPath let insideFunction = false while (parent) { if ( parent.isFunctionDeclaration() || parent.isArrowFunctionExpression() || parent.isFunctionExpression() || parent.isObjectMethod() ) { insideFunction = true break } parent = parent.parentPath } if (!insideFunction) { console.log( `Top-level setInterval found in ${file} at line ${path.node.loc.start.line}` ) } } } }) })