mirror of
https://github.com/hanzoai/agency.git
synced 2026-11-02 19:13:28 +00:00
209 lines
5.5 KiB
Plaintext
209 lines
5.5 KiB
Plaintext
module.exports = ({ root, jscodeshift }) => {
|
|
const findImportIdentifierOf = (importSpecifiers, identifier) => {
|
|
const specifier = importSpecifiers
|
|
.filter((node) => node.value.imported.name === identifier)
|
|
.paths()
|
|
|
|
if (specifier.length > 0) {
|
|
return specifier[0].value.local
|
|
}
|
|
|
|
return jscodeshift.identifier(identifier)
|
|
}
|
|
|
|
const findImportSpecifiers = (packageName) =>
|
|
root
|
|
.find(jscodeshift.ImportDeclaration, {
|
|
source: {
|
|
value: packageName,
|
|
},
|
|
})
|
|
.find(jscodeshift.ImportSpecifier, {})
|
|
|
|
const locateImports = (
|
|
identifiers,
|
|
packageName = '@tanstack/react-query',
|
|
) => {
|
|
const findNamespaceImportIdentifier = () => {
|
|
const specifier = root
|
|
.find(jscodeshift.ImportDeclaration, {
|
|
source: {
|
|
value: packageName,
|
|
},
|
|
})
|
|
.find(jscodeshift.ImportNamespaceSpecifier)
|
|
.paths()
|
|
|
|
return specifier.length > 0 ? specifier[0].value.local : null
|
|
}
|
|
|
|
/**
|
|
* First, we search for the namespace import identifier because if we have any, we assume the consumer uses
|
|
* namespace imports. In this case, we won't search for named imports at all.
|
|
*/
|
|
const namespaceImportIdentifier = findNamespaceImportIdentifier()
|
|
|
|
if (namespaceImportIdentifier) {
|
|
const identifierMap = {}
|
|
|
|
for (const identifier of identifiers) {
|
|
identifierMap[identifier] = jscodeshift.identifier(identifier)
|
|
}
|
|
|
|
return {
|
|
namespace: namespaceImportIdentifier,
|
|
...identifierMap,
|
|
}
|
|
}
|
|
|
|
const importSpecifiers = findImportSpecifiers(packageName)
|
|
const identifierMap = {}
|
|
|
|
for (const identifier of identifiers) {
|
|
identifierMap[identifier] = findImportIdentifierOf(
|
|
importSpecifiers,
|
|
identifier,
|
|
)
|
|
}
|
|
|
|
return {
|
|
namespace: null,
|
|
...identifierMap,
|
|
}
|
|
}
|
|
|
|
const findAllMethodCalls = () =>
|
|
root
|
|
// First, we need to find all method calls.
|
|
.find(jscodeshift.CallExpression, {
|
|
callee: {
|
|
type: jscodeshift.MemberExpression.name,
|
|
property: {
|
|
type: jscodeshift.Identifier.name,
|
|
},
|
|
},
|
|
})
|
|
|
|
const findQueryClientIdentifiers = (importIdentifiers) =>
|
|
root
|
|
.find(jscodeshift.VariableDeclarator, {})
|
|
.filter((node) => {
|
|
if (node.value.init) {
|
|
const initializer = node.value.init
|
|
|
|
return (
|
|
isClassInstantiationOf(
|
|
initializer,
|
|
getSelectorByImports(importIdentifiers, 'QueryClient'),
|
|
) ||
|
|
isFunctionCallOf(
|
|
initializer,
|
|
getSelectorByImports(importIdentifiers, 'useQueryClient'),
|
|
)
|
|
)
|
|
}
|
|
|
|
return false
|
|
})
|
|
.paths()
|
|
.map((node) => node.value.id.name)
|
|
|
|
const isCallExpression = (node) =>
|
|
jscodeshift.match(node, { type: jscodeshift.CallExpression.name })
|
|
|
|
const isIdentifier = (node) =>
|
|
jscodeshift.match(node, { type: jscodeshift.Identifier.name })
|
|
|
|
const isMemberExpression = (node) =>
|
|
jscodeshift.match(node, { type: jscodeshift.MemberExpression.name })
|
|
|
|
const isNewExpression = (node) =>
|
|
jscodeshift.match(node, { type: jscodeshift.NewExpression.name })
|
|
|
|
const isArrayExpression = (node) =>
|
|
jscodeshift.match(node, { type: jscodeshift.ArrayExpression.name })
|
|
|
|
const isObjectExpression = (node) =>
|
|
jscodeshift.match(node, { type: jscodeshift.ObjectExpression.name })
|
|
|
|
const isObjectProperty = (node) =>
|
|
jscodeshift.match(node, { type: jscodeshift.ObjectProperty.name })
|
|
|
|
const isSpreadElement = (node) =>
|
|
jscodeshift.match(node, { type: jscodeshift.SpreadElement.name })
|
|
|
|
/**
|
|
* @param {import('jscodeshift').Node} node
|
|
* @returns {boolean}
|
|
*/
|
|
const isFunctionDefinition = (node) => {
|
|
const isArrowFunctionExpression = jscodeshift.match(node, {
|
|
type: jscodeshift.ArrowFunctionExpression.name,
|
|
})
|
|
const isFunctionExpression = jscodeshift.match(node, {
|
|
type: jscodeshift.FunctionExpression.name,
|
|
})
|
|
|
|
return isArrowFunctionExpression || isFunctionExpression
|
|
}
|
|
|
|
const warn = (message) => {
|
|
if (process.env.NODE_ENV !== 'test') {
|
|
console.warn(message)
|
|
}
|
|
}
|
|
|
|
const isClassInstantiationOf = (node, selector) => {
|
|
if (!isNewExpression(node)) {
|
|
return false
|
|
}
|
|
|
|
const parts = selector.split('.')
|
|
|
|
return parts.length === 1
|
|
? isIdentifier(node.callee) && node.callee.name === parts[0]
|
|
: isMemberExpression(node.callee) &&
|
|
node.callee.object.name === parts[0] &&
|
|
node.callee.property.name === parts[1]
|
|
}
|
|
|
|
const isFunctionCallOf = (node, selector) => {
|
|
if (!isCallExpression(node)) {
|
|
return false
|
|
}
|
|
|
|
const parts = selector.split('.')
|
|
|
|
return parts.length === 1
|
|
? isIdentifier(node.callee) && node.callee.name === parts[0]
|
|
: isMemberExpression(node.callee) &&
|
|
node.callee.object.name === parts[0] &&
|
|
node.callee.property.name === parts[1]
|
|
}
|
|
|
|
const getSelectorByImports = (imports, path) =>
|
|
imports.namespace
|
|
? `${imports.namespace.name}.${imports[path].name}`
|
|
: imports[path].name
|
|
|
|
return {
|
|
findAllMethodCalls,
|
|
getSelectorByImports,
|
|
isCallExpression,
|
|
isClassInstantiationOf,
|
|
isFunctionCallOf,
|
|
isIdentifier,
|
|
isMemberExpression,
|
|
isArrayExpression,
|
|
isObjectExpression,
|
|
isObjectProperty,
|
|
isSpreadElement,
|
|
isFunctionDefinition,
|
|
locateImports,
|
|
warn,
|
|
queryClient: {
|
|
findQueryClientIdentifiers,
|
|
},
|
|
}
|
|
}
|