Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add codemod to convert input selectors passed as separate inline arguments to a single array #681

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
3 changes: 2 additions & 1 deletion .codesandbox/ci.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"sandboxes": ["vanilla", "vanilla-ts"],
"node": "18"
"node": "18",
"packages": [".", "/codemods"]
}
46 changes: 46 additions & 0 deletions .github/workflows/test-reselect-codemods.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Test Reselect Codemods

on: [push, pull_request, workflow_dispatch]

defaults:
run:
working-directory: codemods

jobs:
test:
name: Run test Suite
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
node-version: [18, 20, lts/*]
os: [ubuntu-latest]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'

- name: Check folder contents
run: ls -l .

- name: Install dependencies
run: yarn install

- name: Lint Files
run: yarn lint

- name: Check formatting
run: yarn format-check

- name: Check for duplicate dependencies
run: yarn dedupe --strategy highest --check

- name: Run test suite
run: yarn test
39 changes: 39 additions & 0 deletions codemods/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Dependencies
node_modules

# Production
build

# Generated files
.docusaurus
.cache-loader

# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
.cache
.yarnrc
.yarn/*
!.yarn/patches
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*
*.tgz

tsconfig.vitest-temp.json
.eslintcache

.yalc
.yalc.lock
.vscode
dist
temp
1 change: 1 addition & 0 deletions codemods/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/__testfixtures__/
9 changes: 9 additions & 0 deletions codemods/.release-it.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"hooks": {
"after:bump": "yarn && git add -u"
},
"git": {
"commitMessage": "Release reselect-codemods ${version}",
"tagName": "reselect-codemods@${version}"
}
}
42 changes: 42 additions & 0 deletions codemods/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Reselect Codemods

A collection of codemods for updating legacy Reselect API usage patterns to modern patterns.

## Usage

To run a specific codemod from this project, you would run the following:

```bash
npx reselect-codemods <TRANSFORM NAME> path/of/files/ or/some**/*glob.js

# or

yarn global add reselect-codemods
reselect-codemods <TRANSFORM NAME> path/of/files/ or/some**/*glob.js
```

## Local Usage

```
node ./bin/cli.mjs <TRANSFORM NAME> path/of/files/ or/some**/*glob.js
```

## Transforms

<!--TRANSFORMS_START-->

- [convertInputSelectorsToArray](transforms/convertInputSelectorsToArray/README.md)

<!--TRANSFORMS_END-->

## Contributing

### Installation

- clone the repo
- change into the repo directory
- `yarn`

### Running tests

- `yarn test`
39 changes: 39 additions & 0 deletions codemods/bin/cli.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env node
import { execaSync } from 'execa'
import { globbySync } from 'globby'
import { createRequire } from 'node:module'
import * as path from 'node:path'
import { fileURLToPath } from 'node:url'

const require = createRequire(import.meta.url)

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const transformerDirectory = path.join(
__dirname,
'..',
'transforms',
`${process.argv[2]}/index.ts`,
)

const jscodeshiftExecutable = require.resolve('.bin/jscodeshift')

const extensions = 'ts,js,tsx,jsx,mts,mjs,cts,cjs'

execaSync(
jscodeshiftExecutable,
[
'-t',
transformerDirectory,
'--extensions',
extensions,
...(process.argv.slice(3).length === 1
? globbySync(process.argv[3])
: globbySync(process.argv.slice(3))),
],
{
stdio: 'inherit',
stripFinalNewline: false,
},
)
63 changes: 63 additions & 0 deletions codemods/eslint.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import js from '@eslint/js'
import prettierConfig from 'eslint-config-prettier'
import { config, configs, parser } from 'typescript-eslint'

const ESLintConfig = config(
{ name: 'ignores', ignores: ['**/dist/', '**/__testfixtures__/'] },
{ name: 'javascript', ...js.configs.recommended },
...configs.recommended,
...configs.stylistic,
{ name: 'prettier-config', ...prettierConfig },
{
name: 'main',
languageOptions: {
parser,
parserOptions: {
projectService: {
defaultProject: './tsconfig.json',
},
ecmaVersion: 'latest',
},
},
rules: {
'no-undef': [0],
'@typescript-eslint/consistent-type-imports': [
2,
{ fixStyle: 'separate-type-imports', disallowTypeAnnotations: false },
],
'@typescript-eslint/consistent-type-exports': [2],
'@typescript-eslint/no-unused-vars': [0],
'@typescript-eslint/no-explicit-any': [0],
'@typescript-eslint/no-empty-object-type': [
2,
{ allowInterfaces: 'with-single-extends' },
],
'@typescript-eslint/no-namespace': [
2,
{ allowDeclarations: true, allowDefinitionFiles: true },
],
'@typescript-eslint/ban-ts-comment': [0],
'sort-imports': [
2,
{
ignoreCase: false,
ignoreDeclarationSort: true,
ignoreMemberSort: false,
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
allowSeparatedGroups: true,
},
],
},
linterOptions: { reportUnusedDisableDirectives: 2 },
},
{
name: 'commonjs',
files: ['**/*.c[jt]s'],
languageOptions: { sourceType: 'commonjs' },
rules: {
'@typescript-eslint/no-require-imports': [0],
},
},
)

export default ESLintConfig
63 changes: 63 additions & 0 deletions codemods/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"name": "reselect-codemods",
"version": "0.0.1",
"description": "A collection of codemods for the reselect library",
"keywords": [
"redux",
"redux-toolkit",
"reselect",
"codemod"
],
"homepage": "https://github.com/reduxjs/reselect/tree/master/codemods#readme",
"bugs": {
"url": "https://github.com/reduxjs/reselect/issues"
},
"repository": {
"directory": "codemods",
"type": "git",
"url": "git+https://github.com/reduxjs/reselect.git"
},
"sideEffects": false,
"bin": "./bin/cli.mjs",
"files": [
"bin/*",
"transforms/**/index.ts",
"transforms/**/README.md",
"package.json",
"README.md"
],
"scripts": {
"format": "prettier -w . --config prettier.config.mjs",
"format-check": "prettier -c . --config prettier.config.mjs",
"lint": "eslint --flag unstable_ts_config -c eslint.config.mts",
"lint-fix": "eslint --fix --flag unstable_ts_config -c eslint.config.mts",
"test": "vitest --run"
},
"dependencies": {
"execa": "^9.5.1",
"globby": "^14.0.2",
"jscodeshift": "^17.1.1",
"ts-node": "^10.9.2",
"typescript": "^5.6.3"
},
"devDependencies": {
"@eslint/js": "^9.14.0",
"@types/eslint-config-prettier": "^6.11.3",
"@types/jscodeshift": "^0.12.0",
"@types/node": "^22.9.0",
"eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0",
"jiti": "^2.4.0",
"prettier": "^3.3.3",
"reselect": "workspace:^",
"typescript-eslint": "^8.14.0",
"vitest": "^2.1.5"
},
"engines": {
"node": ">= 16"
},
"publishConfig": {
"access": "public",
"provenance": true
}
}
10 changes: 10 additions & 0 deletions codemods/prettier.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @satisfies {import('prettier').Config}
*/
const prettierConfig = {
arrowParens: 'avoid',
semi: false,
singleQuote: true,
}

export default prettierConfig
Loading