@wise/wds-codemods 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +365 -6
- package/dist/helpers-auDAwIcO.js +2020 -0
- package/dist/helpers-auDAwIcO.js.map +1 -0
- package/dist/index.js +114 -0
- package/dist/index.js.map +1 -0
- package/dist/transforms/button/config.json +28 -0
- package/dist/transforms/button/transformer.js +746 -0
- package/dist/transforms/button/transformer.js.map +1 -0
- package/package.json +37 -18
- package/.changeset/config.json +0 -13
- package/.github/CODEOWNERS +0 -1
- package/.github/actions/bootstrap/action.yml +0 -26
- package/.github/actions/commitlint/action.yml +0 -34
- package/.github/workflows/cd-cd.yml +0 -82
- package/.github/workflows/renovate.yml +0 -16
- package/.husky/commit-msg +0 -1
- package/.husky/pre-commit +0 -1
- package/.nvmrc +0 -1
- package/.prettierignore +0 -1
- package/.prettierrc.js +0 -5
- package/commitlint.config.js +0 -3
- package/eslint.config.js +0 -10
- package/jest.config.js +0 -5
- package/mkdocs.yml +0 -4
- package/renovate.json +0 -9
- package/src/__tests__/index.test.ts +0 -10
- package/src/index.ts +0 -2
- package/tsconfig.json +0 -14
package/README.md
CHANGED
|
@@ -1,13 +1,372 @@
|
|
|
1
|
-
|
|
1
|
+
[](https://github.com/transferwise/wds-codemods/actions)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# WDS Codemods
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> WDS Codemods is a collection of codemod scripts designed to automate codebase transformations
|
|
6
|
+
> specifically for the Wise Design System. This package leverages the power of [jscodeshift](https://github.com/facebook/jscodeshift)
|
|
7
|
+
> to perform AST-based code modifications, enabling large-scale refactoring and updates
|
|
8
|
+
> with minimal manual effort.
|
|
6
9
|
|
|
7
10
|
## Table of Contents
|
|
8
11
|
|
|
9
|
-
- [
|
|
12
|
+
- [The Repository](#-the-repository)
|
|
13
|
+
- [Getting started](#-getting-started)
|
|
14
|
+
- [Commands](#commands)
|
|
15
|
+
- [Key Features](#-key-features)
|
|
16
|
+
- [Available Transforms](#-available-transforms)
|
|
17
|
+
- [Working with the Project Locally](#-working-with-the-project-locally)
|
|
18
|
+
- [Writing Codemod Transforms](#-writing-codemod-transforms)
|
|
19
|
+
- [Developer Documentation](#-developer-documentation)
|
|
20
|
+
- [Notes on Key Tools](#-notes-on-key-tools)
|
|
21
|
+
- [Feedback](#-feedback)
|
|
10
22
|
|
|
11
|
-
##
|
|
23
|
+
## 👨💻 The Repository
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
The project provides a flexible CLI interface that allows you to run codemods either interactively
|
|
26
|
+
via prompts or directly through command-line arguments. It includes intelligent package validation,
|
|
27
|
+
monorepo support, and comprehensive reporting for manual review cases.
|
|
28
|
+
|
|
29
|
+
## 🚀 Getting started
|
|
30
|
+
|
|
31
|
+
You can run codemods against your project in two ways: using interactive prompts or via CLI
|
|
32
|
+
arguments. Here's how to do both:
|
|
33
|
+
|
|
34
|
+
### To get started, install the package
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Using npm
|
|
38
|
+
npm i -g @wise/wds-codemods
|
|
39
|
+
|
|
40
|
+
# Using pnpm
|
|
41
|
+
pnpm add -g @wise/wds-codemods
|
|
42
|
+
|
|
43
|
+
# Using yarn
|
|
44
|
+
yarn global add @wise/wds-codemods
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or, if you prefer, you can run it directly without installing globally:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Using npx
|
|
51
|
+
npx @wise/wds-codemods
|
|
52
|
+
|
|
53
|
+
# Using pnpm
|
|
54
|
+
pnpm dlx @wise/wds-codemods
|
|
55
|
+
|
|
56
|
+
# Using yarn
|
|
57
|
+
yarn dlx @wise/wds-codemods
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Using Interactive Prompts
|
|
61
|
+
|
|
62
|
+
Simply run the codemod runner without any arguments:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
wds-codemods
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or, if you prefer, you can run it directly using `npx` without installing globally:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx wds-codemods
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
You will be prompted to:
|
|
75
|
+
|
|
76
|
+
- Select a codemod transform from the available list.
|
|
77
|
+
- Enter the target directory or file path to apply the codemod.
|
|
78
|
+
- Choose whether to run in dry mode (no files are modified).
|
|
79
|
+
- Choose whether to print the transformed source code to the console.
|
|
80
|
+
- Configure monorepo detection (automatically detected in most cases).
|
|
81
|
+
|
|
82
|
+
### Using CLI Arguments
|
|
83
|
+
|
|
84
|
+
You can also run codemods directly by providing arguments:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
wds-codemods <transform> <targetPath> [--dry] [--print] [--monorepo]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Or using package runners:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx @wise/wds-codemods <transform> <targetPath> [--dry] [--print] [--monorepo]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Commands
|
|
97
|
+
|
|
98
|
+
- `npx wds-codemods <transform> <targetPath>`: Run a specific codemod transform on the target path.
|
|
99
|
+
- `--dry` or `--dry-run`: Run in dry mode without writing changes to files. This is useful for previewing what changes would be made before actually applying them, allowing you to review the transformations safely.
|
|
100
|
+
- `--print`: Print transformed source to the console.
|
|
101
|
+
- `--ignore-pattern=GLOB`: Ignore files matching the provided [glob pattern(s)](https://code.visualstudio.com/docs/editor/glob-patterns). Multiple patterns can be comma separated.
|
|
102
|
+
- `--gitignore`: Respect `.gitignore` files to ignore files/folders during codemod runs.
|
|
103
|
+
- `--no-gitignore`: Do not respect `.gitignore` files.
|
|
104
|
+
- `--monorepo`: Enable monorepo package checking across multiple workspace folders.
|
|
105
|
+
|
|
106
|
+
Examples:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Basic transform with dry run
|
|
110
|
+
wds-codemods button ./src --dry
|
|
111
|
+
|
|
112
|
+
# Transform with pattern exclusions
|
|
113
|
+
wds-codemods button ./src --ignore-pattern="*.test.ts,*.stories.ts"
|
|
114
|
+
|
|
115
|
+
# Ignore multiple directories and file types
|
|
116
|
+
wds-codemods button ./src --ignore-pattern="**/node_modules/**,**/*.test.ts,**/stories/**"
|
|
117
|
+
|
|
118
|
+
# Ignore specific directories
|
|
119
|
+
wds-codemods button ./src --ignore-pattern="dist/**,build/**,coverage/**"
|
|
120
|
+
|
|
121
|
+
# Monorepo transformation
|
|
122
|
+
wds-codemods button ./packages --monorepo
|
|
123
|
+
|
|
124
|
+
# Print output without writing files
|
|
125
|
+
wds-codemods button ./src --print --dry
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 💻 Available Transforms
|
|
129
|
+
|
|
130
|
+
### Button Transform (`button`)
|
|
131
|
+
|
|
132
|
+
Migrates `Button` and `ActionButton` components from `@transferwise/components` (v46.5.0+) to the new v2 API.
|
|
133
|
+
|
|
134
|
+
**Key Features:**
|
|
135
|
+
|
|
136
|
+
- **ActionButton Migration**: Converts deprecated `ActionButton` to `Button` with `v2` prop and default size
|
|
137
|
+
- **Legacy Prop Transformations**:
|
|
138
|
+
- `priority`: Maps legacy values to new API (`primary`, `secondary`, `tertiary`, `secondary-neutral`)
|
|
139
|
+
- `size`: Converts to new size tokens (`sm`, `md`, `lg`, `xl`)
|
|
140
|
+
- `type` & `htmlType`: Handles legacy button types and HTML types appropriately
|
|
141
|
+
- `sentiment`: Manages sentiment values with special ControlType handling
|
|
142
|
+
- `text`: Converts ActionButton text prop to children
|
|
143
|
+
- **Smart Enum Handling**:
|
|
144
|
+
- **Preserves** valid `ControlType` enums (`ControlType.NEGATIVE`, `ControlType.POSITIVE`, `ControlType.ACCENT`)
|
|
145
|
+
- Converts `Priority` and `Size` enums to string equivalents
|
|
146
|
+
- Reports deprecated `Type` enum values for manual review
|
|
147
|
+
- **Icon Processing**: Automatically converts icon children to `addonStart`/`addonEnd` props
|
|
148
|
+
- **Link Button Support**: Removes `as="a"` and manages `href` attributes properly
|
|
149
|
+
- **Configurable Mapping**: Interactive prompts for accent/positive secondary button priority mapping
|
|
150
|
+
|
|
151
|
+
**Configuration Options:**
|
|
152
|
+
|
|
153
|
+
During transform execution, you'll be prompted to choose:
|
|
154
|
+
|
|
155
|
+
- `accentSecondaryMapping`: How accent + secondary buttons are mapped (`secondary-neutral` recommended or `secondary`)
|
|
156
|
+
- `positiveSecondaryMapping`: How positive + secondary buttons are mapped (`secondary-neutral` recommended or `secondary`)
|
|
157
|
+
|
|
158
|
+
**Manual Review:**
|
|
159
|
+
|
|
160
|
+
The transform generates a `codemod-report.txt` file for cases requiring manual attention:
|
|
161
|
+
|
|
162
|
+
- Spread props (`{...props}`)
|
|
163
|
+
- Dynamic expressions that cannot be statically analyzed
|
|
164
|
+
- Unsupported prop values
|
|
165
|
+
- Ambiguous icon children (conditional rendering, complex expressions)
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 🔧 Key Features
|
|
170
|
+
|
|
171
|
+
### Package Requirements Validation
|
|
172
|
+
|
|
173
|
+
- **Automatic Dependency Checking**: Validates required packages and versions before running transforms
|
|
174
|
+
- **Multi-Package Manager Support**: Works with npm, pnpm, and yarn
|
|
175
|
+
- **Smart Detection**: Checks package.json, lockfiles, and node_modules directories
|
|
176
|
+
- **Comprehensive Reporting**: Clear feedback when dependencies are missing or incompatible
|
|
177
|
+
|
|
178
|
+
### Monorepo Support
|
|
179
|
+
|
|
180
|
+
- **Auto-Detection**: Automatically identifies monorepo structures (packages/, apps/, libs/, etc.)
|
|
181
|
+
- **Cross-Package Validation**: Checks dependencies across all workspace packages
|
|
182
|
+
- **Summary Reports**: Provides detailed breakdown of which packages have required dependencies
|
|
183
|
+
- **Flexible Configuration**: Manual monorepo mode for custom structures
|
|
184
|
+
|
|
185
|
+
### Manual Review Reports
|
|
186
|
+
|
|
187
|
+
- **Automated Report Generation**: Creates `codemod-report.txt` for issues requiring manual attention
|
|
188
|
+
- **Detailed Context**: Includes file paths, line numbers, and specific issue descriptions
|
|
189
|
+
- **Smart Cleanup**: Automatically removes old reports and provides fresh summaries
|
|
190
|
+
- **Issue Categories**: Organised reporting for spread props, dynamic expressions, and unsupported values
|
|
191
|
+
|
|
192
|
+
### Intelligent Processing
|
|
193
|
+
|
|
194
|
+
- **Selective Execution**: Only runs transforms on projects with compatible dependencies
|
|
195
|
+
- **Performance Optimisation**: Caching and efficient directory traversal
|
|
196
|
+
- **Robust Error Handling**: Graceful handling of edge cases and invalid configurations
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 👨💻 Working with the Project Locally
|
|
201
|
+
|
|
202
|
+
To work with the project locally, follow these steps:
|
|
203
|
+
|
|
204
|
+
1. **Install dependencies**
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
pnpm install
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
2. **Build the project**
|
|
211
|
+
|
|
212
|
+
This compiles the main source and all transform scripts into the `dist` directory:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
pnpm run build
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
3. **Run codemods**
|
|
219
|
+
|
|
220
|
+
After building, you can run the codemods using the instructions above.
|
|
221
|
+
|
|
222
|
+
### Requirements
|
|
223
|
+
|
|
224
|
+
This project uses [pnpm](https://pnpm.io/) and [Node](https://nodejs.org/en/).
|
|
225
|
+
Ensure you are using version `9.15.4` for `pnpm`, to install please follow
|
|
226
|
+
the [installation guide](https://pnpm.io/installation).
|
|
227
|
+
|
|
228
|
+
For node make sure you've set you local to the one found in `.nvmrc`. Use
|
|
229
|
+
[nvm](https://github.com/nvm-sh/nvm) to manage your local development versions.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## ⚛️ Writing Codemod Transforms
|
|
234
|
+
|
|
235
|
+
Codemod transforms are located in the `src/transforms` directory. Each transform is a
|
|
236
|
+
standalone TypeScript file exporting a default function that follows the [jscodeshift](https://github.com/facebook/jscodeshift) transformer API.
|
|
237
|
+
|
|
238
|
+
### Example: Simple Rename Transform
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
import type { API, FileInfo, Options } from 'jscodeshift';
|
|
242
|
+
import { validatePackageRequirements } from '../helpers';
|
|
243
|
+
|
|
244
|
+
// Define package requirements for this transform
|
|
245
|
+
export const packageRequirements = [{ name: '@wise/components', version: '>=2.0.0' }];
|
|
246
|
+
|
|
247
|
+
const transformer = (file: FileInfo, api: API, options: Options) => {
|
|
248
|
+
// Validate package requirements before running
|
|
249
|
+
if (!validatePackageRequirements(options, packageRequirements)) {
|
|
250
|
+
return file.source;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const j = api.jscodeshift;
|
|
254
|
+
const root = j(file.source);
|
|
255
|
+
|
|
256
|
+
// Find all identifiers named 'foo' and rename them to 'bar'
|
|
257
|
+
root.find(j.Identifier, { name: 'foo' }).replaceWith(() => j.identifier('bar'));
|
|
258
|
+
|
|
259
|
+
return root.toSource();
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export default transformer;
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Adding a New Transform
|
|
266
|
+
|
|
267
|
+
1. Create a new `.ts` file in `src/transforms/your-transform-name/`.
|
|
268
|
+
2. Create `config.json` file in the same directory and set an object defining required dependencies as well as the type of the codemod.
|
|
269
|
+
3. Export a default function following the jscodeshift transformer signature.
|
|
270
|
+
4. Use helper utilities from `src/helpers/` for common operations.
|
|
271
|
+
5. Write unit tests for your transform using the `createTestTransform` utility.
|
|
272
|
+
6. Build the project to compile your transform.
|
|
273
|
+
7. Run the codemod runner and select your new transform.
|
|
274
|
+
|
|
275
|
+
### Package Requirements
|
|
276
|
+
|
|
277
|
+
Each transform should have `prerequisites` defined in `config.json` that specifies which packages and versions are
|
|
278
|
+
required:
|
|
279
|
+
|
|
280
|
+
```json
|
|
281
|
+
{
|
|
282
|
+
"prerequisites": {
|
|
283
|
+
"@wise/components": ">=2.0.0",
|
|
284
|
+
"@wise/icons": "^1.0.0"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
The system will automatically validate these requirements before running the transform, supporting:
|
|
290
|
+
|
|
291
|
+
- Semantic version ranges (`>=`, `^`, `~`, etc.)
|
|
292
|
+
- Multiple package managers (npm, pnpm, yarn)
|
|
293
|
+
- Monorepo structures
|
|
294
|
+
- Comprehensive dependency checking (dependencies, devDependencies, peerDependencies)
|
|
295
|
+
|
|
296
|
+
### Helper Utilities
|
|
297
|
+
|
|
298
|
+
The codemod provides several helper utilities in `src/helpers/`:
|
|
299
|
+
|
|
300
|
+
- **`hasImport`** - Check for and manipulate import statements
|
|
301
|
+
- **`processIconChildren`** - Handle icon component transformations
|
|
302
|
+
- **`createReporter`** - Generate manual review reports with detailed context
|
|
303
|
+
- **`validatePackageRequirements`** - Check package dependencies
|
|
304
|
+
- **JSX Element Utils** - Utilities for manipulating JSX elements and attributes
|
|
305
|
+
- **JSX Reporting Utils** - Standardised reporting for common manual review scenarios
|
|
306
|
+
|
|
307
|
+
Additional utilities are available in `src/controller/utils/` for common operations like file handling, AST
|
|
308
|
+
manipulation, and reporting. As this project evolves, we encourage contributors to add new utilities that can benefit the broader codemod ecosystem.
|
|
309
|
+
|
|
310
|
+
#### Writing Unit Tests for Transforms
|
|
311
|
+
|
|
312
|
+
It is important that all codemod transforms have corresponding unit tests to ensure correctness and prevent regressions. Use the `createTestTransform` utility to simplify writing tests for your transforms. This utility helps set up the testing environment and provides helpers to run your transform against sample input and verify the output.
|
|
313
|
+
|
|
314
|
+
**Basic test setup:**
|
|
315
|
+
|
|
316
|
+
```ts
|
|
317
|
+
import { createTestTransform } from '../../../helpers/createTestTransform';
|
|
318
|
+
import transform from '../my-transform';
|
|
319
|
+
|
|
320
|
+
const testTransform = createTestTransform(transform, [
|
|
321
|
+
{ name: '@wise/components', version: '2.0.0' },
|
|
322
|
+
]);
|
|
323
|
+
|
|
324
|
+
describe('my-transform', () => {
|
|
325
|
+
it('should transform component', () => {
|
|
326
|
+
const input = `<OldComponent prop="value" />`;
|
|
327
|
+
const expected = `<NewComponent newProp="value" />`;
|
|
328
|
+
|
|
329
|
+
expect(testTransform({ source: input })).toBe(expected);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Example usage of `createTestTransform` can be found in the existing tests under `src/transforms/simple-rename/__tests__/simple-rename.test.ts`.
|
|
335
|
+
|
|
336
|
+
Make sure to run your tests regularly using:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
pnpm test
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## 📚 Developer Documentation
|
|
345
|
+
|
|
346
|
+
For comprehensive development details, including transform architecture, helper function documentation, testing patterns, and best practices, see our [Developer Documentation](./DEVELOPER.md).
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## 📝 Notes on Key Tools
|
|
351
|
+
|
|
352
|
+
### jscodeshift
|
|
353
|
+
|
|
354
|
+
[jscodeshift](https://github.com/facebook/jscodeshift) is a toolkit for running codemods over multiple JavaScript or TypeScript files. It provides an API to parse source code into an Abstract Syntax Tree (AST), manipulate it, and print the transformed code back.
|
|
355
|
+
|
|
356
|
+
This project uses jscodeshift as the core engine to perform code transformations.
|
|
357
|
+
|
|
358
|
+
### @inquirer/prompts
|
|
359
|
+
|
|
360
|
+
[@inquirer/prompts](https://github.com/SBoudrias/Inquirer.js/tree/main/packages/prompts) is a modern, promise-based library for interactive command-line prompts.
|
|
361
|
+
|
|
362
|
+
This project uses @inquirer/prompts to provide a user-friendly interactive experience when running codemods without CLI arguments, allowing you to select transforms and options easily.
|
|
363
|
+
|
|
364
|
+
### semver
|
|
365
|
+
|
|
366
|
+
[semver](https://github.com/npm/node-semver) is used for semantic version parsing and comparison when validating package requirements. This ensures accurate dependency checking across different version specification formats.
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## ✍️ Feedback
|
|
371
|
+
|
|
372
|
+
Please ask any questions on this project, you can do so by reaching out on Slack. Or contributing to any [active issues](https://transferwise.atlassian.net/jira/software/projects/DS/boards/277/backlog).
|