Skip to content

feat(ts-resolvers): Add ability to configure a custom resolver#8339

Draft
dac09 wants to merge 1 commit into
dotansimha:masterfrom
dac09:feat/custom-visitors-ts-resolvers
Draft

feat(ts-resolvers): Add ability to configure a custom resolver#8339
dac09 wants to merge 1 commit into
dotansimha:masterfrom
dac09:feat/custom-visitors-ts-resolvers

Conversation

@dac09

@dac09 dac09 commented Sep 8, 2022

Copy link
Copy Markdown
Contributor

Draft PR (WIP) - one way to implement the feature described in #8338

Description

In Redwood, we need the ability to slightly modify how the TypeScriptResolversVisitor works, while keeping all of the other functionality within the typescript-resolvers plugin as is.

I've tried to describe what we're trying to achieve in this recording: https://s.tape.sh/xK6JyeYz?s=1.25

Related #8338

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

This is a draft PR for discussion, I will add tests as advised!

Test Environment:

  • OS: macOS 12.5.1
  • "@graphql-codegen/typescript-resolvers": "2.7.3"
  • NodeJS: v16.17.0

Checklist:

  • I have followed the CONTRIBUTING doc and the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

@changeset-bot

changeset-bot Bot commented Sep 8, 2022

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9edea19

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

* inputValue: true
* object: true
* defaultValue: true
* resolvers: true;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was missing in the documentation :)

if (config.customVisitor) {
// @TODO: figure out how to use custom-visitor#VisirClass syntax
// instead of using default
const CustomVistor = require(config.customVisitor).default;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need a little guidance on how I can load the supplied string, in the same way mappers or resolverFn loads external imports!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For loading modules correctly on both ESM and CJS the following is recommended:

const makeDefaultLoader = (from: string) => {
if (fs.statSync(from).isDirectory()) {
from = path.join(from, '__fake.js');
}
const relativeRequire = createRequire(from);
return async (mod: string) => {
return import(
isESMModule
? /**
* For ESM we currently have no "resolve path" solution
* as import.meta is unavailable in a CommonJS context
* and furthermore unavailable in stable Node.js.
**/
mod
: relativeRequire.resolve(mod)
);
};
};

@dac09 dac09 Sep 12, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking for the function that loads strings like this:

./my-custom-visitor#VisitorClass

is there a separate function for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@n1ru4l, what I'm trying is using parseMapper so that the syntax for configuring an import stays the same.

It'll look a little like this:

import { ExternalParsedMapper, parseMapper } from '@graphql-codegen/visitor-plugin-common';

    const parsedVisitorString = parseMapper(config.customVisitor) as ExternalParsedMapper;

This way you can specify the name of the class, rather than have to specifically use the default export.

It also looks like the makeDefaultLoader is in the codegen-cli package, should I duplicate it in this one? I'll need to spend a bit more time on this, but hopefully async imports are possible in a visitor!

@n1ru4l

n1ru4l commented Sep 12, 2022

Copy link
Copy Markdown
Collaborator

I am fine with this change if proper tests are supplied.

In a future major change, we might move completely away from the visitor pattern. No ETA for this yet, though. It will probably first happen for the typescript-client plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants