| 
1 |  | -import { camelize, capitalize } from '@vue/shared'  | 
 | 1 | +import { capitalize } from '@vue/shared'  | 
2 | 2 | import type { Node, ObjectExpression, Statement } from '@babel/types'  | 
3 | 3 | import generate from '@babel/generator'  | 
4 | 4 | import { partition } from '@antfu/utils'  | 
5 | 5 | import { ParsedSFC, ScriptSetupTransformOptions } from '../types'  | 
6 | 6 | import { applyMacros } from './macros'  | 
7 | 7 | import { getIdentifierDeclarations } from './identifiers'  | 
8 | 8 | import { t } from './babel'  | 
 | 9 | +import { isNotNil, pascalize } from './utils'  | 
9 | 10 | 
 
  | 
10 | 11 | function isAsyncImport(node: any) {  | 
11 | 12 |   if (node.type === 'VariableDeclaration') {  | 
@@ -35,22 +36,29 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf  | 
35 | 36 |   const declarations = new Set<string>()  | 
36 | 37 |   getIdentifierDeclarations(hoisted, declarations)  | 
37 | 38 |   getIdentifierDeclarations(setupBody, declarations)  | 
 | 39 | +  const declarationArray = Array.from(declarations).filter(isNotNil)  | 
38 | 40 | 
 
  | 
39 | 41 |   // filter out identifiers that are used in `<template>`  | 
40 |  | -  const returns: ObjectExpression['properties'] = Array.from(declarations)  | 
41 |  | -    .filter(Boolean)  | 
 | 42 | +  const returns: ObjectExpression['properties'] = declarationArray  | 
42 | 43 |     .filter(i => template.identifiers.has(i))  | 
43 | 44 |     .map((i) => {  | 
44 | 45 |       const id = t.identifier(i)  | 
45 | 46 |       return t.objectProperty(id, id, false, true)  | 
46 | 47 |     })  | 
47 | 48 | 
 
  | 
48 |  | -  const components = Array.from(declarations)  | 
49 |  | -    .filter(Boolean)  | 
50 |  | -    .filter(i => template.components.has(i)  | 
51 |  | -      || template.components.has(camelize(i))  | 
52 |  | -      || template.components.has(capitalize(camelize(i))),  | 
53 |  | -    )  | 
 | 49 | +  const components = Array.from(template.components).map(component =>  | 
 | 50 | +    declarationArray.find(declare => declare === component)  | 
 | 51 | +    ?? declarationArray.find(declare => pascalize(declare) === component),  | 
 | 52 | +  ).filter(isNotNil)  | 
 | 53 | + | 
 | 54 | +  const directiveDeclaration = Array.from(template.directives).map((directive) => {  | 
 | 55 | +    const identifier = declarationArray.find(declaration => declaration === `v${capitalize(directive)}`)  | 
 | 56 | +    if (identifier === undefined)  | 
 | 57 | +      return undefined  | 
 | 58 | + | 
 | 59 | +    return { identifier, directive }  | 
 | 60 | +  },  | 
 | 61 | +  ).filter(isNotNil)  | 
54 | 62 | 
 
  | 
55 | 63 |   // append `<script setup>` imports to `<script>`  | 
56 | 64 | 
 
  | 
@@ -160,6 +168,35 @@ export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransf  | 
160 | 168 |     )  | 
161 | 169 |   }  | 
162 | 170 | 
 
  | 
 | 171 | +  // inject directives  | 
 | 172 | +  // `__sfc_main.directives = Object.assign({ ... }, __sfc_main.directives)`  | 
 | 173 | +  if (directiveDeclaration.length) {  | 
 | 174 | +    hasBody = true  | 
 | 175 | +    const directivesObject = t.objectExpression(  | 
 | 176 | +      directiveDeclaration.map(({ directive, identifier }) => (t.objectProperty(  | 
 | 177 | +        t.identifier(directive),  | 
 | 178 | +        t.identifier(identifier),  | 
 | 179 | +        false,  | 
 | 180 | +        false,  | 
 | 181 | +      ))),  | 
 | 182 | +    )  | 
 | 183 | + | 
 | 184 | +    ast.body.push(  | 
 | 185 | +      t.expressionStatement(  | 
 | 186 | +        t.assignmentExpression('=',  | 
 | 187 | +          t.memberExpression(__sfc, t.identifier('directives')),  | 
 | 188 | +          t.callExpression(  | 
 | 189 | +            t.memberExpression(t.identifier('Object'), t.identifier('assign')),  | 
 | 190 | +            [  | 
 | 191 | +              directivesObject,  | 
 | 192 | +              t.memberExpression(__sfc, t.identifier('directives')),  | 
 | 193 | +            ],  | 
 | 194 | +          ),  | 
 | 195 | +        ),  | 
 | 196 | +      ) as any,  | 
 | 197 | +    )  | 
 | 198 | +  }  | 
 | 199 | + | 
163 | 200 |   if (!hasBody && !options?.astTransforms) {  | 
164 | 201 |     return {  | 
165 | 202 |       ast: null,  | 
 | 
0 commit comments