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
Allow scalars option for SchemaBuilder #910
Comments
While this might be technically possible, there are a couple of issues:
|
My understanding is these would match
Makes sense. I saw this as a happy side effect made possible by having the types up front anyway. |
Interesting, not sure if I just misremembered, or this changed recently, but that would be roughly equivalent. It does look like these types are unused by all the scalars in the graphql-scalars package though.
I think those types of helpers are pretty important. For this kind of major change, there would need to be a fairly compelling case for why it's needed. Maybe a simpler approach would be a create builderWithScalars method? This could do the same thing but wouldn't really be a breaking change, it would just take all the same options as the constructor, but would return a builder with the scalar methods. |
Hopefully these will be made public with this PR If merged the types would be accessible. For example: These types could then be extracted from the graphql-scalar and merged into the This can be done in user-land now import SchemaBuilder from "@pothos/core"
import { GraphQLScalarType } from "graphql"
import { DateTimeResolver as og } from "graphql-scalars"
import { toPairs } from "remeda"
// Pretend the pr is merged and TInternal and TExternal are exposed
const DateTimeResolver = og as GraphQLScalarType<Date, string>
const scalars = { 'DateTime': DateTimeResolver } satisfies Record<string, GraphQLScalarType>
// Extract the TInternal and TExternal types from GraphQLScalarType, map them to Input and Output for SchemaBuilder
type ExtractIO<Type> = Type extends GraphQLScalarType<infer TInternal, infer TExternal> ? {
Input: TInternal
Output: TExternal
} : never
// Create the type for SchemaBuilder
// for this example { 'DateTime': { Input: Date, Output: string } }
type Scalars = { [Property in keyof typeof scalars]: ExtractIO<typeof scalars[Property]> }
const builder = new SchemaBuilder<{ Scalars: Scalars }>({})
// Add the scalar types, (using remeda for type safety, could use Object.entries if preferred)
for (const [name, resolver] of toPairs.strict(scalars)) {
builder.addScalarType(name, resolver, {})
}
builder.queryType()
builder.mutationType()
export { builder } I've ignored the options here for brevity. If this was to move inside of SchemaBuilder, something like Maybe more realistically const builder = new SchemaBuilder({
scalars: [
['Name', resolver, options]
]
})
The dynamic helpers feature is not required to allow scalars as a SchemaBuilder option. Being able to drop in scalars and have the types work with only |
Whoops, I think we are talking about different things with the dynamic helpers. I was talking about any 3rd party helpers depending on specific shapes of the builder, but probably out of scope for this conversation anyway. I looked at this a bit more, and remembered the real reason I haven't done something like this (more generally inferring things from options). There are several features that would really benefit from that (eg changing default nullability). The reason this does not work today is because typescript doesn't have a way to do partial inference. Basically we still need to be able to pass a generic to the builder constructor for other features and plugins. When you explicitly provide a generic for a function or constructor, you can't infer other values anymore. The only way to have inference work is to use a separate method: const builder = new SchemaBuilder<{ Context: Context }>().withScalars({
Name: Resolver,
}) Or something similar, not sure this is actually a good API, but that is the only way you can work around the issue. Are you just trying to get around double declaring the scalars? The main issues I know about with the current API:
I think something like withScalars could be a big improvement, and could theoretically add the t.date style helpers as well. This would still require a fairly large (breaking) change to how the helpers are added to field builders. I'd likely want to standardize to make all the helpers dynamically generated including the built in scalars for consistency. The list of scalars would need to be stored on the builder. I'm currently on vacation and in my spare time working on a big 4.0 release. If you really want this feature, getting it in as part of 4.0 would be the time to do it (still a long way out, probably a couple months) |
Totally haha. Ok, that makes sense
That would make sense to me. Nice win that it is a non-breaking change too.
That is pretty much it. I wanted to use
If you point me in a direction I am happy to write some docs.
🏖️💻 No rush at all
Cool, Would that be aiming the pr at the Would adding |
Adding withScalars wouldn't require a major version, but rebuilding the field builder classes to generate the correct helpers might. If you want to include the helpers, I'd Target v4, but it's completely broken right now and I have a bunch of changes in progress from my last flight I haven't pushed. I think a PR to main that doesn't add the helpers would be an easier place to start and wouldn't require a major version |
Instead of adding scalars after creating a schema builder using
builder.addScalarType
, I would like to be able to giveSchemaBuilder
an object with scalars.This would set up like the following
This would help with this issue on using graphql-scalars and this discussion for custom scalar methods
As the resolvers are set up, methods can then be added for convenience.
This would look like the following with graphql-scalars and method generation. I have used the SimpleObjectsPlugin for simplicity
This is useful as the types can be inferred from the resolver for
Input
andOutput
. This is also useful for not adding the extra methods as the field would still be correctly typede.g
The text was updated successfully, but these errors were encountered: