diff --git a/modules/history/deprecate-createPath-createHref-query.js b/modules/history/deprecate-createPath-createHref-query.js index 2f048d4..1dccc6e 100644 --- a/modules/history/deprecate-createPath-createHref-query.js +++ b/modules/history/deprecate-createPath-createHref-query.js @@ -1,8 +1,6 @@ import parsePath from 'history/lib/parsePath' -function replace(source, api, methodName) { - const j = api.jscodeshift - +function replace(source, j, methodName) { return j(source) .find(j.CallExpression, { callee: { property: { name: methodName } } } @@ -41,10 +39,10 @@ function replace(source, api, methodName) { .toSource() } -export default (file, api) => { +export default (file, { jscodeshift: j }) => { let { source } = file - source = replace(source, api, 'createPath') - source = replace(source, api, 'createHref') + source = replace(source, j, 'createPath') + source = replace(source, j, 'createHref') return source } diff --git a/modules/history/deprecate-pushState-replaceState.js b/modules/history/deprecate-pushState-replaceState.js index 74c9546..df7b8ee 100644 --- a/modules/history/deprecate-pushState-replaceState.js +++ b/modules/history/deprecate-pushState-replaceState.js @@ -1,8 +1,6 @@ import parsePath from 'history/lib/parsePath' -function replace(source, api, flavor) { - const j = api.jscodeshift - +function replace(source, j, flavor) { return j(source) .find(j.CallExpression, { callee: { property: { name: `${flavor}State` } } } @@ -48,10 +46,10 @@ function replace(source, api, flavor) { .toSource() } -export default (file, api) => { +export default (file, { jscodeshift: j }) => { let { source } = file - source = replace(source, api, 'push') - source = replace(source, api, 'replace') + source = replace(source, j, 'push') + source = replace(source, j, 'replace') return source } diff --git a/modules/react-router/deprecate-Link-location-props.js b/modules/react-router/deprecate-Link-location-props.js new file mode 100644 index 0000000..40b198a --- /dev/null +++ b/modules/react-router/deprecate-Link-location-props.js @@ -0,0 +1,63 @@ +function isDeprecatedAttribute(attribute) { + const { name } = attribute.name + return [ 'query', 'hash', 'state' ].includes(name) +} + +function getValueExpression(value) { + if (value.type === 'Literal') { + return value + } + + return value.expression +} + +function replace(source, j, componentName) { + return j(source) + .find(j.JSXOpeningElement, { name: { name: componentName } }) + .forEach(p => { + const { name, attributes, selfClosing } = p.value + + const deprecatedAttributes = attributes.filter(isDeprecatedAttribute) + if (!deprecatedAttributes.length) { + return + } + + const newAttributes = attributes + .filter(attribute => !isDeprecatedAttribute(attribute)) + .map(attribute => { + if (attribute.name.name !== 'to') { + return attribute + } + + const properties = [ + j.property( + 'init', j.identifier('pathname'), + getValueExpression(attribute.value) + ) + ] + + properties.push(...deprecatedAttributes.map(({ name, value }) => ( + j.property( + 'init', j.identifier(name.name), + getValueExpression(value) + ) + ))) + + return j.jsxAttribute( + j.jsxIdentifier('to'), + j.jsxExpressionContainer(j.objectExpression(properties)) + ) + }) + + j(p).replaceWith(j.jsxOpeningElement(name, newAttributes, selfClosing)) + }) + .toSource() +} + +export default (file, { jscodeshift: j }) => { + let { source } = file + source = replace(source, j, 'Link') + source = replace(source, j, 'IndexLink') + + return source +}