|
| 1 | +importtype{ |
| 2 | +ASTNode, |
| 3 | +ASTPath, |
| 4 | +Collection, |
| 5 | +Identifier, |
| 6 | +ObjectExpression, |
| 7 | +}from'jscodeshift' |
| 8 | +importtype{Context}from'./wrapAstTransformation' |
| 9 | + |
| 10 | +exportfunctiongetVueOptionsObject( |
| 11 | +context:Context |
| 12 | +):Collection<ObjectExpression>{ |
| 13 | +constpaths:ASTPath<ObjectExpression>[]=[] |
| 14 | +const{ j, root, filename}=context |
| 15 | + |
| 16 | +functionnodesToPaths<T>( |
| 17 | +nodes:TextendsASTNode ?T|T[] :never |
| 18 | +):ASTPath<T>[]{ |
| 19 | +returnj(nodes).paths() |
| 20 | +} |
| 21 | + |
| 22 | +functiongetConstDeclarationInit(id:Identifier){ |
| 23 | +constdeclarator=root.findVariableDeclarators(id.name) |
| 24 | +constdeclarationKind=declarator.closest(j.VariableDeclaration).nodes()[0] |
| 25 | +.kind |
| 26 | + |
| 27 | +if(declarationKind!=='const'){ |
| 28 | +returnnull |
| 29 | +} |
| 30 | + |
| 31 | +returndeclarator.nodes()[0].init |
| 32 | +} |
| 33 | + |
| 34 | +functionhasRenderOrTemplateProps(obj:ObjectExpression){ |
| 35 | +returnobj.properties.some((prop)=>{ |
| 36 | +if(j.SpreadElement.check(prop)||j.SpreadProperty.check(prop)){ |
| 37 | +returnfalse |
| 38 | +} |
| 39 | + |
| 40 | +if(j.StringLiteral.check(prop.key)){ |
| 41 | +returnprop.key.value==='render'||prop.key.value==='template' |
| 42 | +} |
| 43 | + |
| 44 | +if(j.Identifier.check(prop.key)){ |
| 45 | +returnprop.key.name==='render'||prop.key.name==='template' |
| 46 | +} |
| 47 | +}) |
| 48 | +} |
| 49 | + |
| 50 | +if(filename.endsWith('.vue')){ |
| 51 | +// (.vue) export default {} |
| 52 | +constdefaultObjectExport=root |
| 53 | +.find(j.ExportDefaultDeclaration) |
| 54 | +.map((path)=>{ |
| 55 | +constdecl=path.node.declaration |
| 56 | + |
| 57 | +if(j.ObjectExpression.check(decl)){ |
| 58 | +returnnodesToPaths(decl) |
| 59 | +} |
| 60 | + |
| 61 | +if(j.Identifier.check(decl)){ |
| 62 | +constinit=getConstDeclarationInit(decl) |
| 63 | +if(init&&j.ObjectExpression.check(init)){ |
| 64 | +returnnodesToPaths(init) |
| 65 | +} |
| 66 | +} |
| 67 | + |
| 68 | +returnnull |
| 69 | +}) |
| 70 | + |
| 71 | +paths.push(...defaultObjectExport.paths()) |
| 72 | +}else{ |
| 73 | +// (.js) export default {} with `render` or `template` option |
| 74 | +constdefaultObjectExport=root |
| 75 | +.find(j.ExportDefaultDeclaration) |
| 76 | +.map((path)=>{ |
| 77 | +constdecl=path.node.declaration |
| 78 | + |
| 79 | +if(j.ObjectExpression.check(decl)&&hasRenderOrTemplateProps(decl)){ |
| 80 | +returnnodesToPaths(decl) |
| 81 | +} |
| 82 | + |
| 83 | +if(j.Identifier.check(decl)){ |
| 84 | +constinit=getConstDeclarationInit(decl) |
| 85 | +if( |
| 86 | +init&& |
| 87 | +j.ObjectExpression.check(init)&& |
| 88 | +hasRenderOrTemplateProps(init) |
| 89 | +){ |
| 90 | +returnnodesToPaths(init) |
| 91 | +} |
| 92 | +} |
| 93 | +}) |
| 94 | + |
| 95 | +paths.push(...defaultObjectExport.paths()) |
| 96 | +} |
| 97 | + |
| 98 | +// defineComponent({}) |
| 99 | +// new Vue({}) |
| 100 | +// Vue.component('name', {}) |
| 101 | + |
| 102 | +returnj(paths) |
| 103 | +} |