-
Notifications
You must be signed in to change notification settings - Fork 1k
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
feat(codemod): Add codemod to make relation resolvers partial #6342
Merged
Merged
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
777b6b9
feat(codemod): Add codemod to make relation resolvers partial
dac09 a9b8a07
Merge branch 'main' into feat/codemod-ts-resolver-types
dac09 8e66e4d
Bit of cleanup
dac09 9f9ee23
Remove unused import
dac09 7949212
Merge branch 'main' into feat/codemod-ts-resolver-types
dac09 153af52
Update packages/codemods/src/codemods/v2.x.x/updateResolverTypes/upda…
dac09 8a82e13
Merge branch 'main' into feat/codemod-ts-resolver-types
Tobbe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
22 changes: 22 additions & 0 deletions
22
packages/codemods/src/codemods/v2.x.x/updateResolverTypes/README.md
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,22 @@ | ||
# Update Resolver Types | ||
|
||
- This codemod only affects TS projects. | ||
|
||
It will find all service files, and if they have a relation resolver - it will convert the type to a partial. | ||
|
||
Taking a specific case, in the test project we have Post.author, which is a relation (author is User on the DB). | ||
|
||
```diff | ||
// At the bottom of the file | ||
- export const Post: PostResolvers = { | ||
+ export const Post: Partial<PostResolvers> = { | ||
author: (_obj, gqlArgs) => | ||
db.post.findUnique({ where: { id: gqlArgs?.root?.id } }).author(), | ||
} | ||
``` | ||
|
||
This is because of the `avoidOptionals` flag in graphql codegen. Look for this option in `packages/internal/src/generate/graphqlCodeGen.ts` | ||
|
||
|
||
> Note: | ||
> Very old RW projects don't even have these types in the services. This was introduced in v2.x, when we enabled Prisma model mapping in codegen. |
54 changes: 54 additions & 0 deletions
54
packages/codemods/src/codemods/v2.x.x/updateResolverTypes/__testfixtures__/default.input.js
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,54 @@ | ||
import type { | ||
QueryResolvers, | ||
MutationResolvers, | ||
PostResolvers, | ||
} from 'types/graphql' | ||
|
||
import { db } from 'src/lib/db' | ||
|
||
export const posts: QueryResolvers['posts'] = () => { | ||
return db.post.findMany() | ||
} | ||
|
||
export const post: QueryResolvers['post'] = ({ id }) => { | ||
return db.post.findUnique({ | ||
where: { id }, | ||
}) | ||
} | ||
|
||
export const createPost: MutationResolvers['createPost'] = ({ input }) => { | ||
return db.post.create({ | ||
data: input, | ||
}) | ||
} | ||
|
||
export const updatePost: MutationResolvers['updatePost'] = ({ id, input }) => { | ||
return db.post.update({ | ||
data: input, | ||
where: { id }, | ||
}) | ||
} | ||
|
||
export const deletePost: MutationResolvers['deletePost'] = ({ id }) => { | ||
return db.post.delete({ | ||
where: { id }, | ||
}) | ||
} | ||
|
||
export const Post: PostResolvers = { | ||
author: (_obj, gqlArgs) => | ||
db.post.findUnique({ where: { id: gqlArgs?.root?.id } }).author() as Author, | ||
} | ||
|
||
// Leave these alone | ||
interface Bazinga { | ||
bazinga: string | ||
} | ||
|
||
export const CustomExport: Bazinga = { | ||
bazinga: 'yes' | ||
} | ||
|
||
export const CustomExport2: Partial<Bazinga> = {} | ||
|
||
const HelloWorld: BazingaResolvers['HelloWorld'] = {} |
55 changes: 55 additions & 0 deletions
55
packages/codemods/src/codemods/v2.x.x/updateResolverTypes/__testfixtures__/default.output.js
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,55 @@ | ||
import type { | ||
QueryResolvers, | ||
MutationResolvers, | ||
PostResolvers, | ||
} from 'types/graphql' | ||
|
||
import { db } from 'src/lib/db' | ||
|
||
export const posts: QueryResolvers['posts'] = () => { | ||
return db.post.findMany() | ||
} | ||
|
||
export const post: QueryResolvers['post'] = ({ id }) => { | ||
return db.post.findUnique({ | ||
where: { id }, | ||
}) | ||
} | ||
|
||
export const createPost: MutationResolvers['createPost'] = ({ input }) => { | ||
return db.post.create({ | ||
data: input, | ||
}) | ||
} | ||
|
||
export const updatePost: MutationResolvers['updatePost'] = ({ id, input }) => { | ||
return db.post.update({ | ||
data: input, | ||
where: { id }, | ||
}) | ||
} | ||
|
||
export const deletePost: MutationResolvers['deletePost'] = ({ id }) => { | ||
return db.post.delete({ | ||
where: { id }, | ||
}) | ||
} | ||
|
||
export const Post: Partial<PostResolvers> = { | ||
author: (_obj, gqlArgs) => | ||
db.post.findUnique({ where: { id: gqlArgs?.root?.id } }).author() as Author, | ||
} | ||
|
||
|
||
// Leave these alone | ||
interface Bazinga { | ||
bazinga: string | ||
} | ||
|
||
export const CustomExport: Bazinga = { | ||
bazinga: 'yes' | ||
} | ||
|
||
export const CustomExport2: Partial<Bazinga> = {} | ||
|
||
const HelloWorld: BazingaResolvers['HelloWorld'] = {} |
5 changes: 5 additions & 0 deletions
5
...es/codemods/src/codemods/v2.x.x/updateResolverTypes/__tests__/updateResolverTypes.test.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,5 @@ | ||
describe('updateResolverTypes', () => { | ||
it('Converts PostResolvers to Partial<PostResolvers>', async () => { | ||
await matchTransformSnapshot('updateResolverTypes', 'default') | ||
}) | ||
}) |
61 changes: 61 additions & 0 deletions
61
packages/codemods/src/codemods/v2.x.x/updateResolverTypes/updateResolverTypes.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,61 @@ | ||
import type { API, FileInfo, TSTypeAnnotation } from 'jscodeshift' | ||
import { Identifier, TSTypeReference } from 'jscodeshift' | ||
|
||
const isTypeReference = ( | ||
typeAnnotation: TSTypeAnnotation['typeAnnotation'] | ||
): typeAnnotation is TSTypeReference => TSTypeReference.check(typeAnnotation) | ||
|
||
const getTypeName = (node: TSTypeReference) => { | ||
return Identifier.check(node.typeName) ? node.typeName.name : null | ||
} | ||
|
||
const isWrappedInPartial = (node: TSTypeAnnotation) => { | ||
const typeAnnotation = node.typeAnnotation | ||
|
||
return ( | ||
isTypeReference(typeAnnotation) && getTypeName(typeAnnotation) === 'Partial' | ||
) | ||
} | ||
|
||
export default function transform(file: FileInfo, api: API) { | ||
const j = api.jscodeshift | ||
const ast = j(file.source) | ||
|
||
ast.find(j.TSTypeAnnotation).forEach((path) => { | ||
const typeAnnotationNode = path.node | ||
|
||
if ( | ||
// If it's a MutationResolvers['x'] or QueryResolvers['x'] | ||
j.TSIndexedAccessType.check(typeAnnotationNode.typeAnnotation) | ||
) { | ||
return | ||
} | ||
|
||
if ( | ||
!isWrappedInPartial(typeAnnotationNode) && | ||
isTypeReference(typeAnnotationNode.typeAnnotation) | ||
) { | ||
const originalTypeName = getTypeName(typeAnnotationNode.typeAnnotation) | ||
|
||
if (!originalTypeName || !originalTypeName.includes('Resolvers')) { | ||
// Skip other type annotations! | ||
return | ||
} | ||
|
||
console.log(`Wrapping ${originalTypeName} in Partial....`) | ||
|
||
path.replace( | ||
j.tsTypeAnnotation( | ||
j.tsTypeReference( | ||
j.identifier('Partial'), | ||
j.tsTypeParameterInstantiation([ | ||
j.tsTypeReference(j.identifier(originalTypeName)), | ||
]) | ||
) | ||
) | ||
) | ||
} | ||
}) | ||
|
||
return ast.toSource() | ||
} |
27 changes: 27 additions & 0 deletions
27
packages/codemods/src/codemods/v2.x.x/updateResolverTypes/updateResolverTypes.yargs.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,27 @@ | ||
import path from 'path' | ||
|
||
import fg from 'fast-glob' | ||
import task, { TaskInnerAPI } from 'tasuku' | ||
|
||
import getRWPaths from '../../../lib/getRWPaths' | ||
import runTransform from '../../../lib/runTransform' | ||
|
||
export const command = 'update-resolver-types' | ||
export const description = | ||
'(v2.x.x->v3.x.x) Wraps types for "relation" resolvers in the bottom of service files' | ||
|
||
export const handler = () => { | ||
task('Update Resolver Types', async ({ setOutput }: TaskInnerAPI) => { | ||
await runTransform({ | ||
transformPath: path.join(__dirname, 'updateResolverTypes.js'), | ||
// Target services written in TS only | ||
targetPaths: fg.sync('**/*.ts', { | ||
cwd: getRWPaths().api.services, | ||
ignore: ['**/node_modules/**', '**/*.test.ts', '**/*.scenarios.ts'], | ||
absolute: true, | ||
}), | ||
}) | ||
|
||
setOutput('All done! Run `yarn rw lint --fix` to prettify your code') | ||
}) | ||
} |
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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think tasuku changed their types