-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: [FX-4053] create codemods for RTE (#3657)
* chore: create codemods for rte * chore: adjust codemod * chore: update eslint rules for codemod * chore: update eslintignore * chore: update prettier ignore * chore: update version
- Loading branch information
Showing
10 changed files
with
262 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
'@toptal/picasso-codemod': minor | ||
--- | ||
|
||
--- | ||
|
||
- add codemod for replacing RichTextEditor imports |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
packages/picasso-codemod/src/v36.0.0/__testfixtures__/imports.input.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { RichTextEditor } from '@toptal/picasso-forms' | ||
import type { CustomEmojiGroup } from '@toptal/picasso/RichTextEditor' | ||
import type { CustomEmoji } from '@toptal/picasso/RichTextEditor/types' | ||
import type { RichTextEditorProps as LocalRichTextEditorProps } from '@toptal/picasso' | ||
import { | ||
Container, | ||
RichText as LocalRichText, | ||
Typography, | ||
} from '@toptal/picasso' | ||
import { RichText } from '@toptal/picasso' | ||
import { Icon } from '@toptal/picasso' | ||
import { Something, transformString } from 'some-module' | ||
import { htmlToHast } from '@toptal/picasso/utils' |
10 changes: 10 additions & 0 deletions
10
packages/picasso-codemod/src/v36.0.0/__testfixtures__/imports.output.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { RichTextEditor } from '@toptal/picasso-forms' | ||
import type { CustomEmojiGroup } from '@toptal/picasso-rich-text-editor/RichTextEditor'; | ||
import type { CustomEmoji } from '@toptal/picasso-rich-text-editor/RichTextEditor/types'; | ||
import type { RichTextEditorProps as LocalRichTextEditorProps } from '@toptal/picasso-rich-text-editor'; | ||
import { Container, Typography } from '@toptal/picasso'; | ||
import { RichText as LocalRichText } from '@toptal/picasso-rich-text-editor'; | ||
import { RichText } from '@toptal/picasso-rich-text-editor'; | ||
import { Icon } from '@toptal/picasso' | ||
import { Something, transformString } from 'some-module' | ||
import { htmlToHast } from '@toptal/picasso-rich-text-editor/utils'; |
15 changes: 15 additions & 0 deletions
15
packages/picasso-codemod/src/v36.0.0/__testfixtures__/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "somemodule", | ||
"description": "test", | ||
"version": "0.0.3", | ||
"author": "Toptal", | ||
"license": "ISC", | ||
"main": "./src/index.ts", | ||
"dependencies": { | ||
"@toptal/picasso": "36.0.0", | ||
"@toptal/picasso-forms": "58.0.0", | ||
"@toptal/picasso-rich-text-editor": "1.0.2" | ||
}, | ||
"private": true, | ||
"sideEffects": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { defineTest } from 'jscodeshift/src/testUtils' | ||
|
||
defineTest(__dirname, 'rich-text-editor-replacement', {}, 'imports', { | ||
parser: 'tsx', | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './rich-text-editor-replacement' |
194 changes: 194 additions & 0 deletions
194
packages/picasso-codemod/src/v36.0.0/rich-text-editor-replacement.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
import type { Transform } from 'jscodeshift' | ||
import path from 'path' | ||
import fs from 'fs' | ||
|
||
const specificModules = [ | ||
'RichText', | ||
'htmlToHast', | ||
'RichTextEditor', | ||
'RichTextEditorProps', | ||
'ASTType', | ||
'CustomEmojiGroup', | ||
'CustomEmoji', | ||
] | ||
const picassoVersion = '36.0.0' | ||
const picassoFormsVersion = '58.0.0' | ||
const picassoRichTextEditorVersion = '1.0.1' | ||
|
||
// Get current execution directory | ||
const execDir = process.cwd() | ||
|
||
const findPackageJson = (dirPath: string) => { | ||
// Start with the directory provided | ||
let currentPath = dirPath | ||
|
||
while (currentPath !== '/' && currentPath !== execDir) { | ||
// Attempt to read package.json at current path | ||
try { | ||
const packageJsonPath = path.join(currentPath, 'package.json') | ||
|
||
if (fs.existsSync(packageJsonPath)) { | ||
return packageJsonPath | ||
} | ||
} catch (err) { | ||
console.error(err) | ||
} | ||
|
||
// If package.json doesn't exist, move up one directory | ||
currentPath = path.dirname(currentPath) | ||
} | ||
|
||
throw new Error('Could not find package.json') | ||
} | ||
|
||
const updatePackageJsonVersions = ( | ||
path: string, | ||
{ addRichTextEditorDependency }: { addRichTextEditorDependency: boolean } | ||
) => { | ||
try { | ||
const packageJsonPath = findPackageJson(path) | ||
|
||
// If it exists, read and parse it | ||
try { | ||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')) | ||
|
||
if (!packageJson.dependencies) { | ||
return | ||
} | ||
|
||
let inDevDependencies = false | ||
|
||
// Update Picasso and Picasso forms dependencies | ||
if (packageJson.dependencies['@toptal/picasso']) { | ||
packageJson.dependencies['@toptal/picasso'] = picassoVersion | ||
} else if ( | ||
packageJson.devDependencies && | ||
packageJson.devDependencies['@toptal/picasso'] | ||
) { | ||
packageJson.devDependencies['@toptal/picasso'] = picassoVersion | ||
inDevDependencies = true | ||
} | ||
|
||
if (packageJson.dependencies['@toptal/picasso-forms']) { | ||
packageJson.dependencies['@toptal/picasso-forms'] = picassoFormsVersion | ||
// if picasso form is defined, it depends on RichTextEditor, we should also add a dependency | ||
packageJson.dependencies['@toptal/picasso-rich-text-editor'] = | ||
picassoRichTextEditorVersion | ||
} else if ( | ||
packageJson.devDependencies && | ||
packageJson.devDependencies['@toptal/picasso-forms'] | ||
) { | ||
packageJson.devDependencies['@toptal/picasso-forms'] = | ||
picassoFormsVersion | ||
// if picasso form is defined, it depends on RichTextEditor, we should also add a dependency | ||
packageJson.devDependencies['@toptal/picasso-rich-text-editor'] = | ||
picassoRichTextEditorVersion | ||
inDevDependencies = true | ||
} | ||
|
||
// if RTE is used inside package, we should add a dependency | ||
if (addRichTextEditorDependency) { | ||
if (inDevDependencies) { | ||
packageJson.devDependencies['@toptal/picasso-rich-text-editor'] = | ||
picassoRichTextEditorVersion | ||
} else { | ||
packageJson.dependencies['@toptal/picasso-rich-text-editor'] = | ||
picassoRichTextEditorVersion | ||
} | ||
} | ||
|
||
fs.writeFileSync( | ||
packageJsonPath, | ||
JSON.stringify(packageJson, null, 2) + '\n' | ||
) | ||
} catch (err) { | ||
console.log(`Could not parse package.json at ${packageJsonPath}: ${err}`) | ||
} | ||
} catch (err) { | ||
console.log('err: ', err) | ||
console.error(`Package json not found for ${path}: ${err}`) | ||
} | ||
} | ||
|
||
const transform: Transform = (file, { jscodeshift: j }) => { | ||
const source = j(file.source) | ||
let fileContainsRichTextEditorImport = false | ||
let hasPicassoForms = false | ||
|
||
const picassoImports = source.find(j.ImportDeclaration).filter(path => { | ||
const pattern = /@toptal\/picasso($|\/[a-z\d]*)/gi | ||
|
||
hasPicassoForms = | ||
hasPicassoForms || path.node.source.value === '@toptal/picasso-forms' | ||
|
||
return ( | ||
pattern.test(path.node.source.value as string) && | ||
path.node.source.value !== '@toptal/picasso-forms' | ||
) | ||
}) | ||
|
||
// Iterate over react imports | ||
picassoImports.forEach(picassoImport => { | ||
const richTextSpecifiers = j(picassoImport) | ||
.find(j.ImportSpecifier) | ||
.filter(path => { | ||
return specificModules.includes(path.node.imported.name) | ||
}) | ||
|
||
// there is only single specifier, replace the whole import | ||
if (picassoImport.node.specifiers?.length === richTextSpecifiers.length) { | ||
j(picassoImport).replaceWith( | ||
// Build a new import declaration node based on the existing one | ||
j.importDeclaration( | ||
picassoImport.node.specifiers, // copy over the existing import specificers | ||
j.stringLiteral( | ||
(picassoImport.node.source.value as string).replace( | ||
'@toptal/picasso', | ||
'@toptal/picasso-rich-text-editor' | ||
) | ||
), | ||
picassoImport.node.importKind | ||
) | ||
) | ||
|
||
fileContainsRichTextEditorImport = true | ||
} else if (richTextSpecifiers.length > 0) { | ||
// insert specifiers for rich text editor | ||
// const importSpecifier = j.importSpecifier(richTextSpecifiers); | ||
// Generate new specifiers for the new import | ||
const newSpecifiers = richTextSpecifiers.nodes().map(node => { | ||
return j.importSpecifier( | ||
j.identifier(node.imported.name), | ||
node.local ? j.identifier(node.local.name) : undefined | ||
) | ||
}) | ||
// Create a new import declaration | ||
const newImport = j.importDeclaration( | ||
newSpecifiers, | ||
j.literal('@toptal/picasso-rich-text-editor'), | ||
picassoImport.node.importKind | ||
) | ||
|
||
j(picassoImport).insertAfter(newImport) | ||
|
||
// there are some specifiers left, remove the ones that are replaced | ||
j(picassoImport) | ||
.find(j.ImportSpecifier) | ||
.filter(path => specificModules.includes(path.node.imported.name)) | ||
.remove() | ||
|
||
fileContainsRichTextEditorImport = true | ||
} | ||
}) | ||
|
||
// we must update package.json as well. We have to upgrade @toptal/picasso, @toptal/picasso-forms and add new dependency @toptal/picasso-rich-text-editor | ||
// first of all, we need to search for a package json, it must be in the root of the package | ||
updatePackageJsonVersions(file.path, { | ||
addRichTextEditorDependency: | ||
fileContainsRichTextEditorImport || hasPicassoForms, | ||
}) | ||
|
||
return source.toSource({ trailingComma: false, quote: 'single' }) | ||
} | ||
|
||
export default transform |