Skip to content

Commit 100065d

Browse files
committed
chore: extract fixTypeBased function
1 parent 536c6a1 commit 100065d

File tree

1 file changed

+63
-64
lines changed

1 file changed

+63
-64
lines changed

lib/rules/define-props-declaration.js

+63-64
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,68 @@
66

77
const utils = require('../utils')
88

9+
const PROPS_SEPARATOR = ', '
10+
11+
/**
12+
* @param {RuleFixer} fixer
13+
* @param {CallExpression} node
14+
* @param {ComponentProp[]} props
15+
* @param {RuleContext} context
16+
*/
17+
function* fixTypeBased(fixer, node, props, context) {
18+
try {
19+
const sourceCode = context.getSourceCode()
20+
const autoFixToSeparateInterface =
21+
context.options[1]?.autoFixToSeparateInterface || false
22+
23+
const propTypes = props.map((prop) =>
24+
getComponentPropData(prop, sourceCode)
25+
)
26+
27+
const definePropsType = `{ ${propTypes
28+
.map(
29+
({ name, type, required, defaultValue }) =>
30+
`${name}${required === false || defaultValue ? '?' : ''}: ${type}`
31+
)
32+
.join(PROPS_SEPARATOR)} }`
33+
34+
// remove defineProps function parameters
35+
yield fixer.replaceText(node.arguments[0], '')
36+
37+
// add type annotation
38+
if (autoFixToSeparateInterface) {
39+
const variableDeclarationNode = node.parent.parent
40+
if (!variableDeclarationNode) {
41+
return
42+
}
43+
44+
yield fixer.insertTextBefore(
45+
variableDeclarationNode,
46+
`interface Props ${definePropsType.replace(/;/g, ',')}; `
47+
)
48+
yield fixer.insertTextAfter(node.callee, `<Props>`)
49+
} else {
50+
yield fixer.insertTextAfter(node.callee, `<${definePropsType}>`)
51+
}
52+
53+
// add defaults if needed
54+
const defaults = propTypes.filter(({ defaultValue }) => defaultValue)
55+
if (defaults.length > 0) {
56+
const defaultsCode = defaults
57+
.map(
58+
({ name, defaultValue }) =>
59+
`${name}: ${sourceCode.getText(defaultValue)}`
60+
)
61+
.join(PROPS_SEPARATOR)
62+
63+
yield fixer.insertTextBefore(node, `withDefaults(`)
64+
yield fixer.insertTextAfter(node, `, { ${defaultsCode} })`)
65+
}
66+
return null
67+
} catch (error) {
68+
return null
69+
}
70+
}
971
const mapNativeType = (/** @type {string} */ nativeType) => {
1072
switch (nativeType) {
1173
case 'String': {
@@ -198,15 +260,12 @@ module.exports = {
198260
},
199261
/** @param {RuleContext} context */
200262
create(context) {
201-
const sourceCode = context.getSourceCode()
202-
203263
const scriptSetup = utils.getScriptSetupElement(context)
204264
if (!scriptSetup || !utils.hasAttribute(scriptSetup, 'lang', 'ts')) {
205265
return {}
206266
}
207267

208268
const defineType = context.options[0] || 'type-based'
209-
const autoFixToSeparateInterface = context.options[1]?.autoFixToSeparateInterface || false
210269

211270
return utils.defineScriptSetupVisitor(context, {
212271
onDefinePropsEnter(node, props) {
@@ -217,67 +276,7 @@ module.exports = {
217276
node,
218277
messageId: 'hasArg',
219278
*fix(fixer) {
220-
try {
221-
const propTypes = props.map((prop) =>
222-
getComponentPropData(prop, sourceCode)
223-
)
224-
225-
const definePropsType = `{ ${propTypes
226-
.map(
227-
({ name, type, required, defaultValue }) =>
228-
`${name}${
229-
required === false || defaultValue ? '?' : ''
230-
}: ${type}`
231-
)
232-
.join(', ')} }`
233-
234-
// remove defineProps function parameters
235-
yield fixer.replaceText(node.arguments[0], '')
236-
237-
// add type annotation
238-
if (autoFixToSeparateInterface) {
239-
const variableDeclarationNode = node.parent.parent
240-
if (!variableDeclarationNode) {
241-
return
242-
}
243-
244-
yield fixer.insertTextBefore(
245-
variableDeclarationNode,
246-
`interface Props ${definePropsType.replace(
247-
/;/g,
248-
','
249-
)}; `
250-
)
251-
yield fixer.insertTextAfter(node.callee, `<Props>`)
252-
} else {
253-
yield fixer.insertTextAfter(
254-
node.callee,
255-
`<${definePropsType}>`
256-
)
257-
}
258-
259-
// add defaults if needed
260-
const defaults = propTypes.filter(
261-
({ defaultValue }) => defaultValue
262-
)
263-
if (defaults.length > 0) {
264-
const defaultsCode = defaults
265-
.map(
266-
({ name, defaultValue }) =>
267-
`${name}: ${sourceCode.getText(defaultValue)}`
268-
)
269-
.join(', ')
270-
271-
yield fixer.insertTextBefore(node, `withDefaults(`)
272-
yield fixer.insertTextAfter(
273-
node,
274-
`, { ${defaultsCode} })`
275-
)
276-
}
277-
return null
278-
} catch (error) {
279-
return null
280-
}
279+
yield* fixTypeBased(fixer, node, props, context)
281280
}
282281
})
283282
}

0 commit comments

Comments
 (0)