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": "20"
"node": "20",
"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
45 changes: 45 additions & 0 deletions codemods/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 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
*.tsbuildinfo

.yalc/
.yalc.lock
.vscode/
coverage/
build/
lib/
dist/
temp/
.tmp/
.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`
169 changes: 169 additions & 0 deletions codemods/eslint.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import js from '@eslint/js'
import vitestPlugin from '@vitest/eslint-plugin'
import prettierConfig from 'eslint-config-prettier/flat'
import type { ConfigArray } from 'typescript-eslint'
import { config, configs, parser } from 'typescript-eslint'

const eslintConfig: ConfigArray = config(
{
name: 'global-ignores',
ignores: [
'**/dist/',
'**/.yalc/',
'**/build/',
'**/lib/',
'**/temp/',
'**/.temp/',
'**/.tmp/',
'**/.yarn/',
'**/coverage/',
'**/__testfixtures__/',
],
},
{ name: `${js.meta.name}/recommended`, ...js.configs.recommended },
...configs.recommended,
...configs.stylistic,
{ name: 'vitest/recommended', ...vitestPlugin.configs.recommended },
{
name: 'main',
languageOptions: {
parser,
parserOptions: {
projectService: {
defaultProject: './tsconfig.json',
},
tsconfigRootDir: import.meta.dirname,
ecmaVersion: 'latest',
},
},
rules: {
'@typescript-eslint/consistent-type-imports': [
2,
{
prefer: 'type-imports',
fixStyle: 'separate-type-imports',
disallowTypeAnnotations: true,
},
],
'@typescript-eslint/consistent-type-exports': [
2,
{ fixMixedExportsWithInlineTypeSpecifier: false },
],
'@typescript-eslint/no-explicit-any': [
2,
{ fixToUnknown: false, ignoreRestArgs: false },
],
'@typescript-eslint/no-empty-object-type': [
2,
{ allowInterfaces: 'never', allowObjectTypes: 'never' },
],
'@typescript-eslint/no-restricted-types': [
2,
{
types: {
'{}': {
message: `
- If you want to represent an empty object, use \`type EmptyObject = Record<string, never>\`.
- If you want to represent an object literal, use either \`type AnyObject = Record<string, any>\` or \`object\`.
- If you want to represent any non-nullish value, use \`type AnyNonNullishValue = NonNullable<unknown>\`.`,
suggest: [
'AnyNonNullishValue',
'EmptyObject',
'AnyObject',
'object',
'Record<string, never>',
'Record<string, any>',
'NonNullable<unknown>',
],
},
},
},
],
'@typescript-eslint/no-namespace': [
2,
{ allowDeclarations: false, allowDefinitionFiles: true },
],
'@typescript-eslint/consistent-type-definitions': [2, 'type'],
'sort-imports': [
2,
{
ignoreCase: false,
ignoreDeclarationSort: true,
ignoreMemberSort: false,
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
allowSeparatedGroups: true,
},
],
'@typescript-eslint/unified-signatures': [2],
'@typescript-eslint/no-unnecessary-type-parameters': [2],
'@typescript-eslint/no-invalid-void-type': [2],
'@typescript-eslint/no-confusing-void-expression': [2],
'@typescript-eslint/no-duplicate-type-constituents': [2],
'@typescript-eslint/require-await': [2],
'@typescript-eslint/no-redundant-type-constituents': [2],
'@typescript-eslint/no-unnecessary-type-arguments': [2],
'@typescript-eslint/no-unnecessary-type-assertion': [2],
'@typescript-eslint/prefer-nullish-coalescing': [2],
'@typescript-eslint/no-inferrable-types': [2],
'object-shorthand': [2],

'no-undef': [0],
'@typescript-eslint/no-unused-vars': [
0,
{
vars: 'all',
args: 'after-used',
caughtErrors: 'all',
ignoreRestSiblings: false,
reportUsedIgnorePattern: false,
},
],
'@typescript-eslint/ban-ts-comment': [
0,
[
{
'ts-expect-error': 'allow-with-description',
'ts-ignore': true,
'ts-nocheck': true,
'ts-check': false,
minimumDescriptionLength: 3,
},
],
],
'vitest/valid-title': [0],
'vitest/no-alias-methods': [2],
'vitest/no-disabled-tests': [2],
'vitest/no-focused-tests': [2],
'vitest/no-test-prefixes': [2],
'vitest/no-test-return-statement': [2],
'vitest/prefer-each': [2],
'vitest/prefer-spy-on': [2],
'vitest/prefer-to-be': [2],
'vitest/prefer-to-contain': [2],
'vitest/prefer-to-have-length': [2],
},

settings: {
vitest: {
typecheck: true,
},
},

linterOptions: { reportUnusedDisableDirectives: 2 },
},
{
name: 'commonjs',
files: ['**/*.c[jt]s'],
languageOptions: { sourceType: 'commonjs' },
rules: {
'@typescript-eslint/no-require-imports': [
0,
[{ allow: [], allowAsImport: false }],
],
},
},

prettierConfig,
)

export default eslintConfig
Loading